前言:
- 日前在工作中,遇到一个需求就是需要在一个
.vue文件中,根据数据的变化,动态添加一个 dom,如果这个 dom 只是一个静态的 dom 标签,那么这个问题就很简单,但是需要添加的 dom 是一个带有 vue-directive 自定义指令的 dom,就不能用常规的 js 结合 dom 的语法来处理了。 - 只能使用 createElement 渲染函数来渲染出来一个动态的具有自定义指令的虚拟 dom,然后在适当的时机渲染到页面上,现在问题是怎么渲染这个自己定义的这个虚拟 dom
- 其实 Vue2.0 的实现方式粗略来讲,就是 Vue 把 js 文件设计的页面数据,转化成相应的虚拟 dom,然后再渲染挂载到#app 上的一个单页面工程,然后在 Vue 的工程中,使用 Vue 的 component()函数,实现页面的组件化转化。那么现在思路就是 component 和 extend,这两个函数来实现这个目标。
1.component(id,options) 函数:
- component:
Vue.component( id, [definition] ),注册或获取全局组件。注册还会自动使用给定的 id 设置组件的名称。获取的全局组件也是返回的是一个构造器函数,不是渲染后的 dom 本身。
- 定义一个名为 button-counter 的新组件
- js 函数实现部分
Vue.component("button-counter", {
data() {
return { count: 0 };
},
template: `<button v-on:click="count++">You clicked me {{ count }} times.</button>`,
/*因为已经在Vue的环境中了,
可以使用template 模板语法,
也可以直接使用render渲染函数,
因为我们的需求写一个动态可以重用的小型虚拟dom,
那么就可以直接使用render函数代替上面的内容,重用性就更高一些。*/
render(h) {
h(
"button",
{
on: {
click: this.count++,
},
},
`You clicked me ${this.count} times.`
);
},
});
- html 部分
<div id="components-demo">
<button-counter></button-counter>
</div>
- main.js
new Vue({ el: "#components-demo" });
2.extend(options) 函数
-
extend:
使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象 -
html 部分
<div id="mount-point"></div>
- js 部分
// 创建构造器
var Profile = Vue.extend({
template: "<p>{{firstName}} {{lastName}} aka {{alias}}</p>",
data: function () {
return {
firstName: "Walter",
lastName: "White",
alias: "Heisenberg",
};
},
//同理,也可以使用渲染函数直接替换上面的内容。
render(createElement) {
return createElement("p", `Walter White aka Heisenberg`);
},
});
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount("#mount-point"); //