搞懂vue 的 render 函数, 并使用
render函数是什么
简单的说,在vue中我们使用模板HTML语法组建页面的,使用render函数我们可以用js语言来构建DOM
因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode(虚拟节点)的函数,而用render函数构建DOM,vue就免去了转译的过程。
当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具。官网上给他起了个名字叫createElement。
Vue的渲染过程
template =>render() => h => h它是原生js的createElement() => 创建真实元素 => 生成虚拟dom
使用render函数的渲染过程:
render() => h => h它是原生js的createElement() => 创建真实元素 => 生成虚拟dom
render函数怎么用
父组件:
<template>
<div class="hello">
<Buttem :type="value" :text="text"></Buttem>
</div>
</template>
<script>
import Buttem from '../views/button.vue'
export default {
name: '',
data() {
return {
value: 'success',
text: '成功按钮'
}
},
components: {
Buttem,
}
}
</script>
子组件button.vue:
<script>
export default {
props: {
type: {
type: String,
default: 'normal'
},
text: {
type: String,
default: 'normal'
},
},
// Vue的渲染过程
// template =>render() => h => h它是原生js的createElement() => 创建真实元素 => 生成虚拟dom
render(h) {
// 创建一个button元素
return h('button', {
class: { // 类
btn: true, // 每个按钮都有最初级的样式
'btn-success': this.type === 'success', // 根据条件不同给定样式
'btn-error': this.type === 'error', // 根据条件不同给定样式
'btn-warning': this.type === 'warning', // 根据条件不同给定样式
'normal': !this.type, //
},
// dom属性
domProps: {
innerText: this.text || '默认按钮'
},
})
}
}
</script>
<style scoped>
.btn {
width: 100px;
height: 40px;
color: white;
transition: all 0.5s;
}
.btn-success {
background: green;
}
.btn-error {
background: red;
}
.btn-warning {
background: yellow;
}
.normal {
background: blueviolet;
}
</style>
深入 data 对象
有一件事要注意:正如在模板语法中,v-bind:class 和 v-bind:style ,会被特别对待一样,在 VNode 数据对象中,下列属性名是级别最高的字段。该对象也允许你绑定普通的 HTML 特性,就像 DOM 属性一样,比如 innerHTML (这会取代 v-html 指令)。
{
// 和`v-bind:class`一样的 API
'class': {
foo: true,
bar: false
},
// 和`v-bind:style`一样的 API
style: {
color: 'red',
fontSize: '14px'
},
// 正常的 HTML 特性
attrs: {
id: 'foo'
},
// 组件 props
props: {
myProp: 'bar'
},
// DOM 属性
domProps: {
innerHTML: 'baz'
},
// 事件监听器基于 `on`
// 所以不再支持如 `v-on:keyup.enter` 修饰器
// 需要手动匹配 keyCode。
on: {
click: this.clickHandler
},
// 仅对于组件,用于监听原生事件,而不是组件内部使用
// `vm.$emit` 触发的事件。
nativeOn: {
click: this.nativeClickHandler
},
// 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
// 赋值,因为 Vue 已经自动为你进行了同步。
directives: [
{
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
bar: true
}
}
],
// Scoped slots in the form of
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props => createElement('span', props.text)
},
// 如果组件是其他组件的子组件,需为插槽指定名称
slot: 'name-of-slot',
// 其他特殊顶层属性
key: 'myKey',
ref: 'myRef'
}