文章目录
- 一、文档
- 二、区别
- 三、使用
- h函数的参数解释:
- 参数一:
- 使用导入的组件名
- 参数二:
- 绑定css
- 绑定事件
- 往组件里面传递参数
- 动态绑定值props
- 动态绑定值data
- functional:true到底是做什么的?
- 动态绑定props 非functional:true版本
- 参数三:
- 参数为文本时
- 当参数为数组时
- 当参数里面设置插槽时
- 如何给插槽填写默认值
- 具名插槽
一、文档
(官方文档)
官网地址:https://cn.vuejs.org/api/options-rendering#render
渲染机制说明:https://cn.vuejs.org/guide/extras/rendering-mechanism
渲染函数说明:https://cn.vuejs.org/guide/extras/render-function
(个人参考文档)
如何使用:https://blog.csdn.net/ccattempt/article/details/120481481
render介绍:https://blog.csdn.net/w807139809/article/details/122106086
二、区别
同常规的vue有什么区别:
1、同等条件下,render编程式渲染速度优异,因为编程式跳过了三个阶段的转化(parser -> transform -> generate)
2、编程式缺少了传统template模板编写形式的便捷手段(通俗的讲:用起来不顺手,因为js需要与标签混着写)
3、语法完全不一样(render缺少全局this、标签使用变量由{{}}转为了单{}、、、)
三、使用
<script>
export default {
name: "patientSourceImage",
functional: true,
render(h, context) {
//render需要返回一个vNode节点
//h函数 :参数一原生标签名、或者引入的组件名
// 参数二:为创建的标签绑定的属性内容,可以是class类名、可以是事件、自定义属性......
// 参数三:可以是字符串Text文本或者是h函数构建的对象再者可以是有插槽的对象。
//context 由于没有全局的this,因此出现了context,context是一个对象,里面有很多属性如props、data......
return h('div',{class:"contain"},[<p>render渲染</p>])
}
};
</script>
h函数的参数解释:
参数一:
<script>
export default {
name: "patientSourceImage",
functional: true,
render(h, context) {
//h函数 :参数一原生标签名、或者引入的组件名
//div,就是普通的div元素标签名
return h('div',{class:"contain"},[<p>render渲染</p>])
}
};
</script>
使用导入的组件名
<script>
import HelloWorld from "./components/HelloWorld";
export default {
name: "patientSourceImage",
functional: true,
components: {
HelloWorld,
},
render(h, context) {
//HelloWorld ,导入的组件,没有引号,需要先进行组件注册
return h(HelloWorld, { class: "contain" }, [<p>render渲染</p>]);
},
};
</script>
参数二:
绑定css
<script>
export default {
name: "patientSourceImage",
functional: true,
render(h, context) {
return h(
"div",
//绑定css可以通过类名。或者style属性
{ class: "contain", style: { background: "black", color: "white" } },
[<p>render渲染</p>]
);
},
};
</script>
绑定事件
<script>
export default {
name: "patientSourceImage",
data: function () {
return {
tt: "前端吴彦祖是tjq",
};
},
functional: true,
render: function (h, context) {
return h(
"div",
{
class: "contain",
style: {
background: "black",
color: "white",
},
//绑定事件通过on来进行绑定,
//~ 前缀,表示函数只执行一次
on: {
"~click": () => {
alert("缓存清理成功");
},
mouseout: (e) => {
console.log("鼠标移出", e);
},
},
},
[<p>{111}</p>]
);
},
};
</script>
往组件里面传递参数
<script>
import HelloWorld from "./components/HelloWorld.vue"
export default {
name: "patientSourceImage",
data: function () {
return {
tt: "前端吴彦祖是tjq",
};
},
components: {
HelloWorld,
},
functional: true,
render: function (h, context) {
const name = "tjq";
return h(
HelloWorld,
{
class: "contain",
props: {
name: name,
},
},
[<p>吴彦祖</p>]
);
},
};
</script>
动态绑定值props
app.vue文件
<template>
<div>
<button @click="age++">age++</button>
<HelloWorld :age="age"></HelloWorld>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
data() {
return {
age: 1,
};
},
components: {
HelloWorld,
},
};
</script>
<style scoped>
</style>
HelloWorld.vue
<script>
export default {
name: "HelloWorld",
props: ["age"],
data: function () {
return {
tt: "前端吴彦祖是tjq",
};
},
functional: true,
//解构赋值 context,取出props
render: function (h, { props }) {
return h(
"div",
{
class: "contain",
style: {
background: "black",
color: "white",
},
},
[<p>{props.age}</p>]
);
},
};
</script>
动态绑定值data
这里我们需要去掉functional:true
<script>
export default {
name: "helloworld",
data() {
return {
name: "tjq",
age: 18,
};
},
render(h) {
return h(
"div",
{
on: {
click: () => {
this.age++; //或者使用this.$data.age $data是data的一个映射,同样的也有props的映射$props......
},
},
},
`name:${this.$data.name},age${this.age}`
);
},
};
</script>
functional:true到底是做什么的?
在 Vue 中,当组件设置 functional: true 时,组件函数将被视为无状态函数组件。无状态函数组件没有实例,没有响应式数据,并且不支持实例方法和生命周期钩子函数。由于它们没有实例上下文,因此无法直接访问插槽。
因此我们上面的所有示例,可以把functional: true去掉,去掉之后我们的render函数缺少了context这一参数,但同时我们也可以调用this变量
举个例子:
动态绑定props 非functional:true版本
app.vue文件
<template>
<div>
<button @click="age++">age++</button>
<HelloWorld :age="age"></HelloWorld>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
data() {
return {
age: 1,
};
},
components: {
HelloWorld,
},
};
</script>
<style scoped>
</style>
helloworld.vue文件
<script>
export default {
name: "HelloWorld",
props: ["age"],
render: function (h) {
// render: function (h ,context) { 之前我们是content.props.age来进行获取的
//现在多了this,我们直接this.$props即可
console.log(this.$props.age);
return h("div", {}, [<p>{this.$props.age}</p>]);
},
};
</script>
参数三:
<script>
export default {
name: "patientSourceImage",
functional: true,
render(h, context) {
return h(
"div",
//参数三,可以是一段文本,也可以是一个数组
{},
[<p>render渲染</p>]
);
},
};
</script>
参数为文本时
<script>
export default {
name: "patientSourceImage",
functional: true,
render(h, context) {
return h(
"div",
{},
'啦啦啦,我是前端吴彦祖'
);
},
};
</script>
当参数为数组时
<script>
export default {
name: "patientSourceImage",
functional: true,
render(h, context) {
return h("div", {}, [<em>我是前端吴彦祖</em>,<br/>, `<em>我是前端吴彦祖</em>`]);
},
};
</script>
当参数里面设置插槽时
上诉也提到,functional: true为无状态函数,没有插槽,因此用到插槽我们同样不能使用functional: true
app.vue文件
<template>
<div>
<HelloWorld >
<p>我是前端吴彦祖</p>
<em>我是前端吴彦祖</em>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
data() {
return {
age: 1,
};
},
components: {
HelloWorld,
},
};
</script>
<style scoped>
</style>
helloworld.vue文件
<script>
export default {
name: "helloworld",
render(h) {
return h(
"div",
{ class: "menuBox" },
this.$scopedSlots.default()
);
},
};
</script>
如何给插槽填写默认值
app.vue文件
<template>
<div>
<HelloWorld >
<p>我是前端吴彦祖</p>
<em>我是前端吴彦祖</em>
</HelloWorld>
<!-- 没写默认插槽,会使用默认值 -->
<p>下面的用默认值<p/>
<HelloWorld >
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
data() {
return {
age: 1,
};
},
components: {
HelloWorld,
},
};
</script>
<style scoped>
</style>
helloworld.vue
<script>
export default {
name: "helloworld",
data() {
return {
name: "tjq",
};
},
render(h) {
const scopedSlotFn = this.$scopedSlots.default;
//scopedSlotFn为undefined时表示并没有传递插槽
//如果传递了, scopedSlotFn会是一个函数,该函数的返回值是对应的插槽组件
if (scopedSlotFn) {
const slotVNode = scopedSlotFn();
return h("div", [slotVNode]);
}
return h("div", {}, ["默认的插槽内容"]);
},
};
</script>
具名插槽
helloworld.vue文件
<script>
export default {
name: "helloworld",
data() {
return {
name: "tjq",
};
},
render(h) {
//slots表示所有接收到的插槽
const slots = this.$slots;
//提前预设的插槽,default是默认插槽
const slots_arr = ["default", "title"];
const slot_key = Object.keys(slots).map((item) =>
slots_arr.includes(item) ? slots[item] : null
);
if (slot_key.length) {
return h("div", [...slot_key]);
}
return h("div", {}, ["默认的插槽内容"]);
},
};
</script>
或者使用下面这种写法
helloworld文件
<script>
export default {
name: "helloworld",
data() {
return {
name: "tjq",
};
},
render(h) {
//预设哪个插槽就this.$slots[预设的插槽名]
return h("div", {}, [this.$slots.title, this.$slots.default]);
},
};
app.vue
<template>
<div>
<HelloWorld >
<p>我是前端吴彦祖</p>
<em slot="title">标题插槽</em>
<em slot="detail">没有接受这个插槽</em>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
data() {
return {
age: 1,
};
},
components: {
HelloWorld,
},
};
</script>
<style scoped>
</style>