首页 > 解决方案 > 通过 AJAX 调用使用 Vue 语法/组件字符串渲染内容?

问题描述

我有这个 HTML 模式:

<div id="New"> == ajax loaded content == </div>

在服务器端渲染 HTML 并使用 innerHTML 将内容注入正确的位置很容易。
现在我正在尝试使用 Vue.js 做同样的事情,但在客户端呈现 HTML。我可以用模板把这个模式变成一个组件,比如说componentA:

componentA  

template:
`<div><slot></slot></div>`

如果 HTML 页面内容类似于:

<componentA>
  <componentB></componentB> and some other none component content
</componentA>

组件B 被渲染并替换了组件A 中的插槽。

问题是如何使用 AJAX 调用(调用是在 componentA 之外进行的)加载

  <componentB></componentB> and some other none component content

进入componentA的插槽,仍然让componentB正确渲染?在实际情况下,来自 AJAX 调用的内容可以是

<componentB>, <componentC>, <componentD> ...

以下将componentB视为常规字符串

in HTML:
<componentA>
  <div id="New"></div>
</componentA>

in JS:
document.getElementById('New').innerHTML =
 '<componentB></componentB> And some other none component content';

是否有一种正确的方法可以使用 Vue 语法将 AJAX 返回的字符串呈现为 Vue?

标签: ajaxvue.jsdynamic

解决方案


一种解决方案是将 ajax 响应<component></component>放在Component.template函数内部renderVue 指南:渲染函数)。

就像下面的演示:

const Foo = Vue.component('foo', {template: '<p>Foo - {{flag}}</p>', props: ['flag']})
const Bar = Vue.component('bar', {template: '<p>Bar - {{flag}}</p>', props: ['flag']})
const Generic = Vue.component('generic', { 
  render: function (createElement) {
    return createElement('div', [
      createElement('h3', 'Title'),
      createElement('button', {on: {click: this.loadComponent}}, 'Load Component'),
      this.dynamicComponent
      && createElement(Vue.component('v-fake-slot', {template:this.dynamicComponent, props: ['flag']}), {
        props: {
          flag: this.parent
        }
      }) 
    ])
  },
  props: ['parent'],
  data () {
    return {
      components: ['<foo :flag="flag"></foo>', '<bar :flag="flag"></bar>'],
      index: 0,
      dynamicComponent: ''
    }
  },
  methods: {
    loadComponent: function () {
      setTimeout(() => {
        this.index += 1
        this.dynamicComponent = this.components[this.index % 2]
      }, 1000)
    }
  }
})



new Vue({
  el: '#app',
  data () {
    return {
      test: 'root'
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <generic :parent="test"></generic>
</div>


推荐阅读