Object.assign()实际上对每个源对象执行的是浅复制。如果多个源对象都有相同的属性,则使 用最后一个复制的值。
Array.isArray()
关于render
render 与 template 二者仅能选择一个,而且测试过 render 的渲染级别要比 template高。说明在 render 这个函数当中 this 将指向 Vue实例app的$data对象 使用 Vue.h 来动态的创建一个 VNode 节点。说明几个问题:
- render 函数 仅替代了 template 这个 option 选项
- Component Option 中的 data、props... 均能够正常被使用
- 其中不同的是 插槽,在使用插槽时不能够再使用 标签了取而代之的是 this.$slots 对象,而其中的 属性即代表 命名插槽.但是这个属性,它是一个函数,调用该函数才能返回相应的 插槽中的对象
- 插槽 函数中获取出的内容,不再是文本型,而是一个被转化过的 VNode 列表.
- 如果说 template 是让我们以书写 html 标签的形式来创建 VNode 节点,那么这个render 函数 就是让我们以javascript 的形式来创建 VNode 节点。
- 获取出来的这个 VNode 节点列表,怎么渲染在 页面上呢?那就要使用 h 函数了
聊聊h函数:
h函数 可以接受三个参数:
1、 tag(必须) string object function
string 指的是 标签 tag
object 指的是 组件
function指的是 异步组件、函数式组件
2、props (可选的) 其实就是添加到这个创建的标签上的 Attribute 但是不需要再去指定 v-bind了,这个对象当中 键 作为 属性名称 值 作为属性的值 添加到新创建的元素上。
3、children(可选的)
你这个元素当中 还需要添加个啥东西? 可以是 string Array Object
string 代表 里边就是一个文本 注意这个字符串均是转义的
Object 对象 {} 不行 应该是 Vue.h 创建的 VNode对象
[] 列表 Array 是不是更好理解了? children 列表啊?
demo演示:
html代码:
<div id="example14">
<anchored-heading :level="3">
This is a <span>Title <i>No.1</i></span>
</anchored-heading>
</div>
js代码
Vue.createApp({
components:{
anchoredHeading:{
props:['level'],
render()
{
let test_text = getChildrenTextContent(this.$slots.default())
console.log(test_text)
//获取了所有的文本内容 This is a Title No.1
test_text = test_text
.toLowerCase()
.replace(/\W+/g,'-')
.replace(/(^-|-$)/g,'')
console.log(test_text)
return Vue.h(
`h${this.level}`,
{id:test_text},
Vue.h('a',{href: `#${test_text}`},this.$slots.default())
)
}
}
}
}).mount('#example14')
render只代替 template,如果要重复创建一毛一样的多个元素的话
return Vue.h('ul', Array.from({ length: 10 }).map((_, index) => Vue.h('li', `测试元素${index + 1}`)));
或者也是可以的
const new_v_node = Vue.h('p', { title: '是向新创建的VNode对象添加 Attribute' },
return Array(10).fill(new_v_node);
books && books.length <<<?
// books 删了可以吧?
// 兼容 几个情况
// 1、 props 中没有传递值 books 将为 undefined
// 如果此时直接判断 undefined.length 将报错
// 2、 props 是一个空列表, 空列表的情况下,列表也是一个对象,对象在任何时候判断都为 true
// 所以要在 books 不为 undefined 的情况下,再判断一下 books.length !== 0
// 短路控制符 <<<< 一定要注意鸭