如何为每个事件加载新的外部HTML?

时间:2018-03-16 19:39:39

标签: ajax vuetify.js

  • 问题:我想在模态界面中显示v-html,内容来自网址(ajax)...剪切代码正在运行,但它很糟糕,不专业:尝试运行。您点击 GO ,收到消息说 CLOSE 并再次点击 GO ...我需要“{{3}我的代码“与Vue的最佳实践。

问题:如何更好地完成此界面,全部使用Vuetify?

我需要一键式( GO )界面,以及用户的最短等待时间。

(还需要加载其他URL,因此像其他按钮一样使用AJAX等)。

我认为Vuetify有很好的AJAX加载方法(如promisify),所以我需要使用最好的方法!对于这种情况。

PS:我没有看到如何在单个HTML页面(不是一个大的Node.js系统)中实现Vue-AJAX策略。

一个简化的丑陋界面示例

它正在运行,但是混合了非VueJS代码并且具有所有已解释的问题,由答案修复。

var URL = 'https://codepen.io/chriscoyier/pen/difoC.html';    
var loadFromUrl_cache = '... PLEASE WAYTE 10 seconds ...'+
    '<br/>close and back here.';

function loadFromUrl(URL,tmpStore) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == XMLHttpRequest.DONE) {
           if (xmlhttp.status == 200) {
               loadFromUrl_cache = xmlhttp.responseText;
           } else {
               alert('ERROR, something else other than status 200:'+
               xmlhttp.status);
           }
        }
    };
    xmlhttp.open("GET", URL, true); // async
    xmlhttp.send();
}

// to get rid of "missing v-app" error message
var app = document.createElement('div');
app.setAttribute('data-app', true);
document.body.appendChild(app);

let mainVue = new Vue({ el: '#main' });

new Vue({
  el: '#appDlg',
  data() {
    return {
      dialog: false,
      ct_header: 'the header1 here',
      ct_body: 'the body1 here'
    }
  },
  mounted() {
    mainVue.$on('go-modal', this.handleMain);
  },
  methods: {
    handleMain(data) {
      this.ct_header = data.title;
      loadFromUrl(URL,'tmp-store');
      this.ct_body = loadFromUrl_cache;
      this.dialog = true;
    }
  }
});
.myDialog { 
  padding: 10px;
  height: 100%;
  background-color: white; 
}

.myDialog .btn { margin: 20px 0 0 -4px; }
<link href="https://unpkg.com/vuetify@0.14.8/dist/vuetify.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<script src="https://unpkg.com/vuetify@0.14.8/dist/vuetify.min.js"></script>
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet" type="text/css">

<div id="main">
  <v-expansion-panel>
    <v-btn @click="$emit('go-modal', {title: 'Hello', body: 'Bye!'})">Go</v-btn>
  </v-expansion-panel>
</div>

<div id="appDlg">
  <v-dialog v-model="dialog" fullscreen>
    <div class="myDialog">
      <v-btn @click="dialog = false">Close</v-btn>
      <h4>{{ ct_header }}</h4>
      <div v-html="ct_body"></div>
      <v-btn @click="dialog = false">Close</v-btn>
    </div>
  </v-dialog>
</div>
   

PS:感谢these。如果您愿意,可以使用code at this answer

2 个答案:

答案 0 :(得分:4)

  

我认为Vuetify有很好的AJAX加载方法(因为这些),所以我需要使用最好的方法!对于这种情况。

您可以尝试axios

然后您可以更改示例ct_body html,如下所示:

handleMain(data) {
    var URL = "your HTML url here";
    axios.get(URL)
    .then(response => {
        this.ct_body = response.data;
    })
}

目前您的问题是您在尝试获取数据之前尝试更改html。

您应该在使用ajax调用检索它之后设置它。

请注意,从url获取HTML不是即时的(因为它应该相对较快),因此取决于您想要放置加载指示符的情况。因此,它取决于您要设置this.dialog = true的位置 - 只有当您检索html数据时,.then()内部才会打开它。

Codepen

答案 1 :(得分:1)

纯Javascript(ECMAScript 2015)

我们可以使用fetch()及其嵌入式promises!请参阅developer.mozilla.org/Fetch_API/Using_Fetch

handleMain(data) {
  var self = this;
  self.ct_header = data.title;      
  fetch(URL)
  .then(function(res) { return res.text(); })
  .then(function(data) {
    self.ct_body = data;
    self.dialog = true;
  });
}

...等同于Axios,但是,由于看起来完全相同,解决方案更好,因为避免丢失CPU时间,互联网带宽和内存(13kb)加载 Axios 。参见

https://codepen.io/ppKrauss/pen/oqYOrY