国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Vue的computed和watch的細(xì)節(jié)全面分析

CoderDock / 2181人閱讀

摘要:定義是一個(gè)計(jì)算屬性類似于過濾器對(duì)綁定到的數(shù)據(jù)進(jìn)行處理用法不可在里面定義如果定義會(huì)報(bào)如下圖片的錯(cuò)誤因?yàn)閷?duì)應(yīng)的作為計(jì)算屬性定義并返回對(duì)應(yīng)的結(jié)果給這個(gè)變量變量不可被重復(fù)定義和賦值和用法回調(diào)函數(shù)當(dāng)需要讀取當(dāng)前屬性值是執(zhí)行,根據(jù)相關(guān)數(shù)據(jù)計(jì)算并返回當(dāng)前

1.computed 1.1 定義

是一個(gè)計(jì)算屬性,類似于過濾器,對(duì)綁定到view的數(shù)據(jù)進(jìn)行處理

1.2 get用法
  data: {
    firstName: "Foo",
    lastName: "Bar"
  },
  computed: {
    fullName: function () {
      return this.firstName + " " + this.lastName
    }
  }

fullName不可在data里面定義,
如果定義會(huì)報(bào)如下圖片的錯(cuò)誤,因?yàn)閷?duì)應(yīng)的computed作為計(jì)算屬性定義fullName并返回對(duì)應(yīng)的結(jié)果給這個(gè)變量,變量不可被重復(fù)定義和賦值

1.3 get和set用法
data: {
    firstName: "Foo",
    lastName: "Bar"
  },
  computed: {
  fullName:{
   get(){//回調(diào)函數(shù) 當(dāng)需要讀取當(dāng)前屬性值是執(zhí)行,根據(jù)相關(guān)數(shù)據(jù)計(jì)算并返回當(dāng)前屬性的值
      return this.firstName + " " + this.lastName
    },
   set(val){//監(jiān)視當(dāng)前屬性值的變化,當(dāng)屬性值發(fā)生變化時(shí)執(zhí)行,更新相關(guān)的屬性數(shù)據(jù)
       //val就是fullName的最新屬性值
       console.log(val)
        const names = val.split(" ");
        console.log(names)
        this.firstName = names[0];
        this.lastName = names[1];
   }
   }
  }
2. watch 2.1 定義

watch是一個(gè)觀察的動(dòng)作

2.2 示例
  data: {
    firstName: "Foo",
    lastName: "Bar",
    fullName: "Foo Bar"
  },
  watch: {
     firstName: function (val) {
     this.fullName = val + " " + this.lastName
  },
  lastName: function (val) {
     this.fullName = this.firstName + " " + val
   }
   }

上面是監(jiān)聽firstName和lastName的變化,但是僅限簡(jiǎn)單數(shù)據(jù)類型

2.2 監(jiān)聽簡(jiǎn)單數(shù)據(jù)類型
data(){
      return{
        "first":2
      }
    },
    watch:{
      first(){
        console.log(this.first)
      }
    },
2.3 監(jiān)聽復(fù)雜數(shù)據(jù)類型

1.監(jiān)聽復(fù)雜數(shù)據(jù)類型需用深度監(jiān)聽

data(){
      return{
        "first":{
          second:0
        }
      }
    },
    watch:{
      secondChange:{
        handler(oldVal,newVal){
          console.log(oldVal)
          console.log(newVal)
        },
        deep:true
      }
    },

2.console.log打印的結(jié)果,發(fā)現(xiàn)oldVal和newVal值是一樣的,所以深度監(jiān)聽雖然可以監(jiān)聽到對(duì)象的變化,但是無法監(jiān)聽到具體對(duì)象里面那個(gè)屬性的變化

3.oldVal和newVal值一樣的原因是它們索引同一個(gè)對(duì)象/數(shù)組。Vue 不會(huì)保留修改之前值的副本
vm.$watch的深度監(jiān)聽

4.深度監(jiān)聽對(duì)應(yīng)的函數(shù)名必須為handler,否則無效果,因?yàn)閣atcher里面對(duì)應(yīng)的是對(duì)handler的調(diào)用

2.4 監(jiān)聽對(duì)象單個(gè)屬性
方法一:可以直接對(duì)用對(duì)象.屬性的方法拿到屬性
data(){
          return{
            "first":{
              second:0
            }
          }
        },
        watch:{
          first.second:function(newVal,oldVal){
            console.log(newVal,oldVal);
          }
        },
    

