Vue使用key属性管理可复用元素
问题
最近在使用Vue开发项目时,遇到了如下的问题:
在使用v-if进行状态切换时,Vue会复用两部分中相同的组件,导致该组件的created和自定义指令(bind形式)等不执行,一些状态不会进行刷新。
代码如下:
Test.vue文件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="test">
<fz-form ref="data" :model="addData" label-width="120px" v-if="step == 1">
<fz-form-item label="手机号:" prop="phone" validate="required,Phone">
<el-input placeholder="用户名/手机号" v-model="addData.phone"></el-input>
</fz-form-item>
</fz-form>
<fz-form ref="data1" :model="addData" label-width="120px" v-else>
<fz-form-item label="新密码:" prop="password" validate="required,password">
<el-input v-model="addData.password" type="password"></el-input>
</fz-form-item>
<fz-form-item label="确认新密码:" prop="endpassword" validate="required,password">
<el-input v-model="addData.endpassword" type="password"></el-input>
</fz-form-item>
</fz-form>
...
</div>
</template>
<script>
...
</script>
FormItem.vue文件1
2
3
4
5
6
7
8
9
10
11
12
13
14export default {
...
directives: {
validate: {
bind: function (el) {
//bind中定义了el-form的验证规则
...
}
}
},
created() {
...
}
}
上面代码的执行效果如下:
当从第一个表单切换到第二个表单时,vue会复用组件中的fz-form-item,而不会重新渲染该元素,这会使得该组件中的部分方法不执行,导致自定义的验证方法出现异常。
解决方法:
这里可以使用key对组件进行管理,可以在必要的地方避免组件复用,使得组件进行重新渲染。
用key管理可复用的元素
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。
同时 Vue 提供了一种方式来满足不复用已有元素的业务场景,此时只需要添加一个具有唯一值key属性。
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by=”$index” 。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的唯一 id。这个特殊的属性相当于 Vue 1.x 的 track-by ,但它的工作方式类似于一个属性,所以你需要用 v-bind 来绑定动态值 (在这里使用简写):1
2
3<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>