this.$slots 在 render 函数中的应用

<div id="app">
<my-component>
<p > 灌篮高手</p>
<p >我是要成为海贼王的男人</p>
<h1>我是h1</h1>
<h3 slot="header">《海贼王》</h3> // 用 slot 给 h3起个名字
<!-- 插值 -->
<h5 slot="footer">《火影忍者》</h5>
</my-component>
</div>

<script>
//第三个参数存的就是 VNODE(虚拟节点) createElement('header',header),返回的就是VNODE
Vue.component('my-component', {

render:function(createElement) {
var header = this.$slots.header
//返回的内容就是 含有VNODE数组
// 使用 this.$slots.header 访问名字是 header 的元素
var main = this.$slots.default
var footer = this.$slots.footer
return createElement('div',[
createElement('header',header),
// 创建 header 标签以及它里边的内容
createElement('main',main),
createElement('footer',footer)
])
},
})

var app = new Vue({
el: '#app',

})
</script>

从上例可以看出,在 render 函数中可以不使用 slot 元素,而是直接使用 this.$slots 访问到相应的元素。注意,h3 和 h5 标签中的 slot 是属性,用来给元素“起个名字”的,不是元素!

 

render 函数(二)_赋值

console.log(Array.isArray(header))  // true
console.log(Array.isArray(footer)) // true
console.log(Array.isArray(main)) // true

由上可得,header、main、footer 都是数组。

这些数组中,存的是 VNode(虚拟节点),也就是 <my-component></my-component> 中的节点。
​​​console.log(header)​

render 函数(二)_赋值_02

createElement 的第三个参数,存的就是 VNode(虚拟节点)。

 

在 render 函数中使用 props 传递数据

在 render 函数中,父组件给子组件传递数据的步骤:
在父组件绑定数据;
在子组件使用 props 接收数据;
在子组件使用接收到的数据。

<div id="app">
<button @click="switchshow">点击切换</button> {{show}}
<my-component :show="show"> </my-component>
</div>

<script>
//需求:点击按钮切换图片
//通过点击按钮改变 父组件show 的 true false,改变之后把show 传递给子组件,
//子组件在 prpps 中接收,接收完以后通过 render函数 构建一个 img 标签,通过this.show来改变src 路径,srcl路径在 attrs中进行设置
Vue.component('my-component', {
props: ['show'],
render: function (createElememt) {
var imgsrc
if (this.show) {
imgsrc = 'img/1.jpg'
} else {
imgsrc = 'img/2.jpg'
}
return createElememt('img', {
attrs: {
src: imgsrc
},
style: {
width: '300px',
height: '300px'
}
})
},
})

var app = new Vue({
el: '#app',
data: {
show: true
},
methods: {
switchshow: function () {
this.show = !this.show
}
},
})
</script>

render 函数(二)_数据_03

 

点击切换

 

render 函数(二)_数据_04

在 render 函数中使用 v-­model

在 render 函数中使用 v-model 绑定父组件中的数据;

  • 在父组件中使用 v-model 绑定父组件中的数据;
  • 在子组件中使用 $emit() 触发 input 事件,并传递子组件中的数据。
<div id="app">
<!-- 将name传递过来 -->
<!-- 在input里面输入值的时候,就会将输入的值传递给父组件,在页面上显示。子组件给父组件传递数据 -->
<!-- @input 接收数据 showname事件名-->
<!-- input 事件执行showname方法接收一个数据,把数据赋值给你想要的内容 -->
<!-- <my-component :name="name" @input="showName"></my-component> -->
<my-component :name="name" v-model="name"></my-component>
<!-- v-model 绑定name,做了两步操作:
1.self.$emit('input',event.target.value) 接收子组件传递的数据
2.赋值给绑定的name -->
<br> {{name}}
</div>

<script>
Vue.component('my-component', {
render: function (createElement) { //render渲染组件
var self = this;//在createElememt里面调用this, 指的就是当前的vue实例
return createElement('input', {
domProps: {
value: self.name//将接收的name赋值给input框
},
//在render函数里面写事件方法的时候需要将 this 赋值给一个变量,用到vue中的方法使用声明的变量来调用
on: {//input事件
input: function (event) {//默认会把原生的event事件给传递进来

//此处的this指的是什么?
//此处的this是window,所以不能直接用this.$emit,需要用 Vue 实例中的this来调用,所以声明var self = this.
self.$emit('input', event.target.value)//event.target.value传递input输入的内容;子组件要向父组件传递信息,在父组件上接收;输入内容的时候,触发input事件
}
}
})
},
props: ['name']//props接收name
})

var app = new Vue({
el: '#app',
data: {
name: '你好'
},
// methods: {
// showName:function(value){//showname方法自动加一个参数(自定义),这里的value就是触发input事件之后传递的值
// this.name = value//把value值赋值给this.name
// }
// },
})
</script>

在render函数中使用作用域插槽

作用域插槽使得父组件可以从子组件中获取数据。

<div id="app">
<child-component>
<template slot-scope="data">
<!-- 在父组件中使用 slot-scope 定义变量,data 就是子组件传过来的对象-->
{{ data.text }}
</template>
</child-component>
</div>

Vue.component('child-component', {
render: function (createElement) {
return createElement('div', this.$scopedSlots.default({
// 使用 this.$scopedSlots.default 定义子组件中的数据
text: '我是子组件中的内容'
}))
}
})

var app = new Vue({
el: '#app',
data: {
},
})`

函数化组件

函数化组件在实际开发中并不常用。

<div id="app">
<my-component ></my-component>
</div>
<script>
Vue.component('my-component', {
functional: true, //表示当前vue实例无状态,无实例
//无实例表示没有this这个概念
//context 上下文模块
render: function (createElement, context) {
return createElement('button',{
on:{
click:function(){
console.log(context)

}
}
},'点击我学习context')
}
})
var app = new Vue({
el: '#app',
data: {

}
})
</script>

render 函数(二)_Vue_05

 

可以从中找到需要的 API 。如:打印出父组件 data 中的数据:

render: function (createElement, context) {
return createElement('button', {
on: {
click: function () {

var a = this
console.log(context)
console.log(context.parent)
// alert(context.parent.msg)
// console.log(context.props.value)
alert(this.value) //undefined
}
}
}, '点击我学习context')
}

var app = new Vue({
el: '#app',
data: {
msg: '父组件内容'
}
})

上面代码中的 context.parent 可以访问到父组件。