日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

2.vue的不更新特性-重用机制和key属性-data及其他字段-vue生命周期

發(fā)布時間:2023/12/10 vue 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2.vue的不更新特性-重用机制和key属性-data及其他字段-vue生命周期 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

vue基礎語法

1. 數(shù)據綁定的不更新特性

在數(shù)組中使用索引的方式修改了數(shù)組中的某一條數(shù)據時, 數(shù)組的長度沒有發(fā)生變化, 視圖不會自動更新

如果我們想讓視圖繼續(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++},// 這個時候 我們發(fā)現(xiàn)光點擊 change2 按鈕的時候 視圖是不會改變的!!!!!change2() {this.arr[0]++// 如何解決這個問題?// 方案一: 使用其他數(shù)據更新, 帶動數(shù)組更新// -----> 可以看到, 如果在我單擊change2視圖不更新后, 在點擊change1, 1中的視圖更新會帶動2中的視圖更新!// 方案二: 強制視圖更新:this.$forceUpdate()// 方案三: 使用set函數(shù)// 參一: 要更新的數(shù)組 參二: 要更新數(shù)組中哪一個的索引 參三: 新的值this.$set(this.arr, 0, this.arr[0]++)// 方案四: 更新數(shù)組的長度, 數(shù)組的長度如果發(fā)生了變化 vue視圖就會更新// push()、pop()、shift()、unshift()、splice()、sort()、reverse()可被vue監(jiān)測到。this.arr.unshift()} } 補充: 在初始化的時候, data中并沒有某個字段, 后期我們又添加了這個字段, 那么這個字段的修改就不會更新視圖

2. vue重用機制和屬性key

