Render函数(3):函数式组件、JSX初接触
写在前面:说实话视频学习的方式真的不适合我...之前在B站和慕课上的Vue视频学的组件啊Vuex啊router真的只是囫囵吞枣啊,会用是会用,但是呆的很。
还是纸质适合我,应该这一周就能复习完Vuex和router了,冲!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="Vue.2.6.10.js"></script>
</head>
<body>
<div id="app1">
<smart-item :data='data'></smart-item>
<button @click='change("img")'>切换至图片组件</button>
<button @click='change("video")'>切换至视频组件</button>
<button @click='change("text")'>切换至文字组件</button>
</div>
</body>
<script>
//vue提供了一个functional的布尔值选项(注册组件时),若设置为true,则会使得组件无状态、无实例,即没有data、this上下文,这样使用render函数
//返回的虚拟节点可以更容易渲染,因为函数化的组件只是一个函数(即functional为true)
//图片组件选项
var imgComp = {
props:['data'],
render(h) {
return createElement('div',[
createElement('p','图片组件'),
createElement('img',{
attrs:{
src:this.data.url
}
})
]);
},
};
var videoComp = {
props:['data'],
render:function(createElement){
return createElement('div',[
createElement('p','视频组件'),
createElement('video',{
attrs:{
src:this.data.url,
controls:'controls',
autoplay:'autoplay'
}
})
]);
}
};
var textComp = {
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){//使用函数化组件时,render函数提供了第二个参数context
//来提供临时上下文,组件中需要的data、props、slots、children、parent都是通过它来传递的
//this.level---context.props.level, this.$slots.default---context.children
function getCom(){
var data = context.props.data;
if(data.type === 'img') return imgComp;
if(data.type === 'video') return videoComp;
return textComp;
};
return createElement(
getCom(),
{
props:{
data:context.props.data//从组件smart-item传向上面getCom()返回的组件
}
},
context.children//父组件插槽的默认内容
)
},
props:{
data:{
type:Object,
required:true
}
}
});
var app1 = new Vue({
el:"#app1",
data:{
data:{}//默认为对象嗷
},
methods: {
change:function(type){
if(type === 'img'){
this.data = {
type:'img',
url:''
}
}else if(type === 'video'){
this.data = {
type:'video',
url:''
}
}else if(type === 'text'){
this.data = {
type:'text',
text:'文本组件,冲!'
}
}
}
},
created() {
this.change('text');
},
});
//jsx是什么?它是一种看起来像html,但实际上是js的语法扩展
// // createElement&jsx:
// render(createElement){
// return createElement('div',{
// props:{
// text:'some text'
// },
// attrs:{
// id:'myDiv'
// },
// domProps:{
// innerHTML:'content'
// },
// on:{
// change:this.change
// },
// nativeOn:{
// click:this.clickHandler
// },
// class:{
// show:true,
// on:false
// },
// style:{
// color:"#fff",
// background:'#f50'
// },
// key:'key',
// ref:'element',
// slot:'slot'
// })
// };//改写为jsx如下:
// render(h) {
// return {
// <div
// id='myDiv'
// domPropsInnerHTML='content'
// onChange = {this.change}
// class={{ show:true, on:false }}
// style = {{ ... }}
// }
// }
</script>
</html>