因为在 Render 函数中无法使用 Vue 内置指令,比如 v-if 等,但我们可以在 Render 函数中,利用原生的 JavaScript 来实现这些指令。
1 v-if/v-else
html:
<div id="app">
<e :is-show="isShow"></e>
<button @click="isShow=!isShow">切换</button>
</div>
js:
Vue.component('e', {
render: function (createElement) {
if (this.isShow) {
return createElement('p', 'isShow 为 true');
} else {
return createElement('p', 'isShow 为 false');
}
},
props: {
isShow: {
type: Boolean,
default: false
}
}
});
var app = new Vue({
el: '#app',
data: {
isShow: false
}
});
效果:
2 v-for
可以使用 for 循环来实现 v-for 指令。
html:
<div id="app2">
<e2 :list="list"></e2>
</div>
js:
Vue.component('e2', {
render: function (createElement) {
var nodes = [];
for (var i = 0; i < this.list.length; i++) {
nodes.push(createElement('p', this.list[i]));
}
return createElement('div', nodes);
},
props: {
list: {
type: Array
}
}
});
var app2 = new Vue({
el: '#app2',
data: {
list: [
'人民心理学,实践出真知',
'氢能源上游解析',
'能救命的可穿戴设备都长什么样?'
]
}
});
渲染结果:
createElement 用于创建 DOM 节点,可以把它当作 JavaScript 的函数来理解。
3 v-if 加 v-for 综合示例
下面是综合利用 JavaScript 的 if 、else 和数组的 map 方法来渲染列表的示例。
html:
<div id="app3">
<e3 :list="list"></e3>
<button @click="click">显示</button>
</div>
js:
Vue.component('e3', {
render: function (createElement) {
if (this.list.length) {
return createElement('ul', this.list.map(function (item) {
return createElement('li', item);
}));
} else {
return createElement('p', '无数据');
}
},
props: {
list: {
type: Array,
default: function () {
return [];
}
}
}
});
var app3 = new Vue({
el: '#app3',
data: {
list: []
},
methods: {
click: function () {
this.list = [
'人民心理学,实践出真知',
'氢能源上游解析',
'能救命的可穿戴设备都长什么样?'
];
}
}
});
这里我们使用了 map() 方法,该方法会对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组。
效果:
上述 Render 函数所对应的 template 编码方式为:
<ul v-if="list.length">
<li v-for="item in list">{{item}}</li>
</ul>
<p v-else>无数据</p>
4 v-model
html:
<div id="app4">
<e4></e4>
</div>
js:
Vue.component('e4', {
render: function (createElement) {
var that = this;
return createElement('div', [
createElement('input', {
domProps: {
value: this.value
},
on: {
input: function (event) {
that.value = event.target.value;
}
}
}),
createElement('p', '绑定值:' + this.value)
])
},
data: function () {
return {
value: ''
}
}
});
var app4 = new Vue({
el: '#app4'
});
效果:
这个 Render 函数所对应的 template 编码方式为:
<div>
<input v-model="value">
<p>绑定值:{{value}}</p>
</div>
5 事件与按键修饰符
事件与按键修饰符也可以自行实现:
修饰符 | 语句 |
---|---|
.stop |
event.stopPropagation() |
.prevent |
event.preventDefault() |
.self |
if(event.target !== event.currentTarget) return; |
.enter 或 .13
|
if(event.keyCode !== 13) return; |
.ctrl |
if(event.ctrlKey) return; |
.alt |
if(event.altKey) return; |
.shift |
if(event.shiftKey) return; |
.meta |
if(event.metaKey) return; |
有的事件修饰符, Vue.js 还提供了特殊前缀:
修饰符 | 前缀 |
---|---|
.capture |
! |
.once |
~ |
.capture.once 或 .once.capture
|
~! |
假设我们希望实现一个留言上墙的功能,即在输入框中输入内容,内容会放在留言列表中。
html:
<div id="app5">
<e5></e5>
</div>
js:
Vue.component('e5', {
render: function (createElement) {
var that = this;
//渲染列表
if (this.list.length) {
var listNode = createElement('ul', this.list.map(function (item) {
return createElement('li', item);
}));
} else {
var listNode = createElement('p', '无内容');
}
return createElement('div', [
listNode,
createElement('input', {
attrs: {
placeholder: '想说的话……'
},
style: {
width: '200px'
},
on: {
keyup: function (event) {
//如果不是回车键,直接返回
if (event.keyCode !== 13) {
return;
}
//把输入的内容新增到聊天列表
that.list.push(event.target.value);
//清空输入框
event.target.value='';
}
}
})
])
},
data:function () {
return {
value:'',
list:[]
}
}
});
var app5 = new Vue({
el: '#app5'
});
效果:
6 未定义 slot 内容的默认值
slot 内容的默认值可以通过 this.$slots.default 来判定 ——
html:
<div id="app6">
<e6></e6>
<e6>
<p>5亿年前的地球,磁场几乎全消失了,科学家:因祸得福</p>
</e6>
</div>
js:
Vue.component('e6', {
render: function (createElement) {
if (this.$slots.default === undefined) {
return createElement('div', '无消息');
} else {
return createElement('div', this.$slots.default);
}
}
});
var app6 = new Vue({
el: '#app6'
});
效果:
网友评论