第一個引數(必須) – {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標籤字元或元件選項物件的函式*/
}
});
new Vue({
el: `#app`
});
</script>
</body>
</html>
第二個引數(可選) – {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`, {//一個包含模板相關屬性的資料物件
`class`: {
foo: true,
bar: false
},
style: {
color: `red`,
fontSize: `14px`
},
attrs: {
id: `foo`
},
domProps: {
innerHTML: `baz`
}
});
}
});
new Vue({
el: `#app`
});
</script>
</body>
</html>
第三個引數(可選) – {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`, `文字`);//使用字串生成文字節點
return createElement(`div`, [//由createElement函式構建而成的陣列
createElement(`h1`, `主標`),//createElement函式返回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組成的陣列
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傳遞資料
<!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>
函式化元件
<!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>