2.vue的不更新特性-重用机制和key属性-data及其他字段-vue生命周期
vue基礎(chǔ)語法
1. 數(shù)據(jù)綁定的不更新特性
在數(shù)組中使用索引的方式修改了數(shù)組中的某一條數(shù)據(jù)時(shí), 數(shù)組的長度沒有發(fā)生變化, 視圖不會(huì)自動(dòng)更新
如果我們想讓視圖繼續(xù)更新該怎么辦?
<div id='app'><h1>{{ count }}</h1><button @click="change1">+</button><h1>{{ arr[0] }}</h1><button @click="change2">+</button> </div>data: {count: 1,arr: [66] },methods: {change1() {this.count++},// 這個(gè)時(shí)候 我們發(fā)現(xiàn)光點(diǎn)擊 change2 按鈕的時(shí)候 視圖是不會(huì)改變的!!!!!change2() {this.arr[0]++// 如何解決這個(gè)問題?// 方案一: 使用其他數(shù)據(jù)更新, 帶動(dòng)數(shù)組更新// -----> 可以看到, 如果在我單擊change2視圖不更新后, 在點(diǎn)擊change1, 1中的視圖更新會(huì)帶動(dòng)2中的視圖更新!// 方案二: 強(qiáng)制視圖更新:this.$forceUpdate()// 方案三: 使用set函數(shù)// 參一: 要更新的數(shù)組 參二: 要更新數(shù)組中哪一個(gè)的索引 參三: 新的值this.$set(this.arr, 0, this.arr[0]++)// 方案四: 更新數(shù)組的長度, 數(shù)組的長度如果發(fā)生了變化 vue視圖就會(huì)更新// push()、pop()、shift()、unshift()、splice()、sort()、reverse()可被vue監(jiān)測到。this.arr.unshift()} } 補(bǔ)充: 在初始化的時(shí)候, data中并沒有某個(gè)字段, 后期我們又添加了這個(gè)字段, 那么這個(gè)字段的修改就不會(huì)更新視圖2. vue重用機(jī)制和屬性key
使用切換登錄方式案例
<button @click="login=!login">點(diǎn)擊切換登錄方式</button> // 使用 v-if // 原則上 v-if 是滿足條件時(shí)創(chuàng)建 不滿足銷毀<section v-if="login" id="section1">賬號(hào): <input type="text" placeholder="請輸入賬號(hào)"><br>密碼: <input type="password" placeholder="請輸入密碼"></section><section v-else id="section2">手機(jī)號(hào): <input type="text" placeholder="請輸入手機(jī)號(hào)"><br>驗(yàn)證碼: <input type="text" placeholder="請輸入驗(yàn)證碼"></section>data: {login: true,},// 場景: // 在我們給輸入框輸入內(nèi)容之后, 點(diǎn)擊切換登錄方式, 發(fā)現(xiàn)雖然登錄方式改變了, 但是input中的內(nèi)容還在! 說明輸入框沒有被銷毀// 為什么會(huì)這樣?// ----> vue的重用機(jī)制(懶惰機(jī)制)// 原理:// 在 v-if 切換標(biāo)簽時(shí), 如果將要銷毀的標(biāo)簽和要?jiǎng)?chuàng)建的標(biāo)簽時(shí)相同的標(biāo)簽時(shí), vue不會(huì)執(zhí)行創(chuàng)建和銷毀, 而是保留下來, 繼續(xù)使用.// 如何解決?----------------> // 解決方案一: 使用不同的標(biāo)簽 保證 v-if 和 v-else 使用的不是同一個(gè)類型的標(biāo)簽 <section v-if="login" id="section1"></section> <div v-else id="section2"></div>// 解決方案二: 給切換前后的屬性設(shè)置 key 值 // key的值不可以相同 <section v-if="login" id="section1" key="key1"></section> <section v-else id="section2" key="key2"></section>如何避免重用機(jī)制?
由于重用機(jī)制針對相同的標(biāo)簽, 所以可以設(shè)置不同的標(biāo)簽切換以避免重用機(jī)制
重用機(jī)制只會(huì)對 key 值相同的標(biāo)簽重用, key 不相同則不會(huì)重用, 默認(rèn) key 是相同標(biāo)簽的 索引
3. key屬性深入理解
-
在 vue 中, key 是DOM對象的標(biāo)識(shí)
-
進(jìn)行列表 v-for 展示時(shí),默認(rèn)key是index;
-
如果數(shù)據(jù)只做展示使用,使用index作為key是沒有任何問題的;
-
如果使用index作為key,而后續(xù)操作會(huì)破壞順序,一定會(huì)帶來效率問題,嚴(yán)重時(shí)會(huì)渲染出錯(cuò)誤的DOM
-
key 被使用在虛擬 DOM 中, 不會(huì)出現(xiàn)在真實(shí)的 DOM 中
如果把 index 索引 作為 key 的值
列表內(nèi)有輸入內(nèi)容,后續(xù)操作破壞了原始順序,就會(huì)產(chǎn)生錯(cuò)誤DOM
為什么會(huì)產(chǎn)生錯(cuò)誤的DOM對象?
-------> 因?yàn)樯弦还?jié)的 【重用機(jī)制】 <------------
- 看這個(gè)案例你就懂了!
- 總結(jié)
推薦使用數(shù)據(jù)的唯一標(biāo)識(shí)作為key,比如id,身份證號(hào),手機(jī)號(hào)等等,通常這些數(shù)據(jù)由后端提供。
后續(xù)操作不破壞原來數(shù)據(jù)順序的話,使用index作為key也沒有任何問題。
4. 計(jì)算屬性
4.1基本使用
// 計(jì)算屬性定義在 computed 對象中// 使用計(jì)算屬性的時(shí)候 不需要加()<h2>{{ fullName }}</h2>data: {firstName: 'Lebron',lastName: 'James'},// computed 計(jì)算屬性computed: {fullName(){return this.firstName + ' ' + this.lastName}},4.2 完整的計(jì)算屬性
// 續(xù)基本使用中的 data 和 h2 // 基本使用中的計(jì)算屬性, 實(shí)際上是一種簡寫 computed: {fullName: {set(newValue) {this.firstName = names[0];this.lastName = names[1];},get() {return this.firstName + ' ' + this.lastName}} }// 為什么計(jì)算屬性在使用的時(shí)候不需要加括號(hào)? 因?yàn)橛?jì)算屬性中的方法中的內(nèi)容都是寫在get中的, 在使用計(jì)算屬性的時(shí)候, 會(huì)調(diào)用里面的get// 什么時(shí)候使用 set 什么時(shí)候使用 get? 在我們更改值的時(shí)候, 才會(huì)走set. 使用set的時(shí)候必須要傳參數(shù)!!!4.3 計(jì)算屬性和methods的對比
只要計(jì)算屬性中的值沒有變化 就會(huì)有一層緩存 多次使用的時(shí)候只會(huì)執(zhí)行一次 大大的提高了性能
-
計(jì)算屬性寫在computed中, 自定義函數(shù)寫在methods中
-
自定義函數(shù)需要使用函數(shù)調(diào)用結(jié)構(gòu) 函數(shù)名 + () 調(diào)用; 計(jì)算屬性調(diào)用時(shí), 當(dāng)做data屬性調(diào)用 直接寫屬性名即可.
-
自定義函數(shù)每次調(diào)用的時(shí)候, 都會(huì)執(zhí)行一次 浪費(fèi)性能
-
計(jì)算屬性 在計(jì)算一次之后 會(huì)把結(jié)構(gòu)緩存起來, 下次調(diào)用直接從緩存中讀取結(jié)果 不在重新執(zhí)行計(jì)算 比較節(jié)省性能 提高效率 尤其使用計(jì)算量比較大的場景
注意: 計(jì)算屬性不從新計(jì)算的前提是數(shù)據(jù)源不變, 當(dāng)數(shù)據(jù)源發(fā)生變化, 計(jì)算屬性會(huì)重新計(jì)算
5.監(jiān)聽器
和data平級(jí)的字段 ---> watch 作用: ---> 用于監(jiān)視對應(yīng)data中的字段(變量)數(shù)據(jù)的變化 注意: ---> 監(jiān)視器中依然是函數(shù)函數(shù)結(jié)構(gòu) 但是函數(shù)名 ---> 是要監(jiān)視的字段名 舉例: data: {age: 1,obj: {age3: 2} }, computed: {age2() {return this.age*2} } watch: {// 參數(shù): 數(shù)據(jù)變化前后的新值 和 舊值age(newValue, oldValue) {console.log(1,newValue + "======" + oldvalue);},// 也可以監(jiān)視計(jì)算屬性內(nèi)的函數(shù)age2(newValue, oldValue) {console.log(2,newValue + "======" + oldvalue);},// 監(jiān)聽對象, 對象的屬性增刪改都監(jiān)聽不到obj(newValue,oldvalue) {console.log(3,newValue + "======" + oldvalue);},// 深度監(jiān)聽: obj:{// handler() 是固定的函數(shù)名 不能修改 是一個(gè)監(jiān)聽函數(shù) 只能獲取新值handler(newValue){console.log(4,newValue);},// 開啟深度監(jiān)聽deep: true},// 監(jiān)聽數(shù)組 數(shù)組通過索引更新數(shù)據(jù) 監(jiān)聽不到arr(newValue,oldvalue) {console.log(4,newValue + "======" + oldvalue);},arr:{// handler() 是固定的函數(shù)名 不能修改 是一個(gè)監(jiān)聽函數(shù) 只能獲取新值handler(newValue){console.log(6,newValue);},// 開啟深度監(jiān)聽deep: true}, }// 只有在被監(jiān)聽的數(shù)據(jù)發(fā)生變化時(shí), 監(jiān)聽器才會(huì)被觸發(fā)總結(jié):
普通監(jiān)聽能監(jiān)聽到: data對象中的基本數(shù)據(jù)類型和計(jì)算屬性的更新
深度監(jiān)聽能監(jiān)聽到: 普通監(jiān)聽 + 對象的更新 + 數(shù)組的增刪
深度監(jiān)聽不能監(jiān)聽到的: 數(shù)組通過索引修改數(shù)據(jù)(這是特殊情況1), 對象在data初始化之后添加的字段(特殊情況2)
6. VUE的生命周期函數(shù)
生命周期: 一個(gè)vue對象從創(chuàng)建到銷毀的整個(gè)過程, 在這個(gè)過程中, vue會(huì)自動(dòng)調(diào)用一些函數(shù), 這些函數(shù)叫做生命周期函數(shù).
vue的生命周期分為四個(gè)過程 每個(gè)過程對應(yīng)兩個(gè)函數(shù) 1: 創(chuàng)建過程 beforeCreate created 2: 渲染過程 beforeMount mounted 3: 更新過程 beforeUpdate updated 4: 銷毀過程 beforeDestory destoryed6.1 創(chuàng)建過程
- 生命周期函數(shù)都與 data 平級(jí)
6.2 渲染過程
beforeMount() {// 在這里 vue中的的數(shù)據(jù)還沒有渲染到視圖上, 不建議在這里面操作視圖 }, mounted() {// 這時(shí)候 視圖已經(jīng)渲染完成 可以在這里操作視圖 BOM和DOM相關(guān)操作寫在這里面// 舉個(gè)例子把// 查找標(biāo)簽 獲取一個(gè)按鈕 this.btn 當(dāng)全局變量使用 this.btn = document.getElementsByTagName("button")[0];// 綁定事件 最好把綁定事件的函數(shù)寫在外面(寫在methods中) 這樣就比較好操作銷毀this.btn.addEventListener("mouseenter",this.btnHandle); },methods: { // 自定義函數(shù)// 綁定事件的函數(shù)放在這里面btnHandle(){console.log(this); // vuethis.btn.style.backgroundColor = 'red'}},6.3 更新過程
beforeUpdate() {// vue的數(shù)據(jù)將要更新 但是還未更新// 我們可以在這里添加判斷 來阻止更新// 比如我們不想讓data中的數(shù)據(jù)大于18if(this.age > 18) {this.age = 18} }, updated() {// 在這里數(shù)據(jù)已經(jīng)更新完畢 可以獲取更新后的值 }6.4 銷毀過程
beforeDestroy() {// 此時(shí)vue對象將要銷毀 我們在這里面把無用的計(jì)時(shí)器 和 綁定的事件等銷毀了 釋放性能 }, destroyed() {// vue對象已經(jīng)銷毀 我們在這里把vue變量置空 清理內(nèi)存vm = null }總結(jié)
以上是生活随笔為你收集整理的2.vue的不更新特性-重用机制和key属性-data及其他字段-vue生命周期的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(1962)vue之电商管理系统
- 下一篇: 前端学习(1703):前端系列javas