为了账号安全,请及时绑定邮箱和手机立即绑定

编译在运行时作为 prop 接收的 Vuetify 标签/模板

编译在运行时作为 prop 接收的 Vuetify 标签/模板

温温酱 2022-12-02 17:25:07
我想向组件发送一个“模板”道具然后渲染它。如果我发送一个纯 HTML 它可以工作,但是如果我发送一个 Vuetify 标签,比如<v-btn>test</v-btn>模板不会被编译。我知道我不应该通过道具传递模板,但这是一个特殊情况:父组件充当“模板构建器”,子组件充当“结果查看器”,所以我必须将创建的模板传递给孩子,以便它可以编译并显示它。这是我一直在尝试的:主程序import Vue from 'vue'import App from './App.vue'// Some imports here ...import vuetify from './plugins/vuetify';new Vue({    vuetify,    render: h => h(App)}).$mount('#app')应用程序.vue<scriptimport Vue from 'vue'// eslint-disable-next-linevar staticRenderFns = [];var dynamic = {  props: ['template'],  data: () => ({      templateRender: null,  }),  render(h) {    if (!this.templateRender) {      return h('div', 'loading...');    } else { // If there is a template, I'll show it      return this.templateRender();    }  },  watch: {    // Every time the template prop changes, I recompile it to update the DOM    template:{      immediate: true, // makes the watcher fire on first render, too.      handler() {        var res = Vue.compile(this.template);        this.templateRender = res.render;                // staticRenderFns belong into $options,         // appearantly        this.$options.staticRenderFns = []                // clean the cache of static elements        // this is a cache with the results from the staticRenderFns        this._staticTrees = []                // Fill it with the new staticRenderFns        for (var i in res.staticRenderFns) {          //staticRenderFns.push(res.staticRenderFns[i]);          this.$options.staticRenderFns.push(res.staticRenderFns[i])        }      }    }  },}export default {  name: 'App',  data: () => ({    template:`            <v-row>              <v-col>                <v-btn class="pa-2 primary white--text">Test</v-btn>              </v-col>              <v-col>                <v-btn class="pa-2 primary white--text">Test</v-btn>              </v-col>              <v-col>                <v-btn class="pa-2 primary white--text">Test</v-btn>              </v-col>            </v-row>    `,  }),  components:{    dynamic,  },
查看完整描述

1 回答

?
FFIVE

TA贡献1797条经验 获得超6个赞

在动态组件内部尝试使用传递的模板渲染一个 vue 组件:


var dynamic = {

  props: ['template'],

  data: () => ({

      templateRender: null,

  }),

  render(h) {

    if (!this.template) {

      return h('div', 'loading...');

    } else { // If there is a template, I'll show it

      return h(Vue.component('dynamic-render', {template:this.template}));

    }

  },

}

完整示例


var dynamic = {

  props: ['template'],

  data: () => ({

    templateRender: null,

  }),

  render(h) {

    if (!this.template) {

      return h('div', 'loading...');

    } else { // If there is a template, I'll show it

      return h(Vue.component('dynamic-render', {

        template: this.template

      }));

    }

  },

}


var app = new Vue({

  el: '#app',

  vuetify: new Vuetify(),

  data: () => ({

    count: 1,

    template: `

            <v-row>

              <v-col>

                <v-btn class="pa-2 primary white--text">Test</v-btn>

              </v-col>

              <v-col>

                <v-btn class="pa-2 primary white--text">Test</v-btn>

              </v-col>

              <v-col>

                <v-btn class="pa-2 primary white--text">Test</v-btn>

              </v-col>

            </v-row>

    `,

  }),

  components: {

    dynamic,

  },

  methods: {

    changeContent() {

      this.count = this.count + 1

      this.template = '';

      setTimeout(() => { //simulate loading status

        this.template = `<v-col>

                <v-btn class="pa-2 primary white--text">Btn ${this.count}</v-btn>

              </v-col>`

      }, 2000);


    }

  }



})

<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">

<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">

<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">


<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>

<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>


<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<div id="app">

  <v-app id="inspire">

    <v-btn depressed color="primary" class="black--text" @click="changeContent">change content</v-btn>

    <dynamic :template='template'></dynamic>



  </v-app>

</div>


查看完整回答
反对 回复 2022-12-02
  • 1 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号