如何理解Vue的render函數(shù)的具體用法
本文介紹了如何理解Vue的render函數(shù)的具體用法,分享給大家,具體如下:
第一個參數(shù)(必須) - {String | Object | Function}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<elem></elem>
</div>
<script>
Vue.component('elem', {
render: function(createElement) {
return createElement('div');//一個HTML標簽字符
/*return createElement({
template: '<div></div>'//組件選項對象
});*/
/*var func = function() {
return {template: '<div></div>'}
};
return createElement(func());//一個返回HTML標簽字符或組件選項對象的函數(shù)*/
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
第二個參數(shù)(可選) - {Object}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<elem></elem>
</div>
<script>
Vue.component('elem', {
render: function(createElement) {
var self = this;
return createElement('div', {//一個包含模板相關(guān)屬性的數(shù)據(jù)對象
'class': {
foo: true,
bar: false
},
style: {
color: 'red',
fontSize: '14px'
},
attrs: {
id: 'foo'
},
domProps: {
innerHTML: 'baz'
}
});
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
第三個參數(shù)(可選) - {String | Array}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<elem></elem>
</div>
<script>
Vue.component('elem', {
render: function(createElement) {
var self = this;
// return createElement('div', '文本');//使用字符串生成文本節(jié)點
return createElement('div', [//由createElement函數(shù)構(gòu)建而成的數(shù)組
createElement('h1', '主標'),//createElement函數(shù)返回VNode對象
createElement('h2', '副標')
]);
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
兩種組件寫法對比
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<ele></ele>
</div>
<script>
/*Vue.component('ele', {
template: '<div id="elem" :class="{show: show}" @click="handleClick">文本</div>',
data: function() {
return {
show: true
}
},
methods: {
handleClick: function() {
console.log('clicked!');
}
}
});*/
Vue.component('ele', {
render: function(createElement) {
return createElement('div', {
'class': {
show: this.show
},
attrs: {
id: 'elem'
},
on: {
click: this.handleClick
}
}, '文本');
},
data: function() {
return {
show: true
}
},
methods: {
handleClick: function() {
console.log('clicked!');
}
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
this.$slots用法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<blog-post>
<h1 slot="header"><span>About Me</span></h1>
<p>Here's some page content</p>
<p slot="footer">Copyright 2016 Evan You</p>
<p>If I have some content down here</p>
</blog-post>
</div>
<script>
Vue.component('blog-post', {
render: function(createElement) {
var header = this.$slots.header,//返回由VNode組成的數(shù)組
body = this.$slots.default,
footer = this.$slots.footer;
return createElement('div', [
createElement('header', header),
createElement('main', body),
createElement('footer', footer)
])
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
使用props傳遞數(shù)據(jù)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<ele :show="show"></ele>
<ele :show="!show"></ele>
</div>
<script>
Vue.component('ele', {
render: function(createElement) {
if (this.show) {
return createElement('p', 'true');
} else {
return createElement('p', 'false');
}
},
props: {
show: {
type: Boolean,
default: false
}
}
});
new Vue({
el: '#app',
data: {
show: false
}
});
</script>
</body>
</html>
VNodes必須唯一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<!-- VNode必須唯一 -->
<div id="app">
<ele></ele>
</div>
<script>
var child = {
render: function(createElement) {
return createElement('p', 'text');
}
};
/*Vue.component('ele', {
render: function(createElement) {
var childNode = createElement(child);
return createElement('div', [
childNode, childNode//VNodes必須唯一,渲染失敗
]);
}
});*/
Vue.component('ele', {
render: function(createElement) {
return createElement('div',
Array.apply(null, {
length: 2
}).map(function() {
return createElement(child)//正確寫法
})
);
}
});
new Vue({
el: '#app'
})
</script>
</body>
</html>
v-model指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<el-input :name="name" @input="val=>name=val"></el-input>
<div>你的名字是{{name}}</div>
</div>
<script>
Vue.component('el-input', {
render: function(createElement) {
var self = this;
return createElement('input', {
domProps: {
value: self.name
},
on: {
input: function(event) {
self.$emit('input', event.target.value);
}
}
})
},
props: {
name: String
}
});
new Vue({
el: '#app',
data: {
name: 'hdl'
}
});
</script>
</body>
</html>
作用域插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<ele>
<template scope="props">
<span>{{props.text}}</span>
</template>
</ele>
</div>
<script>
Vue.component('ele', {
render: function(createElement) {
// 相當于<div><slot :text="msg"></slot></div>
return createElement('div', [
this.$scopedSlots.default({
text: this.msg
})
]);
},
data: function() {
return {
msg: '來自子組件'
}
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
向子組件中傳遞作用域插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<ele></ele>
</div>
<script>
Vue.component('ele', {
render: function(createElement) {
return createElement('div', [
createElement('child', {
scopedSlots: {
default: function(props) {
return [
createElement('span', '來自父組件'),
createElement('span', props.text)
];
}
}
})
]);
}
});
Vue.component('child', {
render: function(createElement) {
return createElement('b', this.$scopedSlots.default({text: '我是組件'}));
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
函數(shù)化組件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<smart-item :data="data"></smart-item>
<button @click="change('img')">切換為圖片為組件</button>
<button @click="change('video')">切換為視頻為組件</button>
<button @click="change('text')">切換為文本組件</button>
</div>
<script>
// 圖片組件選項
var ImgItem = {
props: ['data'],
render: function(createElement) {
return createElement('div', [
createElement('p', '圖片組件'),
createElement('img', {
attrs: {
src: this.data.url
}
})
]);
}
}
// 視頻組件
var VideoItem = {
props: ['data'],
render: function(createElement) {
return createElement('div', [
createElement('p', '視頻組件'),
createElement('video', {
attrs: {
src: this.data.url,
controls: 'controls',
autoplay: 'autoplay'
}
})
]);
}
};
/*純文本組件*/
var TextItem = {
props: ['data'],
render: function(createElement) {
return createElement('div', [
createElement('p', '純文本組件'),
createElement('p', this.data.text)
]);
}
};
Vue.component('smart-item', {
functional: true,
render: function(createElement, context) {
function getComponent() {
var data = context.props.data;
if (data.type === 'img') return ImgItem;
if (data.type === 'video') return VideoItem;
return TextItem;
}
return createElement(
getComponent(),
{
props: {
data: context.props.data
}
},
context.children
)
},
props: {
data: {
type: Object,
required: true
}
}
});
new Vue({
el: '#app',
data() {
return {
data: {}
}
},
methods: {
change: function(type) {
if (type === 'img') {
this.data = {
type: 'img',
url: 'https://raw.githubusercontent.com/iview/iview/master/assets/logo.png'
}
} else if (type === 'video') {
this.data = {
type: 'video',
url: 'http://vjs.zencdn.net/v/oceans.mp4'
}
} else if (type === 'text') {
this.data = {
type: 'text',
content: '這是一段純文本'
}
}
}
},
created: function() {
this.change('img');
}
});
</script>
</body>
</html>
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于Vue2的獨立構(gòu)建與運行時構(gòu)建的差別(詳解)
下面小編就為大家分享一篇基于Vue2的獨立構(gòu)建與運行時構(gòu)建的差別詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
vue v-for循環(huán)重復數(shù)據(jù)無法添加問題解決方法【加track-by=''索引''】
這篇文章主要介紹了vue v-for循環(huán)重復數(shù)據(jù)無法添加問題解決方法,結(jié)合實例形式分析了vue.js通過在v-for循環(huán)中添加track-by='索引'解決重復數(shù)據(jù)無法添加問題相關(guān)操作技巧,需要的朋友可以參考下2019-03-03
vue-cli自定義創(chuàng)建項目eslint依賴沖突解決方式
vue-cli是vue.js的腳手架,用于自動生成vue.js+webpack的項目模板,在創(chuàng)建項目時,如果遇到npm安裝報錯,通常是由于依賴版本沖突造成的,文中通過圖文以及代碼介紹的非常詳細,需要的朋友可以參考下2024-09-09
在vue中使用eacharts創(chuàng)建graph關(guān)系圖方式
這篇文章主要介紹了在vue中使用eacharts創(chuàng)建graph關(guān)系圖方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
el-select如何獲取下拉框選中l(wèi)abel和value的值
在開發(fā)業(yè)務(wù)場景中我們通常遇到一些奇怪的需求,例如el-select業(yè)務(wù)場景需要同時獲取我們選中的label跟 value,下面這篇文章主要給大家介紹了關(guān)于el-select如何獲取下拉框選中l(wèi)abel和value的值,需要的朋友可以參考下2022-10-10

