vue之render函数
vue之render函数
render函数的第一个参数
createElement
函数
下面我们介绍一下createElement函数的三个参数
createElement 函数的3个参数
-
必填参数。这个参数可以是一个 HTML 标签字符串(‘div’,或者‘span’等等)或者一个组件(
<my-child> </my-child>
等等),或者一个函数(Function)。类型:String | Object | Function。 -
选填参数。一个包含模板相关属性的数据对象(class、点击事件onclick等),你可以在 template 中使用这些特性。类型:Object。
-
选填参数。子虚拟节点 (VNodes),由 createElement() 构建而成,也可以使用字符串来生成“文本虚拟节点”。类型:String | Array。
下面介绍这三个参数的写法
// createElement第一个参数之使用HTML标签字符串
<div id="app"></div>
<script>
// 实例
const vm = new Vue({
el: "#app",
render:function(createElement){
return createElement("h2")
}
})
</script>
// createElement第一个参数之使用组件
<div id="app"></div>
<script>
// 组件选项对象
let Child= {
template:"<h3>我是子组件</h3>",
};
// 实例中注册组件
const vm = new Vue({
el: "#app",
render(createElement){
return createElement(Child)
}
})
</script>
// createElement第一个参数之使用函数
<div id="app"></div>
<script>
// 实例中注册组件
const vm = new Vue({
el: "#app",
render(createElement){
let myFn = function(){
return {
template:"<h1>正在使用render</h1>"
}
}
return createElement(myFn())
}
})
</script>
// createElement第二个参数之标签的属性
{
// 与 `v-bind:class` 的 API 相同,
// 接受一个字符串、对象或字符串和对象组成的数组
'class': {
foo: true,
bar: false
},
// 与 `v-bind:style` 的 API 相同,
// 接受一个字符串、对象,或对象组成的数组
style: {
color: 'red',
fontSize: '14px'
},
// 普通的 HTML attribute
attrs: {
id: 'foo'
},
// 组件 prop
props: {
myProp: 'bar'
},
// DOM property
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
}
}
],
// 作用域插槽的格式为
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props => createElement('span', props.text)
},
// 如果组件是其它组件的子组件,需为插槽指定名称
slot: 'name-of-slot',
// 其它特殊顶层 property
key: 'myKey',
ref: 'myRef',
// 如果你在渲染函数中给多个元素都应用了相同的 ref 名,
// 那么 `$refs.myRef` 会变成一个数组。
refInFor: true
}
// class style的不同写法
{
class:["class1",{"class2":true}],
style: {background: red}
}
// createElement第三个参数子虚拟节点之使用字符串String
<script>
const vm = new Vue({
el: "#app",
render:function(createElement){
return createElement("input", {
class:"title"
},"这是标题")
}
})
</script>
// createElement第三个参数子虚拟节点之使用Array
<script>
const vm = new Vue({
el: "#app",
render(h){
return h("div",{
class:"box",
},[
h("span","我是一个span标签"),
h("input",{
attrs:{
type:"button",
value:"按钮"
}
})
])
}
})
</script>
练习一下
<script>
export default {
props:{
tag:{
type:String,
required: true
}
},
render(createElement){
return createElement(this.tag,{},"按钮")
}
}
</script>
// 使用这个组件
<sub-components tag="button"></sub-components>
//相当于创建了一个按钮
<buttton>按钮</buttton>
<script>
export default {
props: {
tag: {
type: String,
required: true,
},
data: {
type: Array,
required:true
},
},
render(createElement) {
return createElement(this.tag, {},
// 嵌套到 this.tag 元素上
this.data.map(item=>
createElement('li',{},item.toString())
)
);
},
};
</script>
<sub-components tag="ul" :data="data"></sub-components>
data:["11111","22222","33333"]
// 相当于
<ul>
<li>11111</li>
<li>22222</li>
<li>33333</li>
</ul>
<script>
export default {
props: {
tag: {
type: String,
required: true,
},
data: {
type: Array,
required:true
},
},
render(createElement) {
return createElement(this.tag, {},
this.data.map(item=>
createElement('li',{
domProps: {
className: "child-element"
},
// 在on中我们可以写需要的事件
on:{
// 点击事件 点击打印 Pointer Event
click:(e)=>{
console.log(e)
},
// mouseover
// mouseout
}
},item.toString())
)
);
},
};
</script>