方法二:watch如果想要監(jiān)聽對(duì)象的單個(gè)屬性的變化,必須用computed作為中間件轉(zhuǎn)化,因?yàn)閏omputed可以取到對(duì)應(yīng)的屬性值

data(){
      return{
        "first":{
          second:0
        }
      }
    },
    computed:{
      secondChange(){
        return this.first.second
      }
    },
    watch:{
      secondChange(){
        console.log("second屬性值變化了")
      }
    },
3 computed和watch的區(qū)別 3.1 computed特性

1.是計(jì)算值,
2.應(yīng)用:就是簡(jiǎn)化tempalte里面{{}}計(jì)算和處理props或$emit的傳值
3.具有緩存性,頁面重新渲染值不變化,計(jì)算屬性會(huì)立即返回之前的計(jì)算結(jié)果,而不必再次執(zhí)行函數(shù)

3.2 watch特性

1.是觀察的動(dòng)作,
2.應(yīng)用:監(jiān)聽props,$emit或本組件的值執(zhí)行異步操作
3.無緩存性,頁面重新渲染時(shí)值不變化也會(huì)執(zhí)行

3 props傳值 3.1 常見錯(cuò)誤1

傳入的值想作為局部變量來使用,直接使用會(huì)

props:["listShop"],
    data(){
      return{}
    },
    created(){
      this.listShop=30
}

報(bào)錯(cuò)

這個(gè)錯(cuò)誤是說的避免直接修改父組件傳入的值,因?yàn)闀?huì)改變父組件的值,貼上官網(wǎng)介紹

3.2 解決方案1

簡(jiǎn)單數(shù)據(jù)類型解決方案:
所以可以在data中重新定義一個(gè)變量,改變指向,但是也只是針對(duì)簡(jiǎn)單數(shù)據(jù)類型,因?yàn)閺?fù)雜數(shù)據(jù)類型棧存貯的是指針,

props:["listShop"],
    data(){
      return{
        listShopChild:this.listShop
      }
    },
    created(){
      this.listShopChild=30
    }
    

這樣就可以愉快的更改傳入的簡(jiǎn)單數(shù)據(jù)類型的數(shù)據(jù)啦!不會(huì)有任何報(bào)錯(cuò),也不會(huì)影響父組件!

3.4 存在的問題

復(fù)雜數(shù)據(jù)類型在棧中存貯的是指針,所以賦值給新的變量也會(huì)改變?cè)嫉淖兞恐?那么應(yīng)該咋整呢?
1.可以手動(dòng)深度克隆一個(gè)復(fù)雜的數(shù)據(jù)出來,循環(huán)或者遞歸都行

數(shù)組深度克隆:

var x = [1,2,3];
var y = [];
for (var i = 0; i < x.length; i++) {
    y[i]=x[i];
}
console.log(y);  //[1,2,3]
y.push(4);
console.log(y);  //[1,2,3,4]
console.log(x);  //[1,2,3]

對(duì)象深度克隆:

var x = {a:1,b:2};
var y = {};
for(var i in x){
    y[i] = x[i];
}
console.log(y);  //Object {a: 1, b: 2}
y.c = 3;
console.log(y);  //Object {a: 1, b: 2, c: 3}
console.log(x);  //Object {a: 1, b: 2}

函數(shù)深度克隆

var x = function(){console.log(1);};
var y = x;
y = function(){console.log(2);};
x();  //1
y();  //2

為什么函數(shù)可以直接賦值克隆?
由于函數(shù)對(duì)象克隆之后的對(duì)象會(huì)多帶帶復(fù)制一次并存儲(chǔ)實(shí)際數(shù)據(jù),因此并不會(huì)影響克隆之前的對(duì)象。所以采用簡(jiǎn)單的復(fù)制“=”即可完成克隆。

2.Object.assign
只會(huì)對(duì)只是一級(jí)屬性復(fù)制,比淺拷貝多深拷貝了一層而已,所以還是無法達(dá)到深度克隆的目的.
詳請(qǐng)請(qǐng)戳

3.強(qiáng)大的JSON.stringify和JSON.parse

const obj1 = JSON.parse(JSON.stringify(obj));

