最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue父子組件傳值的一些坑

 更新時(shí)間:2020年09月16日 11:40:38   作者:文淵  
這篇文章主要介紹了Vue父子組件傳值的一些坑,幫助大家更好的理解和使用vue父子組件,感興趣的朋友可以了解下

在用 Vue 的父子組件傳值時(shí)遇到一個(gè)冷門的問題,子組件改變值后父組件的值也隨之改變了,特此記錄下原因和解決方式。
再系統(tǒng)梳理下 JavaScript 的深拷貝與淺拷貝相關(guān)知識點(diǎn)。

1. 問題描述

父組件傳值給子組件,子組件改變傳過來的值后,父組件的值也會(huì)跟著改變。
這個(gè)問題比較冷門,平時(shí)如果對組件通信使用得比較簡單,一般不會(huì)遇到。

2. 原因剖析

  • 核心:雙向綁定

父子組件傳值的時(shí)候涉及雙向綁定,當(dāng)傳值為 object 類型時(shí),傳值之后數(shù)據(jù)源會(huì)被改變。

  • 深拷貝與淺拷貝

下文詳細(xì)講。

3. 解決方案

我目前采用的解決辦法是:
傳值的時(shí)候不要直接傳數(shù)據(jù)源,而是通過拷貝或者定義新變量等方式傳值。

簡單處理就 JSON.parse(JSON.stringify(obj)),但是這種簡單粗暴的方法有其局限性。當(dāng)值為 undefined、function、symbol 會(huì)在轉(zhuǎn)換過程中被忽略。所以,對象值有這三種的話用這種方法會(huì)導(dǎo)致屬性丟失。

剩下的就是自寫深拷貝的工具函數(shù),或者直接借助第三方的庫函數(shù),下面展開講。

4. 深拷貝和淺拷貝

JavaScript中的淺拷貝與深拷貝,只是針對復(fù)雜數(shù)據(jù)類型(Object,Array)的復(fù)制問題。淺拷貝與深拷貝都可以實(shí)現(xiàn)在已有對象上再生出一份的作用。但是對象的實(shí)例是存儲(chǔ)在堆內(nèi)存中然后通過一個(gè)引用值去操作對象,由此拷貝的時(shí)候就存在兩種情況了:拷貝引用和拷貝實(shí)例,這也是淺拷貝和深拷貝的區(qū)別。

下圖為JavaScript復(fù)雜數(shù)據(jù)類型的淺拷貝示意圖:

  • 淺拷貝

淺拷貝是拷貝引用,拷貝后的引用都是指向同一個(gè)對象的實(shí)例,彼此之間的操作會(huì)互相影響。

值得注意的是:Object.assgin() 是淺拷貝,它只能深拷貝第一層,深層的還是淺拷貝。因?yàn)?Object.assign() 拷貝的是屬性值。假如源對象的屬性值是一個(gè)對象的引用,那么它也只指向那個(gè)引用。(摘選自MDN)

MDN講述 assign 的時(shí)候,就有一個(gè)典型的例子,這里是文章鏈接。

下面列舉第一類淺拷貝 - 拷貝原對象的引用:

/**
 * 對象的淺拷貝
 */
var obj1 = {
 name:'wenyuan',
 age: 22
}
var obj2 = obj1;
obj2['job'] = 'coder';
console.log(obj1); //Object {name: "wenyuan", age: 22, job: "coder"}
console.log(obj2); //Object {name: "wenyuan", age: 0, job: "coder"}


/* ------------------------- 華麗的分割線 ------------------------- */


/**
 * 數(shù)組的淺拷貝
 */
var arr1 = [1, 2, 3, '4'];
var arr2 = arr1;
arr2[1] = "test"; 
console.log(arr1); // [1, "test", 3, "4"]
console.log(arr2); // [1, "test", 3, "4"]

接下來看第二類淺拷貝 - 源對象拷貝實(shí)例,其屬性對象拷貝引用:

這種情況,外層源對象是拷貝實(shí)例,如果其屬性元素為復(fù)雜數(shù)據(jù)類型(Object、Array)時(shí),內(nèi)層元素拷貝引用。

對源對象直接操作,不影響另外一個(gè)對象,但是對其屬性操作時(shí)候,會(huì)改變另外一個(gè)對象的屬性的值。

/**
 * 對象的淺拷貝
 * jQuery的 $.extend(a,b) 或 $.extend({},a,b)
 */
var obj1 = {
 name:'wenyuan',
 age: 22,
 social: {
  blog: 'www.wenyuanblog.com'
 },
 skills: ['js', 'html', 'css', 'python']
}
var obj2 = $.extend({},obj1);
console.log(obj1 === obj2) // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(obj1.social === obj2.social) // 輸出true,說明對于Object類型的屬性是拷貝引用
console.log(obj1.skills === obj2.skills) // 輸出true,說明對于Array類型的屬性是拷貝引用


