Vue動(dòng)態(tài)路由緩存不相互影響的解決辦法
關(guān)于react與vue中的key
之前在學(xué)習(xí)react的時(shí)候,常常遇到循環(huán)渲染組件時(shí)會(huì)提示需要在循環(huán)組件中加上key屬性,比如有一組列表:
import React, { Component } from 'react'; export default calss MainApp extends Component { state = { student: [ { name: 'Jenny', id: 'a001' }, { name: 'Jerry', id: 'a002' }, ] } render() { return ( <div> <ul> { this.state.student.map(item => { // key是必須的屬性,不然瀏覽器會(huì)拋出錯(cuò)誤提示 return (<li key={item.id}>{item.name}</li>) }) } </ul> </div> ) } }
可能對(duì)這個(gè)key不是太了解,或者也不許要太深入地去了解它,只知道在循環(huán)渲染組件時(shí),隨手加上這個(gè)屬性就好。摘自網(wǎng)上的的文章的總結(jié),key的作用為
key的作用主要是為了高效的更新虛擬DOM
雖然不是很懂,但也裝作大切大悟的樣子。key是一個(gè)給框架內(nèi)部用的,我們只管給它加上去就好。
Vue中的key
同樣有一個(gè)vue的組件:
<template> <div> <ul> <!-- key是必須的屬性,不然瀏覽器會(huì)拋出錯(cuò)誤提示 --> <li v-for="itme in student" :key={item.id}>{{item.name}}</li> </ul> </div> </template> <script> import vue from 'vue'; import { Component } from 'vue-property-decorator' @Component export default calss MainApp extends vue { student = [ { name: 'Jenny', id: 'a001' }, { name: 'Jerry', id: 'a002' }, ] } </script>
同樣的,回到vue中的key,其實(shí)也類(lèi)似,解釋key的作用,就不得不介紹一下虛擬DOM的diff算法了...算了,我也不是很懂
簡(jiǎn)單理解就是react與vue內(nèi)部判斷組件的一個(gè)標(biāo)識(shí),用于更新或者重用組件的一個(gè)重要屬性
更新
key用于更新:是框架內(nèi)部的算法實(shí)現(xiàn),一兩句話(huà)也說(shuō)不清楚(主要是我也不懂這個(gè)算法),簡(jiǎn)單理解為當(dāng)數(shù)據(jù)更新了,框架內(nèi)部會(huì)判斷更新頁(yè)面哪些DOM元素需要更新刪除等操作;
重用
key用于組件重用:其實(shí)key不止是在map或者v-for中使用,我們也也可以在其他組件上使用這個(gè)屬性(至于哪個(gè)組件可以加,小孩子才做選擇,我們的目標(biāo)是全都加!),當(dāng)然加了貌似也沒(méi)什么毛病,只是加了顯得有些多余!
在做SPA的時(shí)候,我們都會(huì)有一個(gè)主組件App.vue:
<template> <div id="app"> <div> <keep-alive> <router-view /> </keep-alive> </div> </div> </template> <script> import Vue from 'vue' import { Component } from 'vue-property-decorator' @Component export default class MainApp extends Vue { } </script>
上面代碼會(huì)把頁(yè)面全部都緩存下來(lái)(路由切換回來(lái)的時(shí)候,頁(yè)面表單填寫(xiě)的內(nèi)容沒(méi)有被清空),這是應(yīng)為在<router-view />的外面包裹著keep-alive標(biāo)簽, 頁(yè)面數(shù)據(jù)都保留下來(lái)了,避免用戶(hù)切換路由,數(shù)據(jù)丟失的情況,看似很完美!
比如一個(gè)產(chǎn)品頁(yè)面:
當(dāng)兩個(gè)路由都使用同一個(gè)組件如Product.vue這個(gè)組件時(shí),來(lái)回切換兩個(gè)路由,兩個(gè)頁(yè)面填寫(xiě)的東西就會(huì)共用!切換頁(yè)面時(shí),發(fā)現(xiàn)頁(yè)面自動(dòng)填寫(xiě)了上個(gè)頁(yè)面的東西,這并不是我們想要的!
如果頁(yè)面比較少, 比如只有A、B兩個(gè)產(chǎn)品,可以每個(gè)頁(yè)面都定義一個(gè)路由地址,并且name屬性不一樣的值:
{ path: '/product', name: 'product', component: Product, children: [ { path: 'a', name: 'aProduct', component: Detail }, { path: 'b', name: 'bProduct', component: Detail }, ] }
這時(shí)這樣<router-view :key="$route.name"/>
就解決上面的問(wèn)題了
But,頁(yè)面較多的時(shí)候,定義路由就不能像上面這樣定義了:
{ path: '/product', name: 'product', component: Product, children: [ { path: 'detail/:id', name: 'aProduct', component: Detail }, ] }
此時(shí)路由變成了動(dòng)態(tài)的了,那么,key就不能取name的值了,此時(shí)就需要引入一個(gè)變量來(lái)存儲(chǔ)路由的歷史記錄了,當(dāng)路由切換時(shí),在歷史記錄中匹配相應(yīng)的路由,在歷史記錄中保存的一個(gè)位置值,取出來(lái)賦值個(gè)key就可以了
嗯,前面好像廢話(huà)有點(diǎn)多,而且貌似有騙標(biāo)題的嫌疑,其實(shí)理解key這個(gè)屬性,對(duì)于解決頁(yè)面緩存,組件重復(fù)不相互影響有重要的作用。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue中同時(shí)監(jiān)聽(tīng)多個(gè)參數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了vue中同時(shí)監(jiān)聽(tīng)多個(gè)參數(shù)的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04詳解如何在Vue3使用<script lang=“ts“ setup>語(yǔ)法糖
本文主要介紹了在Vue3使用<script lang=“ts“ setup>語(yǔ)法糖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06vue動(dòng)態(tài)設(shè)置頁(yè)面title的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于vue動(dòng)態(tài)設(shè)置頁(yè)面title的相關(guān)資料,文中通過(guò)實(shí)例代碼結(jié)束的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08Vue中iframe?結(jié)合?window.postMessage?實(shí)現(xiàn)跨域通信
window.postMessage()?方法可以安全地實(shí)現(xiàn)跨源通信,在一個(gè)項(xiàng)目的頁(yè)面中嵌入另一個(gè)項(xiàng)目的頁(yè)面,需要實(shí)現(xiàn)父子,子父頁(yè)面的通信,對(duì)Vue中iframe?結(jié)合?window.postMessage?實(shí)現(xiàn)跨域通信相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧2022-12-12