Vue高级特性
自定义v-model $nextTick slot 动态异步组件 keep-alive mixin refs
自定义V-model
v-model其实是一个语法糖,绑定了一个叫value的属性,然后处理了一个叫input的事件,事件中把返回值重新赋给了value
<template>
<!-- 例如:vue 颜色选择 -->
<input type="text"
:value="text1"
@input="$emit('change1', $event.target.value)"
>
<!--
1. 上面的 input 使用了 :value 而不是 v-model
2. 上面的 change1 和 model.event1 要对应起来
3. text1 属性对应起来
-->
</template>
<script>
export default {
model: {
prop: 'text1', // 对应 props text1
event: 'change1'
},
props: {
text1: String,
default() {
return ''
}
}
}
</script>
$nextTick
Vue是异步渲染
data改变之后,DOM 不会立刻渲染
$nextTick 会在DOM 渲染之后被触发,以获取最新DOM 节点
<template>
<div id="app">
<ul ref="ul1">
<li v-for="(item, index) in list" :key="index">
{{item}}
</li>
</ul>
<button @click="addItem">添加一项</button>
</div>
</template>
<script>
export default {
name: 'app',
data() {
return {
list: ['a', 'b', 'c']
}
},
methods: {
addItem() {
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
// 1. 异步渲染,$nextTick 待 DOM 渲染完再回调
// 3. 页面渲染时会将 data 的修改做整合,多次 data 修改只会渲染一次
this.$nextTick(() => {
// 获取 DOM 元素
const ulElem = this.$refs.ul1
// eslint-disable-next-line
console.log( ulElem.childNodes.length )
})
}
}
}
</script>
Slot 插槽 父组件往子组件插入点元素
,slot就是可以让你在组件内添加内容的‘空间
父组件 在子组件<slot> </slot>处插入 data
默认插槽:又名匿名插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个匿名插槽。
// 子组件 : (假设名为:ebutton)
<template>
<div class= 'button'>
<button> </button>
<slot></slot>
</div>
</template>
new Vue({
el:'.button',
data:{
child:'子组件'
}
})
// 父组件:(引用子组件 ebutton)
<template>
<div class= 'app'>
<ebutton> {{ child }}</ebutton>
</div>
</template>
子组件 ebutton 多个<slot ></slot> <slot></slot> 对应插入内容 具名插槽
<template>
<div class= 'button'>
<button> </button>
<slot name= 'one'> 这就是默认值1</slot>
<slot name='two'> 这就是默认值2 </slot>
<slot name='three'> 这就是默认值3 </slot>
</div>
</template>
父组件
书写 v-slot:one 的形式时,可以简写为 #one
//父组件:(引用子组件 ebutton)
<template>
<div class= 'app'>
<ebutton>
<template #one> 这是插入到one插槽的内容 </template>
<template #two> 这是插入到two插槽的内容 </template>
<template v-slot:three> 这是插入到three插槽的内容 </template>
</ebutton>
</div>
</template>
作用域插槽 ( 父组件 在子组件 <slot> </slot> 处使用子组件 data)
通过slot 我们可以在父组件为子组件添加内容,通过给slot命名的方式,我们可以添加不止一个位置的内容。但是我们添加的数据都是父组件内的
//子组件 : (ebutton)
<template>
<div class= 'button'>
<button> </button>
<slot name= 'one' :value1='child1'> 这就是默认值1</slot> //绑定child1的数据
<slot :value2='child2'> 这就是默认值2 </slot> //绑定child2的数据
</div>
</template>
new Vue({
el:'.button',
data:{
child1:'数据1',
child2:'数据2'
}
})
//父组件:(引用子组件 ebutton)
<template>
<div class= 'app'>
<ebutton>
// 通过v-slot的语法 将插槽 one 的值赋值给slotonevalue
<template v-slot:one = 'slotonevalue'>
{{ slotonevalue.value1 }}
</template>
// 同上,由于子组件没有给slot命名,默认值就为default
<template v-slot:default = 'slottwovalue'>
{{ slottwovalue.value2 }}
</template>
</ebutton>
</div>
</template>