/**
 * 對象的淺拷貝
 * ES6的 Object.assign() 和 對象擴(kuò)展運(yùn)算符...
 */
var obj1 = {
 name:'wenyuan',
 age: 22,
 social: {
  blog: 'www.wenyuanblog.com'
 },
 skills: ['js', 'html', 'css', 'python']
}
var obj2 = Object.assign({},obj1);
console.log(obj1 === obj2) // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(obj1.social === obj2.social) // 輸出true,說明對于Object類型的屬性是拷貝引用
console.log(obj1.skills === obj2.skills) // 輸出true,說明對于Array類型的屬性是拷貝引用
var obj3 = {...obj1};
console.log(obj1 === obj3) // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(obj1.skills === obj3.skills) // 輸出true,說明對于Array類型的屬性是拷貝引用
console.log(obj1.skills === obj3.skills) // 輸出true,說明對于Array類型的屬性是拷貝引用


/* ------------------------- 華麗的分割線 ------------------------- */


/**
 * 數(shù)組的淺拷貝
 * Array.prototype.slice()
 */
var arr1 = [{name: "wenyuan"}, {name: "Evan You"}];
var arr2 = arr1.slice(0);
console.log(arr1 === arr2); // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(arr1[0] === arr2[0]); // 輸出true,說明其元素拷貝的是引用


/**
 * 數(shù)組的淺拷貝
 * Array.prototype.concat()
 */
var arr1 = [{name: "wenyuan"}, {name: "Evan You"}];
var arr2 = arr1.concat();
console.log(arr1 === arr2); // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(arr1[0] === arr2[0]); // 輸出true,說明其元素拷貝的是引用


/**
 * 數(shù)組的淺拷貝
 * ES6的 Object.assign() 和 對象擴(kuò)展運(yùn)算符...
 * 由于數(shù)組是特殊的對象,所以ES6中的這種方式也可以用于數(shù)組
 */
var arr1 = [{name: "wenyuan"}, {name: "Evan You"}];
var arr2 = Object.assign([],arr1)
var arr3 = { ...arr1 };
console.log(arr1 === arr2); // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(arr1 === arr3); // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(arr1[0] === arr2[0]); // 輸出true,說明其元素拷貝的是引用
console.log(arr1[0] === arr3[0]); // 輸出true,說明其元素拷貝的是引用
  • 深拷貝

在堆中重新分配內(nèi)存,并且把源對象所有屬性都進(jìn)行新建拷貝,以保證深拷貝的對象的引用圖不包含任何原有對象或?qū)ο髨D上的任何對象,拷貝后的對象與原來的對象是完全隔離,互不影響。

下面列舉一些深拷貝的例子:

/**
 * 對象的深拷貝
 * JSON.stringify()和JSON.parse()
 * 這種深拷貝最簡單,但有其局限性,上文已經(jīng)提到過了
 */
var obj1 = {
 name:'wenyuan',
 age: 22,
 social: {
  blog: 'www.wenyuanblog.com'
 },
 skills: ['js', 'html', 'css', 'python']
}
var obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj1 === obj2) // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(obj1.social === obj2.social) // 輸出false,說明對于Object類型的屬性也是拷貝實(shí)例
console.log(obj1.skills === obj2.skills) // 輸出false,說明對于Array類型的屬性也是拷貝實(shí)例


/**
 * 對象的深拷貝
 * jQuery的 $.extend(true,a,b)
 */
var obj1 = {
 name:'wenyuan',
 age: 22,
 social: {
  blog: 'www.wenyuanblog.com'
 },
 skills: ['js', 'html', 'css', 'python']
}
var obj2 = $.extend(true,obj1);
console.log(obj1 === obj2) // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(obj1.social === obj2.social) // 輸出false,說明對于Object類型的屬性也是拷貝實(shí)例
console.log(obj1.skills === obj2.skills) // 輸出false,說明對于Array類型的屬性也是拷貝實(shí)例


/**
 * 對象的深拷貝
 * 也可以自己寫一個(gè)函數(shù)實(shí)現(xiàn),用遞歸+判斷,注意別進(jìn)入死循環(huán)就好
 * 這里不舉例了,以前我整理過一篇常用工具類函數(shù)的博客,里面包含了深拷貝函數(shù)
 */


/**
 * 對象的深拷貝
 * lodash的_.cloneDeep
 */