這是ES5新出來的API,先將對(duì)象轉(zhuǎn)化為字符串,就是簡(jiǎn)單數(shù)據(jù)類型賦值,再用JSON.parse轉(zhuǎn)化

3.5 解決方案2

直接用computed改變

computed:{
  listShopChild(){
    return this.listShop
   }
}
3.5 存在的問題

注意:此時(shí)用computed時(shí),如果是數(shù)組this.$set(arr,1,true)對(duì)應(yīng)的值耶不更新
這個(gè)很坑,這個(gè)bug我找個(gè)很久
如果傳入的值只是在data定義,并未在methods或生命周期鉤子更改,直接改變也會(huì)報(bào)錯(cuò)
所以還是可以先用局部變量接收,再修改,這個(gè)坑比較多

4 應(yīng)用 4.1 應(yīng)用1

監(jiān)聽本組件計(jì)算和監(jiān)聽

4.2 應(yīng)用2

計(jì)算或監(jiān)聽父?jìng)髯拥膒rops值

4.3 應(yīng)用3

分為簡(jiǎn)單數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型監(jiān)聽,監(jiān)聽方法如上watch的使用

4.4 應(yīng)用4

監(jiān)聽vuex的state或者getters值的變化

computed:{
    stateDemo(){
        return this.$store.state.demoState;
    }
}
watch:{
    stateDemo(){
        console.log("vuex變化啦")
    }
}
5. computed和watch的原理分析

很開心小伙伴們能看到這里,接下來給大家簡(jiǎn)單羅列下他們的原理!

5.1 computed的原理

深入理解 Vue Computed 計(jì)算屬性

5.2 watch的原理

分為三個(gè)過程:實(shí)例化Vue、調(diào)用$watch方法、屬性變化,觸發(fā)回調(diào)
Vue的數(shù)據(jù)依賴實(shí)現(xiàn)原理簡(jiǎn)析
vue中$watch源碼閱讀筆記

6 簡(jiǎn)單實(shí)現(xiàn)computed和watch

公共類

function defineReactive(data, key, val, fn) {
      let subs = [] // 新增
      Object.defineProperty(data, key, {
        configurable: true,
        enumerable: true,
        get: function() {
          // 新增
       if (data.$target) {
        subs.push(data.$target)
      }
      return val
     },
     set: function(newVal) {
      if (newVal === val) return
      fn && fn(newVal)
      // 新增
      if (subs.length) {
        // 用 setTimeout 因?yàn)榇藭r(shí) this.data 還沒更新
        setTimeout(() => {
          subs.forEach(sub => sub())
        }, 0)
      }
      val = newVal
    },
   })
 }
6.1 computed實(shí)現(xiàn)
function computed(ctx, obj) {
  let keys = Object.keys(obj)
  let dataKeys = Object.keys(ctx.data)
  dataKeys.forEach(dataKey => {
    defineReactive(ctx.data, dataKey, ctx.data[dataKey])
  })
  let firstComputedObj = keys.reduce((prev, next) => {
    ctx.data.$target = function() {
      ctx.setData({ [next]: obj[next].call(ctx) })
    }
    prev[next] = obj[next].call(ctx)
    ctx.data.$target = null
    return prev
  }, {})
  ctx.setData(firstComputedObj)
}
6.1 watch實(shí)現(xiàn)
function watch(ctx, obj) {
  Object.keys(obj).forEach(key => {
    defineReactive(ctx.data, key, ctx.data[key], function(value) {
      obj[key].call(ctx, value)
    })
  })
}

https://segmentfault.com/a/11...
大家如果發(fā)現(xiàn)有什么錯(cuò)誤,歡迎指正,共同交流。如果覺得篇文章真的對(duì)你有點(diǎn)作用。
謝謝親們能看完!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/92688.html

