VUE一般使用template來創建HTML,然後在有的時候,我們需要使用javascript來創建html,這時候我們需要使用render函數。
以下我們來做一個需求跟根據level等級來編寫對應等級的標題
template解析
<body>
<divid="app">
<h-titlelevel=1>
<p>Alley</p>
</h-title>
<h-titlelevel=2>
<p>Alley</p>
</h-title>
</div>
</body>
</html>
<scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component("h-title", {
template: `<div>
<h1 v-if="level==1"><slot></slot></h1>
<h2 v-else-if="level==2"><slot></slot></h2>
</div>`,
props: {
level: {
type: Number,
required: true
}
}
})
letvm=newVue({
el: "#app"
})
</script>
render解析
<body>
<divid="app">
<h-titlelevel=1>
<p>Alley</p>
</h-title>
<h-titlelevel=2>
<p>Alley</p>
</h-title>
</div>
</body>
</html>
<scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component("h-title", {
render:function(createElement){
returncreateElement(
"h"+this.level,
this.$slots.default
)
},
props: {
level: {
type: Number,
required: true
}
}
})
letvm=newVue({
el: "#app"
})
</script>二者對比我們不難看出render函數創建組件的方式更加的靈活,同時也能讓我們最大的發揮出JavaScript的編程能力
二、render函數詳解
Vue中的Render函數中有一個參數,這個參數是一個函數通常我們叫做h。其實這個h叫做createElement。Render函數將createElement的返回值放到了HTML中
createElement這個函數中有3個參數
第一個參數(必要參數):主要用於提供DOM的html內容,類型可以是字符串、對象或函數
第二個參數(類型是對象,可選):用於設置這個DOM的一些樣式、屬性、傳的組件的參數、綁定事件之類
第三個參數(類型是數組,數組元素類型是VNode,可選):主要是指該結點下還有其他結點,用於設置分發的內容,包括新增的其他組件。注意,組件樹中的所有VNode必須是唯一的
createElement(
'div',
{
attrs: {
name: headingId,
href: '#'+headingId
},
style: {
color: 'red',
fontSize: '20px'
},
'class': {
foo: true,
bar: false
},
domProps: {
innerHTML: 'baz'
},
props: {
myProp: 'bar'
},
on: {
click: function(event) {
event.preventDefault();
console.log(111);
}
}
}
[
'xxxx',
createElement('h1', '一則頭條'),
createElement(MyComponent, {
props: {
someProp: 'xxx'
}
}),
this.$slots.default
]
)三、什麼時候用render函數?假設我們要封裝一套按鈕組件,按鈕有四個樣式(success、error、warning、default)。首先,你可能會想到如下實現
<template>
<divclass="btn btn-success"v-if="type === 'success'">{{ text }}</div>
<divclass="btn btn-danger"v-else-if="type === 'danger'">{{ text }}</div>
<divclass="btn btn-warning"v-else-if="type === 'warning'">{{ text }}</div>
</template>雖然我們這樣實現沒有問題,但是如果現在有十幾個樣式的情況下我們就需要寫N多個判斷,如果遇到了這種情況我們就可以選擇使用render函數。
其實簡單的來說就是template適合簡單的組件封裝,然後render函數適合複雜的組件封裝
<script>
Vue.component("alley-button", {
props: {
type: {
type: String,
default: 'default'
},
text: {
type: String,
default: '按鈕'
}
},
computed: {
tag() {
switch(this.type) {
case'success':
return1;
case'danger':
return2;
case'warning':
return3;
default:
return1;
}
}
},
render(h) {
returnh('div', {
class: {
btn: true,
'btn-success': this.type==='success',
'btn-danger': this.type==='danger',
'btn-warning': this.type==='warning'
},
domProps: {
},
on: {
click: this.handleClick
}
},
this.$slots.default
);
},
methods: {
handleClick() {
console.log('---');
console.log('alley');
}
}
})
letvm=newVue({
el: "#app"
})
</script>四、template與render函數對比
相同之處:
render 函數 跟 template 一樣都是創建 html 模板
不同之處:
如果你喜歡本文,請分享到朋友圈,想要獲得更多信息,請關注我。