1.具名插槽
1.1 什么是具名插槽
具名插槽:使用slot标签的时候,给标签添加name属性,name属性就是插槽中标签设置的slot的的值;
关键点:把组件标签对中的内容标签对添加slot属性,slot属性对应那个组件模板slot标签的name属性;
_注意:使用默认插槽slot标签不会显示具名插槽中的内容_
1.2 具名插槽的使用方式
1.在子组件的标签对中添加内容,内容中要使用插槽的标签添加slot属性,并设置其自定义的slot值;
2.在子组件模板中可以使用slot标签来代替显示子组件标签对中内容,并在slot标签对中添加name属性,设置name属性值与第一步中的slot的属性值相同;
第一步设置,还可以时候使用其他两种写法:
第二种:使用template标签对,添加v-slot属性和设置其v-slot属性值与slot标签name值相同;
第三种:使用template标签对,添加#属性值与slot标签name值相同;
1.3 代码演示
<div id="app">
<page>
<!-- 第一种写法 设置slot属性和设置slot属性值对应插槽中的name属性值-->
<h1 slot="header">网页头部</h1>
<h2 slot="main">网页内部</h2>
<h3 slot="footer">网页尾部</h3>
<!-- 第二种写法 使用template标签加v-slot属性和对应的插槽的name属性值 -->
<template v-slot:main>
<h1>网页内容</h1>
</template>
<template v-slot:footer>
<h1>网页尾部</h1>
</template>
<template v-slot:header>
<h1>网页头部</h1>
</template>
<!-- 第三种写法 使用#+插槽名对应的插槽的name属性值 -->
<template #header>
<h1>
网页头部
</h1>
</template>
<template #footer>
<h1>
网页尾部
</h1>
</template>
<template #main>
<h1>
网页主体
</h1>
</template>
</page>
</div>
Vue.component('page', {
template: `
<div>
<header style='border:1px solid green;'>
<slot name='header'></slot>
</header>
<main style='border:1px solid yellow;'>
<slot name='main'></slot>
</main>
<footer style='border:1px solid red;'>
<slot name='footer'></slot>
</footer>
<slot></slot>
</div>
`
})
new Vue({
el: '#app',
data: {
},
methods: {
},
})
2 深度监听
2.1 监听器
在vue中通过在组件内部添加watch字段设置监听器对象;
watch字段中设置监听的data中的数据,然后设置其对应的监听匿名函数,此函数中有两个参数,第一个参数是改变后(现在)的值,第二个参数是改变前的值;
watch监听器常常使用来监听计算属性或者data中数据上,但是监听的数据是一个对象(引用类型的值),仅仅改变此对象中的属性值,并不能触发此监听器;(感觉监听引用类型值,此监听的是地址);那么就需要设置深度监听来监听对象等引用类型值,可以使用深度监听来监听对象中某个属性;
2.2 深度监听实现方式
与基本类型的监听直接设置函数不同,对对象的深度监听是设置个对象;
在此对象中的handle属性值设置监听函数;
设置属性值deep为true;
2.3 深度监听代码演示
new Vue({
el: '#app',
data: {
obj:{
name:"张三",
age:10
}
},
watch:{
// 使用深度监听,可以监听整个对象,并且在对象字段发生变化的时候可以被检测到。
// 属性值是对象,包含监听函数handler 和deep:true开启深度监听。
obj:{
handler:function(n1){
//此处是改变后的obj,但是此处引用值都是指向同一地址,所有第二个参数实际上显示的还是改变后的obj
console.log(n1)
},
deep:true
},
//可以直接监听对象一个字段 当对象字段进行修改的时候 监听函数会被触发
"obj.name":{
handler:function(n1,o1){
console.log(n1,o1)
}
}
}
})
3.强制更新
3.1 为什么data中数组中某一个元素发生变化时候,使用数组渲染的页面没有变化?
数据响应式原理:组件在初始化,遍历data所有的属性,为所有属性通过object.defineProperty给每个属性都添加了set和get函数,当以后对数据进行修改,调用set函数,set函数里面调用页面更新的函数,所以说只要是数据发生变化,页面也会随之更新;
原因:data在初始化的时候,本质上使用的object.defineProperty进行数据拦截时,只是对数组本身进行拦截;array本身是具备响应式特点,并且设置set和get函数,但是没有对数组中的元素进行数据拦截,也就是说数组里面的元素没有set和get方法,当数组的某个数据进行更新的时候,不具有响应式特点;
3.2 数据更新,页面不更新的例子;
1. data中某一个元素发生变化,数组的长度没有发生变化时候;
2. 在钩子函数中设置添加的全局data数据,数据改变,使用其数据渲染的页面并没有刷新;
3.在钩子函数对象中添加的属性,属性值改变,使用属性值渲染的页面并没有刷新;
3.3 强制更新的方法
1. 针对数组的一种强制更新方式: this.$set(更新的数据源 , 更新的索引 , 数据源中索引的元素的更新后的结果);
2. 使用splice函数来改变数值中某个元素的值;
3. 针对数组,可以使用改变数组长度方式来更改:pop、push、shift、unshift等
4. 任何需要更新的都可以使用此方式进行更新; this.$forceUpdate();