render渲染函数的基本约束
VNode必须唯一组件树中的所有VNode 必须是唯一的。这意味着,下面的渲染函数是不合法的:
render(createElement) {
let my_el = createElement('h1',
{
on: {
click: (e) => {
this.msg += 'ok'
}
}
},
this.msg)
return createElement('div', [my_el, my_el])
}
如果你真的需要重复很多次的元素/组件,你可以使用工厂函数来实现。运行一次createElement方法, 就会创造一个新的VNode
render: function (createElement) {
return createElement('div',
Array.apply(null, { length: 20 }).map(function () {
return createElement('h1', '111')
})
)
}
js替换模板功能
js替换模板功能之if/for指令
只要在原生的JavaScript 中可以轻松完成的操作,Vue 的渲染函数就不会提供专有的替代方法。比如,在模板中使用的v-if 和v-for:
标准的V-for指令
<body>
<div id='app'>
<h1 v-for='item in items'>{{item}}</h1>
</div>
<script src='./js/vue.js'></script>
<script>
const app = new Vue({
el: '#app',
data: {
items: [1, 2, 3]
}
})
</script>
</body>
这些都可以在渲染函数中用 JavaScript 的 if/else 和 map 来重写:
render(h) {
if (this.items.length) {
return h('div', this.items.map(item => {
return h('h1', item)
}))
} else {
return h('p', '没有找到items')
}
}
js替换模板功能之v-model指令
<!--v-model基本使用-->
......
<input type="text" v-model='name'>
......
data: {
name: 'yzh'
},
<!-- v-bind和input事件实现v-model-->
......
<input type="text" :value='name' @input='fn'>
......
data: {
name: 'yzh'
},
methods: {
fn(e) {
console.log(e);
this.name = e.target.value
}
}
使用render函数时,实现v-model双向数据绑定
components: {
cpn: {
data() {
return { value: '1234' }
},
methods: {
handleClick() {
this.value = '改变value'
}
},
render(h) {
let that = this
console.log(this);
return h('div', [
h('input', {
domProps: {
value: this.value
},
on: {
input: function (e) {
that.value = e.target.value
}
}
}),
h('h1', 'value:' + this.value),
h('button', {
attrs: { type: 'button' },
domProps: { innerHTML: 'btn' },
on: {
click: this.handleClick
}
})
])
}
}
}
js替换模板功能之事件和按键修饰符
对于 .passive、.capture和 .once这些事件修饰符, Vue提供了相应的前缀可以用于on:
修饰符 | 前缀 |
---|---|
.passive | & |
.capture | ! |
.once | ~ |
.capture.once 或 .once.capture | ~! |
修饰符对应的处理函数也是可用的
过滤器
局部过滤器
Vue.js允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和v-bind 表达式 。过滤器应该被添加在JavaScript 表达式的尾部,由“管道”符号指示:
<body>
<div id='app'>
<cpn></cpn>
</div>
<template id="cpn">
<div>
{{msg|gl}}
<h1>{{num|jg}}</h1>
<test :msg="msg|gk"></test>
</div>
</template>
<script src='./js/vue.js'></script>
<script>
const app = new Vue({
el: '#app',
components: {
cpn: {
template: '#cpn',
data() {
return {
msg: 'hello world',
num: 1000
}
},
filters: {
gl(value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice('1')
},
gk(value) {
console.log(value);
if (!value) return ''
return value.toString().split('').shift().toUpperCase()
}
}
}
}
})
</script>
</body>
全局过滤器
Vue.filter(“过滤器名称”,fn)
<body>
<div id='app'>
<cpn></cpn>
{{info|aa}}
<cpn1></cpn1>
</div>
<template id="cpn">
<div>
<h1>{{msg|aa}}</h1>
</div>
</template>
<script src='./js/vue.js'></script>
<script>
Vue.filter('aa', function (value) {
if (!value) return ''
return value.toString().charAt(0).toUpperCase() + value.slice(1)
})
const app = new Vue({
el: '#app',
data: {
info: 'aaaaa'
},
components: {
cpn1: {
template: '<div>{{info|aa}}</div>',
data() {
return { info: 'bbb' }
}
},
cpn: {
template: '#cpn',
data() {
return { msg: 'hello world' }
}
}
}
})
</script>
</body>
当全局过滤器和局部过滤器重名时,会采用局部过滤器。
Vue.filter('aa', function (value) {
if (!value) return ''
return value.toString().charAt(0).toUpperCase() + value.slice(1)
})
......
filters: {
aa(value) {
if (!value) return ''
return value.toString().charAt(1).toUpperCase() + value.slice(1)
}
}
......
串联过滤器
过滤器函数总接收表达式的值(之前的操作链的结果) 作为第一个参数。
<body>
<div id='app'>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h1>{{msg|aa|bb}}</h1>
</div>
</template>
<script src='./js/vue.js'></script>
<script>
const app = new Vue({
el: '#app',
data: {
info: 'aaaaa'
},
components: {
cpn: {
template: '#cpn',
data() {
return { msg: 'hello world' }
},
filters: {
aa(value) {
if (!value) return ''
return value.toString().charAt(0).toUpperCase() + value.slice(1)
}, //Hello world1
bb(value) {
console.log(value);
if (!value) return ''
return value.toString().charAt(1).toUpperCase() + value.slice(1)
}
}
}
}
})
</script>
</body>
在这个例子中,aa被定义为接收单个参数的过滤器函数,表达式msg的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数bb,将 aa的结果传递到bb 中。
过滤器是 JavaScript函数,因此可以接收参数:
<h1>{{msg|aa('val1',info)}}</h1>
这里,aa被定义为接收三个参数的过滤器函数。其中msg 的值作为第一个参数,普通字符串’val1’ 作为第二个参数,表达式info 的值作为第三个参数。