相關(guān)文章

  • Vuecomputedwatch細(xì)節(jié)全面分析

    摘要:定義是一個(gè)計(jì)算屬性類似于過濾器對(duì)綁定到的數(shù)據(jù)進(jìn)行處理用法不可在里面定義如果定義會(huì)報(bào)如下圖片的錯(cuò)誤因?yàn)閷?duì)應(yīng)的作為計(jì)算屬性定義并返回對(duì)應(yīng)的結(jié)果給這個(gè)變量變量不可被重復(fù)定義和賦值和用法回調(diào)函數(shù)當(dāng)需要讀取當(dāng)前屬性值是執(zhí)行,根據(jù)相關(guān)數(shù)據(jù)計(jì)算并返回當(dāng)前 1.computed 1.1 定義 是一個(gè)計(jì)算屬性,類似于過濾器,對(duì)綁定到view的數(shù)據(jù)進(jìn)行處理 1.2 get用法 data: { ...

    lastSeries 評(píng)論0 收藏0
  • 做面試不倒翁:淺談 Vuecomputed 實(shí)現(xiàn)原理

    摘要:當(dāng)某個(gè)屬性發(fā)生變化,觸發(fā)攔截函數(shù),然后調(diào)用自身消息訂閱器的方法,遍歷當(dāng)前中保存著所有訂閱者的數(shù)組,并逐個(gè)調(diào)用的方法,完成響應(yīng)更新。 編者按:我們會(huì)不時(shí)邀請(qǐng)工程師談?wù)動(dòng)幸馑嫉募夹g(shù)細(xì)節(jié),希望知其所以然能讓大家在面試有更出色表現(xiàn)。也給面試官提供更多思路。 showImg(https://segmentfault.com/img/bVbgYyU?w=1200&h=600); 雖然目前的技術(shù)...

    Anonymous1 評(píng)論0 收藏0
  • vue源碼-對(duì)于「計(jì)算屬性」理解

    摘要:源碼對(duì)于計(jì)算屬性的理解這是我最近學(xué)習(xí)源碼的一個(gè)個(gè)人總結(jié)和理解,所以可能并不適合每一位讀者本文的整體脈絡(luò)如下,首先盡可能去掉細(xì)節(jié),對(duì)計(jì)算屬性源碼的大致實(shí)現(xiàn)有一個(gè)了解,然后舉一例子,分別談?wù)動(dòng)?jì)算屬性依賴收集和派發(fā)更新的流程。 vue源碼-對(duì)于「計(jì)算屬性」的理解 這是我最近學(xué)習(xí)vue源碼的一個(gè)個(gè)人總結(jié)和理解,所以可能并不適合每一位讀者 本文的整體脈絡(luò)如下,首先盡可能去掉細(xì)節(jié),對(duì)計(jì)算屬性源碼的...

    xiaochao 評(píng)論0 收藏0
  • vue組件通信全面總結(jié)

    摘要:當(dāng)一個(gè)組件沒有聲明任何時(shí),這里會(huì)包含所有父作用域的綁定和除外,并且可以通過傳入內(nèi)部組件在創(chuàng)建高級(jí)別的組件時(shí)非常有用。 寫在前面 組件間的通信是是實(shí)際開發(fā)中非常常用的一環(huán),如何使用對(duì)項(xiàng)目整體設(shè)計(jì)、開發(fā)、規(guī)范都有很實(shí)際的的作用,我在項(xiàng)目開發(fā)中對(duì)此深有體會(huì),總結(jié)下vue組件間通信的幾種方式,討論下各自的使用場(chǎng)景 文章對(duì)相關(guān)場(chǎng)景預(yù)覽 父->子組件間的數(shù)據(jù)傳遞 子->父組件間的數(shù)據(jù)傳遞 兄弟...

    余學(xué)文 評(píng)論0 收藏0
  • 前端知識(shí)點(diǎn)整理(待續(xù))

    摘要:知識(shí)點(diǎn)閉包問題執(zhí)行機(jī)制定時(shí)器線程理解構(gòu)造函數(shù)內(nèi)的方法與構(gòu)造函數(shù)屬性上方法的對(duì)比中都經(jīng)歷了什么深入理解中的屬性和特性中的方法詳解為什么編程語言的都要定義數(shù)據(jù)類型中與的區(qū)別輕松理解基本包裝對(duì)象中數(shù)據(jù)類型內(nèi)置對(duì)象包裝類型對(duì)象關(guān)系基礎(chǔ)之?dāng)?shù)組中的邏輯 JS知識(shí)點(diǎn) JS hoist JS閉包問題 JS執(zhí)行機(jī)制 JS定時(shí)器線程理解 構(gòu)造函數(shù)內(nèi)的方法與構(gòu)造函數(shù)prototype屬性上方法的對(duì)比 JS...

    silencezwm 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<