var obj1 = {
 name:'wenyuan',
 age: 22,
 social: {
  blog: 'www.wenyuanblog.com'
 },
 skills: ['js', 'html', 'css', 'python']
}
var obj2 = _.cloneDeep(obj1);
console.log(obj1 === obj2) // 輸出false,說明外層數(shù)組拷貝的是實(shí)例
console.log(obj1.social === obj2.social) // 輸出false,說明對于Object類型的屬性也是拷貝實(shí)例
console.log(obj1.skills === obj2.skills) // 輸出false,說明對于Array類型的屬性也是拷貝實(shí)例

以上就是JavaScript中的淺拷貝與深拷貝的知識點(diǎn),以代碼的形式記錄下來,方便回顧。

到此這篇關(guān)于Vue父子組件傳值的一些坑的文章就介紹到這了,更多相關(guān)Vue父子組件傳值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue2+JS實(shí)現(xiàn)掃雷小游戲

    Vue2+JS實(shí)現(xiàn)掃雷小游戲

    實(shí)現(xiàn)小游戲可以鍛煉自己的邏輯思維能力,也不會(huì)很枯燥,完成時(shí)會(huì)給自己帶來一種滿足感。本文就將利用Vue和JS實(shí)現(xiàn)簡單的掃雷小游戲,需要的可以參考一下
    2022-06-06
  • VUE項(xiàng)目中引入JS文件的方法總結(jié)

    VUE項(xiàng)目中引入JS文件的方法總結(jié)

    在vue中如果把所有的代碼都寫到一個(gè)頁面中,有時(shí)比較難找,顯得比較復(fù)雜,下面這篇文章主要給大家介紹了關(guān)于VUE項(xiàng)目中引入JS文件的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • 使用vue控制元素顯示隱藏方式

    使用vue控制元素顯示隱藏方式

    這篇文章主要介紹了使用vue控制元素顯示隱藏方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 一文帶你了解Vue中的axios和proxy代理

    一文帶你了解Vue中的axios和proxy代理

    這篇文章主要為大家詳細(xì)介紹了Vue中的axios和proxy代理的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2023-03-03
  • 詳解基于vue的服務(wù)端渲染框架NUXT

    詳解基于vue的服務(wù)端渲染框架NUXT

    這篇文章主要介紹了Nuxt之vue服務(wù)端渲染,NUXT集成了利用Vue開發(fā)服務(wù)端渲染的應(yīng)用所需要的各種配置,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • Vue3組合式API中使用forwardRef()函數(shù)

    Vue3組合式API中使用forwardRef()函數(shù)

    本文主要介紹了Vue3組合式API中使用forwardRef()函數(shù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 詳解vue 中使用 AJAX獲取數(shù)據(jù)的方法

    詳解vue 中使用 AJAX獲取數(shù)據(jù)的方法

    本篇文章主要介紹了詳解vue 中使用 AJAX獲取數(shù)據(jù)的方法,在VUE開發(fā)時(shí),數(shù)據(jù)可以使用jquery和vue-resource來獲取數(shù)據(jù),有興趣的可以了解一下。
    2017-01-01
  • Vue2路由跳轉(zhuǎn)傳參中文問題處理方案

    Vue2路由跳轉(zhuǎn)傳參中文問題處理方案

    在el-table中的記錄列表中放置了一個(gè) 操作按鈕,點(diǎn)這個(gè)按鈕時(shí)可以新增一個(gè)tab頁簽,并將通過路由傳參方式將一些信息傳遞到新打開的tab頁簽中,但發(fā)現(xiàn)傳遞中文參數(shù)時(shí)會(huì)出現(xiàn)報(bào)錯(cuò),所以本文給大家介紹了Vue2路由跳轉(zhuǎn)傳參中文問題處理方案,需要的朋友可以參考下
    2024-05-05
  • vue項(xiàng)目使用axios封裝request請求的過程

    vue項(xiàng)目使用axios封裝request請求的過程

    這篇文章主要介紹了vue項(xiàng)目使用axios封裝request請求,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • vue中對虛擬dom的理解知識點(diǎn)總結(jié)

    vue中對虛擬dom的理解知識點(diǎn)總結(jié)

    在本篇文章里小編給大家整理了一篇關(guān)于vue中對虛擬dom的理解知識點(diǎn)總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-06-06

最新評論

绥棱县| 深州市| 祁东县| 三河市| 七台河市| 叙永县| 五大连池市| 卢龙县| 承德县| 绥宁县| 舞钢市| 定日县| 孟村| 修水县| 剑河县| 高雄市| 阿鲁科尔沁旗| 澳门| 师宗县| 福鼎市| 莱芜市| 防城港市| 双江| 昌黎县| 隆安县| 廉江市| 沐川县| 万宁市| 芷江| 固原市| 玉门市| 安岳县| 麦盖提县| 通河县| 城步| 安吉县| 阿图什市| 石楼县| 贵州省| 措美县| 和硕县|