Vue2.0 组件实现动态模板(即Template)

Posted lee576

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue2.0 组件实现动态模板(即Template)相关的知识,希望对你有一定的参考价值。

从 这篇 文章得到启发

先定义一个组件从外部接收Template,然后在组件里调用

<template >
  <div ref="markedContent"></div>
</template>
<script>
import Vue from 'vue/dist/vue.esm.js'
export default 
  name: 'wf-marked-content',
  props: ['content'],
  mounted () 
    this.compile()
  ,
  methods: 
    compile () 
      // 变量html是生成好的vue格式的HTML模板字符串,
      // 这个模板里面可以包含各种vue的指令,数据绑定等操作,
      // 比如 v-if, :bind, @click 等。
      const html = this.content
      
      // Vue.extend是vue的组件构造器,专门用来构建自定义组件的,
      // 但是不会注册,类似于js中的createElement,
      // 创建但是不会添加。
      // 在这里创建出一个子组件对象构造器。
      const Component = Vue.extend(
        // 模板文件。由于Markdown解析之后可能会有多个根节点,
        // 因此需要包裹起来。
        // 实际的内容是:
        // `<div><img src="url" @click="showInfo(`图片文字')"></div>`
        template: `<div> $html </div>`,
        data() 
          return 
            name: '你'
          
        ,
        // 这里面写的就是这个动态生成的新组件中的方法了,
        // 当然你也可加上data、mounted、updated、watch、computed等等。
        methods: 
          // 上面模板中将点击事件绑定到了这里,因此点击了之后就会调用这个函数。
          // 你可以写多个函数在这里,但是这里的函数的作用域只限在这个子组件中。
          showInfo (title) 
            console.log(title)
          
        
      )
      
      // new Component()是将上面构建的组件对象给实例化,
      // $mount()是将实例化的组件进行手动挂载,
      // 将虚拟dom生成出实际渲染的dom,
      // 这里的markedComponent是完成挂载以后的子组件
      const component = new Component().$mount()
      
      // 将挂载以后的子组件dom插入到父组件中
      // markedComponent.$el就是挂载后生成的渲染dom
      this.$refs['markedContent'].appendChild(component.$el)
    
  
  // 本质上来讲,这个子组件不是任何组件的子组件,
  // 它是由vue直接在全局动态生成的一个匿名组件,然后将它插入到当前位置的。
  // 也正是因此,它才能够完成动态的生成和添加。

</script>

这里尤其要注意 Vue 引入的是 vue.esm.js 这个文件,所以这一句很重要

import Vue from 'vue/dist/vue.esm.js'

不然会报如下错误,大体就是只能用在运行时编译(除非引用的是 vue.esm.js 文件),或根据 这里 的方式修改,都可以实现运行时 template 编译

you are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

下面在父组件中传入template

<template>
  <div id="app">
    <DynamicTemplate content="<div v-text='name'></div>"/>
  </div>
</template>

<script>
import DynamicTemplate from './components/DynamicTemplate.vue'

export default 
  name: 'App',
  components: 
    DynamicTemplate
  

</script>

<style>
#app 
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;

</style>

注意这一段

<DynamicTemplate content="<div v-text='name'></div>"/>

只可以使用 v-text 不能使用 ,不然也会编译报错。实际效果如下

这个"你"字就是我在子组件定义的 name 的值 

以上是关于Vue2.0 组件实现动态模板(即Template)的主要内容,如果未能解决你的问题,请参考以下文章

vue2.0动态添加组件

vue2.0学习笔记之组件

vue2.0的变化

Vue2.0的字符串模板、html模板、组件、slot

Vue2.0学习—Todolist案例(五十九)

vue2.0-数据绑定-循环渲染-数据渲染