使用切換登錄方式案例
<button @click="login=!login">點擊切換登錄方式</button> // 使用 v-if // 原則上 v-if 是滿足條件時創(chuàng)建 不滿足銷毀<section v-if="login" id="section1">賬號: <input type="text" placeholder="請輸入賬號"><br>密碼: <input type="password" placeholder="請輸入密碼"></section><section v-else id="section2">手機號: <input type="text" placeholder="請輸入手機號"><br>驗證碼: <input type="text" placeholder="請輸入驗證碼"></section>data: {login: true,},// 場景: // 在我們給輸入框輸入內容之后, 點擊切換登錄方式, 發(fā)現(xiàn)雖然登錄方式改變了, 但是input中的內容還在! 說明輸入框沒有被銷毀// 為什么會這樣?// ----> vue的重用機制(懶惰機制)// 原理:// 在 v-if 切換標簽時, 如果將要銷毀的標簽和要創(chuàng)建的標簽時相同的標簽時, vue不會執(zhí)行創(chuàng)建和銷毀, 而是保留下來, 繼續(xù)使用.// 如何解決?----------------> // 解決方案一: 使用不同的標簽 保證 v-if 和 v-else 使用的不是同一個類型的標簽 <section v-if="login" id="section1"></section> <div v-else id="section2"></div>// 解決方案二: 給切換前后的屬性設置 key 值 // key的值不可以相同 <section v-if="login" id="section1" key="key1"></section> <section v-else id="section2" key="key2"></section>
如何避免重用機制?
  • 由于重用機制針對相同的標簽, 所以可以設置不同的標簽切換以避免重用機制

  • 重用機制只會對 key 值相同的標簽重用, key 不相同則不會重用, 默認 key 是相同標簽的 索引

  • 3. key屬性深入理解

    • 在 vue 中, key 是DOM對象的標識

    • 進行列表 v-for 展示時,默認key是index;

    • 如果數(shù)據只做展示使用,使用index作為key是沒有任何問題的;

    • 如果使用index作為key,而后續(xù)操作會破壞順序,一定會帶來效率問題,嚴重時會渲染出錯誤的DOM

    • key 被使用在虛擬 DOM 中, 不會出現(xiàn)在真實的 DOM 中

    如果把 index 索引 作為 key 的值

    列表內有輸入內容,后續(xù)操作破壞了原始順序,就會產生錯誤DOM

    為什么會產生錯誤的DOM對象?

    -------> 因為上一節(jié)的 【重用機制】 <------------

    • 看這個案例你就懂了!
    <button @click="add">添加一個老劉</button><ul><li v-for="(p,index) in persons" :key="index">{{p.name}}-{{p.age}}<input type="text"></li></ul>data:{persons:[{'id':'1', 'name':'張三','age':'18'},{'id':'2', 'name':'李四','age':'19'},{'id':'3', 'name':'王五','age':'20'}]},methods:{add(){const p = {'id':'4', 'name':'老劉','age':'40'}// 在前面添加this.persons.push(p)}}// 場景一: :key屬性的值為 ---> 索引 // 根據重用機制 如果標簽都相同的時候 key屬性的值默認為 標簽的索引 // 如果我們在標簽內輸入內容之后, 在點擊添加, 發(fā)現(xiàn)出現(xiàn)dom渲染出錯 // 在key生成虛擬dom的時候 會和舊的key進行比較 新生成的'老劉'DOM會對比舊的'張三'的DOM, 因為在渲染之前'張三'的key屬性為0,在虛擬DOM中, '老劉'的key屬性值為0; 在渲染新數(shù)據的時候, 會把'老劉'渲染到頁面上, 在渲染input的時候, 發(fā)現(xiàn)已經存在key===0的屬性,就不會在重新渲染! 直接會拿過來使用!!! ----> 所以出現(xiàn)了錯誤的真是DOM// 場景二: :key屬性設置為 ---> 數(shù)據中的唯一標識 id 因為 id 的值是唯一的, 所以在生成虛擬DOM的時候. key找不到相同的值 因為id都是唯一的啊 找不到怎么辦呢? ----> 很簡單, 重新渲染新的啊 ---> 這就是我們想要的效果
    • 總結

    推薦使用數(shù)據的唯一標識作為key,比如id,身份證號,手機號等等,通常這些數(shù)據由后端提供。

    后續(xù)操作不破壞原來數(shù)據順序的話,使用index作為key也沒有任何問題。

    4. 計算屬性

    4.1基本使用
    // 計算屬性定義在 computed 對象中// 使用計算屬性的時候 不需要加()<h2>{{ fullName }}</h2>data: {firstName: 'Lebron',lastName: 'James'},// computed 計算屬性computed: {fullName(){return this.firstName + ' ' + this.lastName}},
    4.2 完整的計算屬性
    // 續(xù)基本使用中的 data 和 h2 // 基本使用中的計算屬性, 實際上是一種簡寫 computed: {fullName: {set(newValue) {this.firstName = names[0];this.lastName = names[1];},get() {return this.firstName + ' ' + this.lastName}} }// 為什么計算屬性在使用的時候不需要加括號? 因為計算屬性中的方法中的內容都是寫在get中的, 在使用計算屬性的時候, 會調用里面的get// 什么時候使用 set 什么時候使用 get? 在我們更改值的時候, 才會走set. 使用set的時候必須要傳參數(shù)!!!
    4.3 計算屬性和methods的對比

    只要計算屬性中的值沒有變化 就會有一層緩存 多次使用的時候只會執(zhí)行一次 大大的提高了性能

    • 計算屬性寫在computed中, 自定義函數(shù)寫在methods中

    • 自定義函數(shù)需要使用函數(shù)調用結構 函數(shù)名 + () 調用; 計算屬性調用時, 當做data屬性調用 直接寫屬性名即可.

    • 自定義函數(shù)每次調用的時候, 都會執(zhí)行一次 浪費性能

    • 計算屬性 在計算一次之后 會把結構緩存起來, 下次調用直接從緩存中讀取結果 不在重新執(zhí)行計算 比較節(jié)省性能 提高效率 尤其使用計算量比較大的場景

    注意: 計算屬性不從新計算的前提是數(shù)據源不變, 當數(shù)據源發(fā)生變化, 計算屬性會重新計算

    5.監(jiān)聽器

    和data平級的字段 ---> watch 作用: ---> 用于監(jiān)視對應data中的字段(變量)數(shù)據的變化 注意: ---> 監(jiān)視器中依然是函數(shù)函數(shù)結構 但是函數(shù)名 ---> 是要監(jiān)視的字段名 舉例: data: {age: 1,obj: {age3: 2} }, computed: {age2() {return this.age*2} } watch: {// 參數(shù): 數(shù)據變化前后的新值 和 舊值age(newValue, oldValue) {console.log(1,newValue + "======" + oldvalue);},// 也可以監(jiān)視計算屬性內的函數(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ù)名 不能修改 是一個監(jiān)聽函數(shù) 只能獲取新值handler(newValue){console.log(4,newValue);},// 開啟深度監(jiān)聽deep: true},// 監(jiān)聽數(shù)組 數(shù)組通過索引更新數(shù)據 監(jiān)聽不到arr(newValue,oldvalue) {console.log(4,newValue + "======" + oldvalue);},arr:{// handler() 是固定的函數(shù)名 不能修改 是一個監(jiān)聽函數(shù) 只能獲取新值handler(newValue){console.log(6,newValue);},// 開啟深度監(jiān)聽deep: true}, }// 只有在被監(jiān)聽的數(shù)據發(fā)生變化時, 監(jiān)聽器才會被觸發(fā)

    總結:

  • 普通監(jiān)聽能監(jiān)聽到: data對象中的基本數(shù)據類型和計算屬性的更新

  • 深度監(jiān)聽能監(jiān)聽到: 普通監(jiān)聽 + 對象的更新 + 數(shù)組的增刪

  • 深度監(jiān)聽不能監(jiān)聽到的: 數(shù)組通過索引修改數(shù)據(這是特殊情況1), 對象在data初始化之后添加的字段(特殊情況2)

  • 6. VUE的生命周期函數(shù)

    生命周期: 一個vue對象從創(chuàng)建到銷毀的整個過程, 在這個過程中, vue會自動調用一些函數(shù), 這些函數(shù)叫做生命周期函數(shù).

    vue的生命周期分為四個過程 每個過程對應兩個函數(shù) 1: 創(chuàng)建過程 beforeCreate created 2: 渲染過程 beforeMount mounted 3: 更新過程 beforeUpdate updated 4: 銷毀過程 beforeDestory destoryed
    6.1 創(chuàng)建過程
    • 生命周期函數(shù)都與 data 平級
    beforCreate(){// 此時vue對象還未創(chuàng)建完成, this雖然有值, 但是data中的數(shù)據全部都是undefined, 無法調用. 所以不能在此操作視圖console.log(this) },created() {// 此時vue對象已經創(chuàng)建完成 可以操作vue中的數(shù)據 但是視圖還未渲染 不能操作視圖我們通常都是在這里面進行 ajax 請求, 因為在這里可以最早的拿到數(shù)據進行操作在拿到請求數(shù)據之后, 可以直接賦值給data中的某個值// 補充data中沒有 sex 這個數(shù)據, 但是我們在這里打點調用了. 雖然也可以渲染到視圖上, 但是由于沒有在data中定義, 所以不具備更新視圖的功能, 就算數(shù)據更新了, 視圖不會更新, 所以這樣一般是當做全局變量使用this.sex = '男' }
    6.2 渲染過程
    beforeMount() {// 在這里 vue中的的數(shù)據還沒有渲染到視圖上, 不建議在這里面操作視圖 }, mounted() {// 這時候 視圖已經渲染完成 可以在這里操作視圖 BOM和DOM相關操作寫在這里面// 舉個例子把// 查找標簽 獲取一個按鈕 this.btn 當全局變量使用 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ù)據將要更新 但是還未更新// 我們可以在這里添加判斷 來阻止更新// 比如我們不想讓data中的數(shù)據大于18if(this.age > 18) {this.age = 18} }, updated() {// 在這里數(shù)據已經更新完畢 可以獲取更新后的值 }
    6.4 銷毀過程
    beforeDestroy() {// 此時vue對象將要銷毀 我們在這里面把無用的計時器 和 綁定的事件等銷毀了 釋放性能 }, destroyed() {// vue對象已經銷毀 我們在這里把vue變量置空 清理內存vm = null }

    總結

    以上是生活随笔為你收集整理的2.vue的不更新特性-重用机制和key属性-data及其他字段-vue生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。