前端小伙伴们有没有遇到过这样的场景,iviewUI组件库中select双向绑定数据时,修改了绑定值,可是页面中渲染的值仍是以前的值,不论是去打印仍是使用vue插件去查看变量,均显示绑定值已修改,但是页面始终显示修改以前的数据,是否是很困恼,心中简直是卧槽、卧槽、卧槽。html
我以前作过很暴力的事情,就是在select标签上绑定v-if,在修改v-modal的值时,对v-if对应的变量先赋值false,紧接着赋值true,若是还不行就加个延时settimeout。当时还为本身的机智洋洋得意,如今想一想属实是真没文化,吃了读书少的亏。前端
最近从新阅读vue官网文档时,读到了这段话:vue
当 Vue.js 用 v-for
正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。若是数据项的顺序被改变,而不是移动 DOM 元素来匹配数据项的顺序, Vue 将简单复用此处每一个元素,而且确保它在特定索引下显示已被渲染过的每一个元素。这个相似 Vue 1.x 的 track-by="$index"
。react
这个默认的模式是有效的,可是只适用于不依赖子组件状态或临时 DOM 状态(例如:表单输入值)的列表渲染输出。算法
为了给 Vue 一个提示,以便它能跟踪每一个节点的身份,从而重用和从新排序现有元素,你须要为每项提供一个惟一 key
属性。理想的 key
值是每项都有惟一 id。这个特殊的属性至关于 Vue 1.x 的 track-by
,但它的工做方式相似于一个属性,因此你须要用 v-bind
来绑定动态值(在这里使用简写):bash
<div v-for="item in items" :key="item.id"> <!-- 内容 --></div>复制代码 |
建议尽量使用 v-for
来提供 key
,除非迭代 DOM 内容足够简单,或者你是故意要依赖于默认行为来得到性能提高。iview
由于它是 Vue 识别节点的一个通用机制, key
并不特别与 v-for
关联,key 还具备其余用途,咱们将在后面的指南中看到其余用途。dom
划重点了,划重点了,划重点了,重要的事说三遍,ide
由于它是 Vue 识别节点的一个通用机制, key
并不特别与 v-for
关联,key 还具备其余用途,咱们将在后面的指南中看到其余用途。
性能
由于它是 Vue 识别节点的一个通用机制, key
并不特别与 v-for
关联,key 还具备其余用途,咱们将在后面的指南中看到其余用途。
由于它是 Vue 识别节点的一个通用机制, key
并不特别与 v-for
关联,key 还具备其余用途,咱们将在后面的指南中看到其余用途。
我觉着key能够为我作点什么,以后我又看了一下react中diff算法的文章(vue原理与之一致),发现这个key果然厉害的不要不要的。
key值的做用主要用来减小不必的diff算法的对比,对于同一个组件或者节点来讲,只要父节点状态或属性发生改变,该组件就会进行diff 对比,即便该组件没有发生改变;若是为该组件引入key值,在进行diff对比前先作一次校验,判断该组件是否须要diff对比,也能够判断该 组件是直接更新操做仍是销毁或者新建操做,从而提升了diff算法的效率;特别在渲染同级同结构的组件们时,key能够为它们加上了身份的 标志,在rerender时,能够经过key来判断该组件是否已经存在,是否须要跟新或者销毁,新建等操做,提升了diff算法在同级节点上的操做。 原理: 由于在reactelement中有一个属性是key,该属性默认是为空值,因此通常状况下,只要组件不加上key值,react是不会去校验组件 的key,而是直接采用diff算法进行对比,一旦组件加上了key值,react就会在渲染时对该组件的身份进行校验,首先校验新旧组件的key值 是否是一致,不一致的话,该组件直接销毁,而后在新建该组件;若是一致,则比较组件的属性是否发生变化,若是发生变化,则采用diff算 法进行对比,而后得出差别对象,若是属性没发生变化,则认为该组件不须要改变;
回到文章一开始提到的问题,个人理解是select这部分的dom被就近复用了,所以有时才会出现修改v-modal的值以后页面显示的是以前的值,所以,我就想到了,为何不能在select上绑定key值,说作就作。
<select v-modal="selectValue" :key="selectkey" @onChange="selectChange">
<option>111</option>
...
</select>复制代码
每次修改值的时候我会让selectKey自增一下,也就是说让select的身份标识发生变化,获得从新渲染,这样就规避掉绑定值不生效的现象了,也规避掉v-if带来的闪一下的不良体验。
亲测有效,但愿遇到相同问题的小伙伴可以用得上。