Vue.js - 程序化设置插槽内容

3

有没有办法从组件内部设置/覆盖插槽的内容?例如:

模板:

<div>
    <slot></slot>
</div>

JS:

export default {
    ...
     mounted() {
        this.$slot.render("<button>OK</button>");
     }
    ...
}

我知道我可以在元素上使用 v-html,将内容动态地插入组件模板中,但我指的不仅仅是纯HTML,而是带有Vue指令的HTML。举个例子:

JS:

export default {
    ...
     mounted() {
        this.$slot.default.render('<button @click="submit">OK</button>');
     },
    methods: {
        submit() {
            // Here I want to get :)
        }
    }
    ...
}

基本上我希望Vue能在我的组件范围内渲染(像解析和渲染,而不是像innerHTML那样)特定的字符串,并将其放置在我的组件中的特定位置。原因是我通过AJAX从服务器获取新内容。

很抱歉,经过两天的谷歌搜索,我仍无法理解。

非常感谢!


可能不行。你最好的机会是在创建实际对象之前构建组件模板字符串(但它不支持任何更改)。这是一个相当糟糕的解决方案,所以你很可能应该考虑重构你的应用程序。 - FitzFish
有点像在框架中反向工作。 - Nicolas Heimann
2个回答

6
根据 这篇文章,你可以编写程序来实例化一个组件,并插入插槽内容。
import Button from 'Button.vue'
import Vue from 'vue'
var ComponentClass = Vue.extend(Button)
var instance = new ComponentClass({
    propsData: { type: 'primary' }
})
instance.$slots.default = [ 'Click me!' ]
instance.$mount() // pass nothing
this.$refs.container.appendChild(instance.$el)

1
我认为这是您最好的机会:动态构建您的组件。 在此示例中,我使用了一个简单的占位符(带有v-cloak)。
您可以使用vue-router来获得更好的结果,在执行过程中使用router.addRoutes添加您新创建的组件,这样您的应用程序就不必等待实例化整个vue。

function componentFactory(slot) {
  return new Promise((resolve, reject) => {
    window.setTimeout(() => { // Asynchronous fetching
      resolve({ // Return the actual component
        template: `<div>
            ${slot}
          </div>`,
        methods: {
          submit() {
            console.log('hello');
          }
        }
      });
    }, 1000);
  });
}

componentFactory('<button @click="submit">OK</button>') // Build the component
  .then(component => {
    new Vue({ // Instantiate vue
      el: '#app',
      components: {
        builtComponent: component
      }
    });
  });
[v-cloak], .placeholder {
 display: none;
}

[v-cloak] + .placeholder {
 display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>

<div id='app' v-cloak>
  <built-component></built-component>
</div>
<div class="placeholder">
  This is a placeholder, my vue app is loading...
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接