VUE 2.X
1.ref引用
1)什么是ref引用
ref用来辅助开发者在不依赖jQuery的轻快下,获取DOM元素或组件的引用.
每个vue的组件实例上,都包含一个$refs对象,里面存储这对应的DOM元素或组件的引用.默认情况下,组件的$refs指向一个空对象
2)使用示例
- 组件中给html标签添加ref属性,并且命名,名称不能重复
<div class="box2">
<h2 ref="myh2">ref测试</h2>
<button @click="showThis">打印this</button>
</div>
- 在methods方法或者其他js操作中,通过this.$refs.名称,来获取对应的DOM元素,比如:
export default {
methods:{
showThis(){
console.log(this)
console.log(this.$refs.myh2.innerHTML)
}
},
}
3)在子组件上使用ref
- 给子组件添加ref属性,并且命名为"leftComRef",示例:
<div class="box">
<Left :msg="msg" :user="user" ref="leftComRef"></Left>
<button @click="showSonCom">打印子组件元素</button>
</div>
- 父组件中获取子组件,并操作子组件数据或调用子组件方法
export default {
methods:{
showSonCom(){
console.log(this.$refs.leftComRef.message)
this.$refs.leftComRef.showMessage()
}
},
}
注:给ref属性命名的时候,最好以ref结尾,便于区分
4)this.$nextTick(callback)使用场景
组件的$nextTick(callback)方法,会把callback回调推迟到下一个DOM更新周期之后执行.
通俗的理解是:等组件的DOM更新完成之后,再执行callback回调函数.从而保证callback回调函数可以操作到最新的DOM元素.示例代码:
- 按钮1和按钮2完成显示隐藏功能,按钮添加ref属性
<div class="box3">
<button v-if="btnFlag" @click="showBtn" ref="btn1Ref">按钮1:显示按钮2</button>
<button v-else @click="showBtn">按钮2:显示按钮1</button>
</div>
- showBtn方法中使用this.$nextTick(callback)
export default {
data:{
return {
btnFlag:true
}
},
methods:{
showBtn(){
this.btnFlag = !this.btnFlag
this.$nextTick(()=>{
if(this.btnFlag){
console.log('按下了按钮2,按钮1显示了')
console.log(this.$refs.btn1Ref.innerHTML)
}
})
}
},
}
2.js数组常用方法
-
Array.push(),向数组的末尾添加一个或多个元素,并返回新的数组长度。原数组改变。
-
Array.pop(),删除并返回数组的最后一个元素,若该数组为空,则返回undefined。原数组改变。
-
Array.unshift(),向数组开头添加一个或多个元素,并返回新的数组长度。原数组改变。
-
Array.shift(),删除数组的第一项,并返回第一个元素的值,若该数组为空,则返回undefined。原数组改变。
-
Array.concat(arr1,arr2…),合并两个或多个数组,生成一个新的数组。原数组不变。
-
[…arr1,…arr2] 拼接数组,等同于上面的concat
-
Array.join(),将数组的每一项用指定字符连接形成一个字符串,默认连接字符是","
-
Array.reverse(),将数组倒叙,原数组改变
-
Array.sort(),对数组元素进行排序。按照字符串UniCode码排序,原数组改变。
-
Array.map(function),原数组每一项执行函数后,返回一个新数组,原数组不变,示例代码:
var arr = [1,2,3]
var newArr = arr.map(item=> item + ‘str’) // [‘1str’, ‘2str’, ‘3str’] -
Array.splice(index,howmany,arr1,arr2…),用于添加或删除数组中的元素。从index位置开始删除howmany个元素,并将arr1、arr2…数据从index位置依次插入。howmany为0时,则不删除元素。原数组改变。
-
Array.forEach(function),用于调用数组的每个元素,并将元素传递给回调函数。原数组不变。
-
Array.filter(function),过滤数组中,符合条件的元素并返回一个新的数组。— 删除数组也可以用此方法
-
Array.every(function),对数组中的每一项进行判断,若都符合则返回true,否则返回false。
-
Array.some(function),对数组中的每一项进行判断,若都不符合则返回false,否则返回true。
-
Array.reduce(function),reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
-
indexOf() 检测当前值在数组中第一次出现的位置索引,没有找到则返回-1
-
includes() 判断一个数组是否包含一个指定的值
参考:
https://blog.youkuaiyun.com/weixin_45822171/article/details/123773198
https://www.bilibili.com/read/cv9715493/
3.动态组件
1)基本概念
动态组件指的是动态切换组件的显示和隐藏
2)如何实现动态组件
vue提供了一个内置的组件,专门用来实现动态组件的渲染.示例代码如下:
<button @click="switchCom">切换组件</button>
<div class="box">
<!-- 其中通过is属性动态绑定data属性值来切换组件-->
<component :is="comName"></component>
</div>
export default {
data(){
return {
comName:'Left'
}
},
methods:{
switchCom(){
this.comName = this.comName === 'Left'?'Right':'Left'
}
},
}
3)keep-alive的介绍与使用
- 背景:在使用动态组件的时候,每次切换组件,组件中的数据都会重置,为了避免这种情况,则需要使用keep-alive
- 原因:在使用动态组件切换组件的时候,每次切换都会销毁然后重新创建组件
- 验证方式:在组件中添加生命周期函数
示例代码:
<div class="box">
<keep-alive>
<component :is="comName"></component>
</keep-alive>
</div>
4)keep-alive对应的生命周期函数
当组件被缓存时,会自动触发组件的deactivated生命周期函数
当组件被激活时,会自动触发组件的activated生命周期函数
示例代码:
export default {
data:{
return{
comName:"Left"
}
},
created(){
console.log("left组件被创建了...")
},
destroyed(){
console.log("left组件被销毁")
},
deactivated(){
console.log("left组件被缓存了...")
},
activated(){
console.log("left组件被激活了")
},
}
注:当组件第一次被创建的时候,既会执行crated生命周期函数,也会执行activated生命周期函数;但是,当组件被重新激活的时候,只会执行activated生命周期函数
5)keep-alive的include,exclude属性
include属性用来指明:只有匹配的组件会被缓存,多个组件之间用",“分隔
exclude属性用来指明:哪些组件不需要被缓存,多个组件之间用”,"分隔
<div class="box">
<!-- 组件名称 -->
<keep-alive include="Left,Right">
<component :is="comName"></component>
</keep-alive>
</div>
注:include和exclude不要同时使用
6)关于组件名称
如果没有给组件起名称,那么组件的名称与当前注册的名称一致
App.vue中注册Right组件:
export default {
components:{
Left, // 注册名称主要是为了程序猿能够以标签方式使用组件,而页面真正展示的名称是组件自己声明的名称
Right
}
}
Right组件自己声明组件名称:
export default {
// 组件的声明名称用途:1.keep-alive中使用 2.页面展示时呈现
name:'MyRight'
}
4.插槽
1)什么是插槽
插槽(Slot)是vue为组件的封装者提供的能力,允许开发者在封装组件时,把不确定的,希望由用户指定的部分定义为插槽
2)插槽名称
vue官方规定:每一个slot插槽,都要有一个name名称,如果省略了slot的name属性,则有一个默认名default.
默认情况下,在使用组件的时候,提供的内容都会被填充到名为default的插槽中
3)把内容填充到指定插槽
- 需要使用v-slot指令
- v-slot 后面要跟上插槽的名称
- v-slot:不能直接用在当前元素身上,必须用在template标签
- template标签,它是一个虚拟的标签,只起到包括性质的作用,不会被渲染成任何实质的html元素
- v-slot可以简写成"#",使用示例:
Left.vue定义插槽:
<div>
<p>插槽</p>
<!-- 插槽的使用与默认内容 -->
<slot name="leftSlot"><h6>这是插槽的默认内容11</h6></slot>
<hr>
<!-- 定义插槽的时候,可以定义多个同名插槽,同名插槽内容相同,默认值可以不同 -->
<slot name="leftSlot"><h6>这是插槽的默认内容22</h6></slot>
</div>
App.vue使用:
<Left :msg="msg" :user="user" ref="leftComRef">
<template v-slot:leftSlot>
<p>这是用户在left组件中自定义内容</p>
</template>
</Left>
或者
<Left :msg="msg" :user="user" ref="leftComRef">
<template #leftSlot>
<!-- 如果不填写内容,则显示插槽的默认内容 -->
<p>这是用户在left组件中自定义内容</p>
</template>
</Left>
4)作业域插槽
在封装组件时,为预留的<slot>提供属性对应的值,示例代码:
- 在组件Left.vue中定义插槽
<div>
<p>插槽</p>
<!-- 插槽的使用 -->
<slot name="leftSlot" msg="hello vue.js"><h6>这是插槽的默认内容111</h6></slot>
<hr>
<slot name="leftSlot" msg2="hello vue.js2"><h6>这是插槽的默认内容222</h6></slot>
</div>
- App.vue中使用作用域插槽
// 这里的scope就是插槽中定义的属性和值,是一个对象{}
<template v-slot:leftSlot="scope">
<p>这是用户在left组件中自定义内容</p>
<p>{{ scope.msg }}</p>
<p>{{ scope.msg2 }}</p>
</template>
或
<template #leftSlot="scope">
<p>这是用户在left组件中自定义内容</p>
<p>{{ scope.msg }}</p>
<p>{{ scope.msg2 }}</p>
</template>
或
<!-- 解构赋值 -->
<template #leftSlot="{msg,msg2,user}">
<p>这是用户在left组件中自定义内容</p>
<p>{{ msg }}</p>
<p>{{ msg2 }}</p>
<p>{{ user }}</p>
</template>
5.自定义指令
1)分类
自定义指令分为两类:私有自定义指令,全局自定义指令
2)私有自定义指令
在每个vue组件中,可以在directives节点下声明私有自定义指令,示例代码如下:
1. 当前组件中定义自定义指令(无入参)
export default {
data:{
return {}
},
directives:{
color:{
bind(el){
el.style.color='red'
}
}
}
}
// 当前组件中使用使用自定义指令
<div class="test-container">
<p>========自定义指令=======</p>
<h2 v-color>自定义指令color</h2>
</div>
2. 自定义指令接收入参
export default {
data(){
return {
color:'blue'
}
},
directives:{
color:{
// 当指令第一次被绑定到元素上的时候,会立即触发bind函数
// 形参中的el表示当前指令所绑定到的那个DOM对象
// 通过第二个形参binding可以获取到指令入参
bind(el,binding){
console.log('触发了v-color指令')
el.style.color = binding.value
console.log(binding)
}
}
}
}
<div class="test-container">
<p>========自定义指令=======</p>
<!-- 属性绑定color -->
<h2 v-color = "color">自定义指令color111</h2>
<!-- 直接入参green -->
<h2 v-color="'green'">自定义指令color222</h2>
</div>
3)自定义指令update函数
由于bind函数只调用1次,当指令第一次绑定到元素时调用,当DOM更新时bind函数不会被触发,update函数会在每次DOM更新时被调用,示例代码如下:
export default {
data(){
return {
color:'blue'
}
},
directives:{
color:{
// 当指令第一次被绑定到元素时被调用
bind(el,binding){
console.log('触发了v-color指令')
el.style.color = binding.value
console.log(binding)
},
// 每次DOM更新时调用
update(el,binding){
el.style.color = binding.value
}
}
}
}
4)自定义指令的简写
如果定义指令的时候,bind和update函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式:
export default {
data(){
return {
color:'blue'
}
},
directives:{
color(el,binding){
el.style.color = binding.value
}
}
}
5)全局自定义指令
全局共享的自定义指令需要通过"Vue.directive()"进行声明,示例代码:
// 参数1:字符串,表示全局自定义指令的名称
// 参数2:对象,用来接收指令的参数值
Vue.directive('color',function(el,binding){
console.log('全局自定义指令....')
console.log(el)
console.log(binding)
el.style.color = binding.value
})
注:全局自定义指令在main.js中定义