render函数初步了解
template下只允许有一个子节点
- 代码引入
<body>
<div id = "app">
<child :level = "level">
我是蜡笔小新。
</child>
</div>
<template id = "hdom">
<!--template下只允许有一个子节点-->
<div>
<h1 v-if = "level == 1">
<slot></slot>
</h1>
<h2 v-if = "level == 2">
<slot></slot>
</h2>
<h3 v-if = "level == 3">
<slot></slot>
</h3>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
//父组件向子组件传递数据,传递的数据是1-6,对应子组件的内容就会被h1-h6包裹。
//使用Vue组件进行定义
Vue.component('child',{
props:['level'],
template: '#hdom'
});
var app = new Vue({
el: '#app',
data: {
level: 2
}
})
</script>
</body>
以上代码过于冗长,并且使用v-if会先渲染页面在移除,所以引入render函数。
- 具体代码实现
<body>
<div id = "app">
<child :level = "level">
我是蜡笔小新。
</child>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
//父组件向子组件传递数据,传递的数据是1-6,对应子组件的内容就会被h1-h6包裹。
//使用render函数进行定义
Vue.component('child',{
render: function(createElement){
return createElement('h'+ this.level,this.$slots.default);
},
props:['level']
});
var app = new Vue({
el: '#app',
data: {
level: 2
}
})
</script>
</body>
render函数的第一个参数
在render函数的方法中,参数必须是createElement
,createElement
的类型是function
alert(typeof createElement) // function
render函数的第一个参数可以是 String | Object | Function
,并且render函数的第一个参数是必选的。
- render 函数的第一个参数string,创建一个HTML标签div
return createElement('div')
- render 函数的第一个参数Object,创建一个含有数据选项的对象
return createElement({
template: '<div>这是参数object</div>'
})
- render 函数的第一个参数是Function,返回一个含有数据选项的对象
var domFun = function(){
return {
template: '<div>这是参数function</div>'
}
};
return createElement(domFun());
}
render函数的第二个参数
第二个参数是可选的,是数据对象----Object
<body>
<div id = "app">
<child></child>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
Vue.component('child',{
//第二个参数是数据对象
render: function(createElement){
return createElement({
template: '<div>我是内容</div>'
},{
'class': {
foo: true, //div的class类中有foo
baz: false //div的class类中没有false
},
style: {
color: 'red',
fontSize: '16px'
},
//正常的html特性(一般除了class和style之外都可以写进来)
attrs: {
id: 'cont',
src: 'badiic.com'
},
//用来写原生的DOM属性
domProps: {
innerHTML: '<span style = "color: blue">我是拉暗</span>',
innerText: '我是内容凄凄切切'
}
})
}
});
var app = new Vue({
el: '#app'
})
</script>
</body>
render函数的第三个参数
第三个参数也是可选的。类型:String | Array
作用:作为我们构建函数的子节点来使用的
Vue.component('child',{
//第三个参数是可选的---array --代表子节点
render: function(createElement){
return createElement('div',[
//创建一个h1标签,里面包含“我是h1”的文本节点,作为div的子节点
createElement('h1','我是h1'),
//h6的节点作为div的子节点
createElement('h6','我是h6')
])
}
});
this.$slots在render函数中的应用
第三个 参数存的就是VNODE
createElement(‘header’,header)
, 返回的就是VNODE
var header = this.$slots.heade
r; //–这返回的内容就是含有VNODE的数组
- 具体代码示例:
//第三个参数存的就是VNode的数组(虚拟节点)
Vue.component('child',{
render: function(createElement){
var header = this.$slots.header; //返回的内容就是含有Vnode的数组
var main = ths.$slots.default;
var footer = this.$slots.footer;
return createElement('div',[
createElement('header',header), //返回的是vnode
createElement('main',main),
createElement('footer',footer)
])
}
});
在render函数中使用props传递数据
- 具体代码实现
<body>
<div id = "app">
<button @click = "switshow">点击切换图片</button>{{show}}
<child :show = "show"></child>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
//点击按钮切换图片
Vue.component('child',{
props:['show'],
render: function(createElement){
var imgsrc;
if(this.show){
imgsrc = '../img/001.jpg'
}else {
imgsrc = '../img/002.jpg'
}
return createElement('img',{
attrs: {
src: imgsrc
},
style :{
width: '300px',
height: '300px'
}
})
}
});
var app = new Vue({
el: '#app',
data: {
show: false
},
methods: {
switshow:function(){
this.show = !this.show
}
}
})
</script>
</body>
v-model在render函数中的使用
- 代码引入
<body>
<div id = "app">
<child :name = "name" @input = "showName"></child>
<br>{{name}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
//
Vue.component('child',{
render: function(createElement){
var self = this;//this指的就是当前的value实例
return createElement('input',{
domProps:{
value: self.name
},
on :{
input:function(){
// c此处使用的是self
self.$emit('input',event.target.value)
}
}
})
},
props:['name']
});
var app = new Vue({
el: '#app',
data: {
name: 'JACK'
},
methods: {
showName: function(value){
this.name = value
}
}
})
/*@input触发的是父组件的showName方法,输入内容的时候,首先会触发子组件的self.$emit(),向
父组件传递信息,把输入的内容传递给父组件,父组件在showName方法中用value这个参数接收,直接
赋值给name*/
</script>
</body>
- V-model的实现代码
<body>
<div id = "app">
<child :name = "name" v-model = "name"></child>
<br>{{name}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
//
Vue.component('child',{
render: function(createElement){
var self = this;//this指的就是当前的value实例
return createElement('input',{
domProps:{
value: self.name
},
on :{
input:function(){
//只有vue实例才能调用$emit方法
//不能使用This,此处的this 指的是window
self.$emit('input',event.target.value)
}
}
})
},
props:['name']
});
var app = new Vue({
el: '#app',
data: {
name: 'JACK'
}
})
/*首选;v-model = name,他已经绑定了name,(即接受了从父组件传递过来的数据)。
其次,当触发input事件的时候,v-model绑定的就是input事件,
触发input事件,往父组件传递数据的时候,v-model会自动接收,并把它自动赋值给绑定的name。*/
</script>
</body>
作用域插槽在render函数中的使用
<div id = "app">
<child>
<!--prop就是render函数中传递的所有数,prop是自定义的-->
<template scope = "prop">
{{prop.text}}
{{prop.msg}}
</template>
</child>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
Vue.component('child',{
render: function(createElement){
//相当于<div><slot :text = "text></slot></div>
return createElement('div',this.$scopedSlots.default({
//对象中的内容为传递的数据
text:'我是子组件传递过来的数据',
msg: 'scopetext'
}))
}
});
var app = new Vue({
el: '#app'
})
</script>
</body>
函数化组件的应用
主要用于:程序化选择多个组件显示在页面中,从多个组件中选择一个的时候等会用到。
使用context的转变----
this.text --- context.props.text
this.$slots.default --- context.children
functional:true表示该组件无状态实例
- 代码示例
<body>
<div id = "app">
<child value = "haha">
</child>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
Vue.component('child',{
//拿到从外界传来的数据
functional: true,//当前的vue实例无状态。无实例。也就是说在组件内部没有this的概念
//所以传入了第二个参数context,可以通过context拿到数据
render:function(createElement,context) {
return createElement('button',{
on: {
click:function(){
console.log(context);
console.log(context.parent);
console.log(context.props.value);
console.log(context.parent.msg);
console.log(this.value) //undefined,因为此时的this代表window对象,不是value实例
}
}
},'点击我学习context')
}
});
var app = new Vue({
el: '#app',
data: {
msg: '我是父组件的内容,'
}
})
</script>
</body>
网友评论