vue-

复习vue特性: 自定义v-model、$nextTick、slot、动态异步组件、keep-alive、mixin

主要参考来源:

v-model

你可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。 — vue官方文档

基本用法:

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<input type="text" id="name" v-model="name">
</template>
<script>
export default {
data () {
return {
name: 'zjl',
}
}
}
</script>

v-model 做了什么?

v-model 是个语法糖,一个指令实现数据同步、绑定数据,类似如下代码:

1
<input type="text" v-bind:value="tangVal" v-on:input="tangVal=$event.target.value">

修饰符

  • .lazy v-model 默认 input 事件触发值与数据同步,添加 lazy 修饰符之后,会转为 change 事件之后进行同步;
  • .number 自动将输入的内容转为数字类型(type=”number”返回的值也是字符串);
  • .trim 自动过滤用户输入的首尾空白字符

自定义组件使用 v-model

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突 — vue官方文档

手写一个input 和 select

自定义 input 组件

1
2
3
4
5
6
7
8
9
10
<template>
<input type="text" :value="value" @input="$emit('input', $event.target.value)">
</template>
<script>
export default {
props: {
value: String
},
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<select :value="value" @input="$emit('change', $event.target.value)">
<option value="学生">学生</option>
<option value="老师">老师</option>
<option value="工人">工人</option>
<option value="其他">其他</option>
</select>
</template>
<script>
export default {
model: {
prop: 'value',
event: 'change'
},
props: {
value: String
}
}
</script>

$nextTick

将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上 — vue官方文档
$nextTick 是vue 实例的方法

  • 参数: {Function} [callback]

通俗的讲就是,当vue实例的数据更新之后,dom会发生变化,dom更新数据之后采购执行 $nextTick 的回调。

不使用 $nextTick,data更改之后直接使用dom元素获取 dom 的 innerText

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div class="main">
<p id="test_data">测试dom:{{ name }}</p>
<button @click="onClickSetData">点击更改为->456</button>
</div>
</template>
<script>
export default {
name: 'TestNextTick',
data () {
return {
name: '123',
}
},
methods: {
onClickSetData() {
this.name = '456';
console.log(document.getElementById('test_data').innerText);
}
}
}
</script>

控制台打印结果:

1
测试dom:123

结果表明,修改了vue 实例的data后,直接获取 dom 的 innerText,获取结果依旧是更改data之前的内容;
使用 $nextTick,更改 methods

1
2
3
4
 onClickSetData() {
this.name = '456';
console.log(document.getElementById('test_data').innerText);
}

控制台打印结果:

1
测试dom:456

$nextTick 的使用场景

  • 生命周期 created 内需要操作dom时,需要使用 $nextTick;
  • 生命周期 mounted 内需要操作 dom 时,推荐使用 $nextTick;官方文档描述,mounted 不会保证所有的子组件也都被挂载完成,所以在此生命周期需要操作dom时候,推荐使用 $nextTick;
  • 数据更新之后需要操作 dom,需要使用 $nextTick,保证 此时操作的 dom 是最终渲染完毕的;

注意

$nextTick 在官方文档最后,有参考异步更新队列。
当 vue 实例的 data 被修改,组件并不会立即重新渲染 DOM。这个过程是异步的,vue会开启一个队列,这个事件会被推入队列(中间也做了去除重复数据渲染这样不必要的操作)。

当你设置 vm.someData = ‘new value’,该组件不会立即重新渲染。当刷新队列时,组件会在下一个事件循环“tick”中更新。多数情况我们不需要关心这个过程,但是如果你想基于更新后的 DOM 状态来做点什么,这就可能会有些棘手。虽然 Vue.js 通常鼓励开发人员使用“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们必须要这么做。为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用 — vue官方文档

slot

插槽

动态异步组件

keep-alive

mixin

当有多个组件有部分公用的 vue 实例方法时,可以使用mixin 将通用的部分提取出来。