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

vue通過(guò)子組件修改父組件prop的多種實(shí)現(xiàn)方式

 更新時(shí)間:2021年09月22日 10:24:53   作者:鄭宇棟  
這篇文章主要介紹了vue通過(guò)子組件修改父組件prop的幾種實(shí)現(xiàn)方式,比較常用的方式是通過(guò)Prop單向傳遞的規(guī)則,需要的朋友可以參考下

前言

實(shí)際工作項(xiàng)目開(kāi)發(fā)中,很經(jīng)常會(huì)有父組件先傳遞值給子組件,再由子組件渲染展示的場(chǎng)景,下面我總結(jié)一下目前工作中遇到和用過(guò)的一些方式,也算是給大家一個(gè)實(shí)現(xiàn)方式和思路參考,如有理解不對(duì)or有其他方法歡迎在評(píng)論區(qū)留言指導(dǎo)~

常用方式

推薦,遵循prop單向傳遞的規(guī)則,基本數(shù)據(jù)類型和引用數(shù)據(jù)類型均可。

1. 通過(guò)父組件on監(jiān)聽(tīng)子組件emit事件實(shí)現(xiàn)修改prop

原理:

  • 給子組件中的input標(biāo)簽綁定value屬性賦值prop中的值,因?yàn)槭怯胿alue而不是v-model,所以修改input值的時(shí)候并不會(huì)影響到prop。
  • 然后給input綁定input事件,每次輸入內(nèi)容都會(huì)觸發(fā)input事件,在事件里通過(guò)this.$emit(‘父要監(jiān)聽(tīng)的事件名', 修改后的值)去將值向上傳遞。
  • 父組件中通過(guò)on監(jiān)聽(tīng)子組件剛剛觸發(fā)的emit事件,將事件傳遞過(guò)來(lái)的值更新到父組件的data中。
  • 父組件data中的值更新后,因?yàn)橛型ㄟ^(guò)prop傳遞給子組件,所以子組件也會(huì)同步更新prop值并渲染視圖層。

emit

父組件代碼如下:

<template>
  <div style="background-color: skyblue;">
    <h3>通過(guò)父組件on監(jiān)聽(tīng)子組件emit事件實(shí)現(xiàn)修改prop</h3>
    <div>父obj:{{ obj }}</div>
    <div>父msg:{{ msg }}</div>
    <!-- 父組件調(diào)用子組件時(shí)通過(guò)on監(jiān)聽(tīng)子組件觸發(fā)的emit事件,以接收值并更新用 -->
    <emitChild
      :obj="obj"
      :msg="msg"
      @update-obj="updateObj"
      @update-msg="updateMsg"
    />
  </div>
</template>

<script>
import emitChild from './components/emitChild'

export default {
  name: 'emitUpdate',
  components: {
    emitChild
  },
  data () {
    return {
      obj: {
        name: 'zhangsan',
        age: 18
      },
      msg: 'hello'
    }
  },
  methods: {
    // 監(jiān)聽(tīng)子組件觸發(fā)的事件并更新data中的obj
    updateObj (key, newVal) {
      this.obj[key] = newVal
    },
    // 監(jiān)聽(tīng)子組件觸發(fā)的事件并更新data中的msg
    updateMsg (newVal) {
      this.msg = newVal
    }
  }
}
</script>

子組件代碼如下:

<template>
  <div style="background-color: pink;">
    <div>
      <span>修改name:</span>
      <!-- 這里綁定值用value,因?yàn)閕nput在這主要用作展示prop數(shù)據(jù),實(shí)際修改不在子組件,子組件只是作為修改觸發(fā)源 -->
      <!-- 綁定input事件,作為觸發(fā)源的入口 -->
      <input type="text" :value="obj.name" @input="updateObj($event, 'name')">
    </div>
    <div>
      <span>修改age:</span>
      <input type="text" :value="obj.age" @input="updateObj($event, 'age')">
    </div>
    <div>
      <span>修改msg:</span>
      <input type="text" :value="msg" @input="updateMsg($event.target.value)">
    </div>
  </div>
</template>

<script>
export default {
  name: 'emitUpdateChild',
  props: {
    obj: {
      type: Object,
      default: () => {}
    },
    msg: {
      type: String,
      default: ''
    }
  },
  methods: {
    // 通知父組件更新obj
    updateObj ($event, key) {
      // 接收輸入的值,和obj中對(duì)應(yīng)需要更新值的屬性,然后回傳給父組件
      // 父組件就可以知道子組件需要更新obj中哪個(gè)屬性的值
      this.$emit('update-obj', key, $event.target.value)
    },
    // 通知父組件更新msg
    updateMsg (newVal) {
      this.$emit('update-msg', newVal)
    }
  }
}
</script>

2. 通過(guò)父組件sync修飾符 + 子組件emit事件實(shí)現(xiàn)修改prop

原理:

  • 給子組件中的input標(biāo)簽綁定value屬性賦值prop中的值,因?yàn)槭怯胿alue而不是v-model,所以修改input值的時(shí)候并不會(huì)影響到prop。
  • 然后給input綁定input事件,每次輸入內(nèi)容都會(huì)觸發(fā)input事件,在事件里通過(guò)this.$emit(‘父要監(jiān)聽(tīng)的事件名', 修改后的值)去將值向上傳遞。
  • 父組件調(diào)用子組件傳遞prop時(shí),在prop后加上.sync即可將事件傳遞過(guò)來(lái)的值更新到父組件的data中,因?yàn)閟ync其實(shí)就相當(dāng)于執(zhí)行了@監(jiān)聽(tīng)子觸發(fā)的事件名 = "父data中的屬性名 = emit傳遞的值(即$event)"這一段代碼。
  • 父組件data中的值更新后,因?yàn)橛型ㄟ^(guò)prop傳遞給子組件,所以子組件也會(huì)同步更新prop值并渲染視圖層。

sync

父組件代碼如下:

<template>
  <div style="background-color: skyblue;">
    <h3>通過(guò)父組件sync修飾符 + 子組件emit事件實(shí)現(xiàn)修改prop</h3>
    <div>父obj:{{ obj }}</div>
    <div>父msg:{{ msg }}</div>
    <!-- 父組件調(diào)用子組件傳遞prop時(shí),在prop后加上.sync即可 -->
    <syncChild :obj.sync="obj" :msg.sync="msg" />
    <!--
      sync其實(shí)就相當(dāng)于執(zhí)行了
        @監(jiān)聽(tīng)子觸發(fā)的事件名 = "父data中的屬性名 = emit傳遞的值(即$event)"
      這一段代碼
    -->
    <!-- 效果相當(dāng)于下面的代碼,所以父組件methods中不需要再定義修改data數(shù)據(jù)的方法 -->
    <!--
      <syncChild
        :obj="obj"
        :msg="msg"
        @update-obj="obj = $event"
        @update-msg="msg = $event"
      />
    -->
  </div>
</template>

<script>
import syncChild from './components/syncChild'

export default {
  name: 'syncUpdate',
  components: {
    syncChild
  },
  data () {
    return {
      obj: {
        name: 'zhangsan',
        age: 18
      },
      msg: 'hello'
    }
  }
}
</script>

子組件代碼如下:

<template>
  <div style="background-color: pink;">
    <div>
      <span>修改name:</span>
      <!-- 這里綁定值用value,因?yàn)閕nput在這主要用作展示prop數(shù)據(jù),實(shí)際修改不在子組件,子組件只是作為修改觸發(fā)源 -->
      <!-- 綁定input事件,作為觸發(fā)源的入口 -->
      <input type="text" :value="childObj.name" @input="updateObj($event, 'name')">
    </div>
    <div>
      <span>修改age:</span>
      <input type="text" :value="childObj.age" @input="updateObj($event, 'age')">
    </div>
    <div>
      <span>修改msg:</span>
      <input type="text" :value="msg" @input="updateMsg($event.target.value)">
    </div>
  </div>
</template>

<script>
// 這里引入lodash工具庫(kù)的cloneDeep深拷貝方法
// 官方文檔地址 https://www.lodashjs.com/
import { cloneDeep } from 'lodash'

export default {
  name: 'emitUpdateChild',
  props: {
    obj: {
      type: Object,
      default: () => {}
    },
    msg: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      // 這里通過(guò)深拷貝將prop的obj復(fù)制了一份,主要為了:
      // 1.區(qū)分2個(gè)對(duì)象(引用類型)用的不是同一個(gè)內(nèi)存地址
      // 2.保留對(duì)象中所有的值,方便子組件渲染/修改/回傳用
      childObj: cloneDeep(this.obj)
    }
  },
  methods: {
    // 通知父組件更新obj
    updateObj ($event, key) {
      // 接收輸入的值,和childObj中對(duì)應(yīng)需要更新值的屬性
      // 然后更新childOBj后,回傳給父組件
      // 父組件直接把拿到的childObj更新到data的obj即可
      this.childObj[key] = $event.target.value
      this.$emit('update:obj', this.childObj)
    },
    // 通知父組件更新msg
    updateMsg (newVal) {
      this.$emit('update:msg', newVal)
    }
  }
}
</script>

取巧方式

主要針對(duì)引用數(shù)據(jù)類型,繞過(guò)了vue對(duì)于prop的檢測(cè)機(jī)制,具體看項(xiàng)目規(guī)范是否允許這樣寫(xiě)。

3.通過(guò)data實(shí)現(xiàn)修改prop

前提:只有引用數(shù)據(jù)類型可以實(shí)現(xiàn)

原理:

  • 將父組件傳入的prop直接賦值給子組件的data,此時(shí)prop和data兩邊的變量指向的都是同一個(gè)內(nèi)存地址,所以修改data等于修改prop。
  • vue2開(kāi)始不允許直接修改prop,但此時(shí)我們表面修改的是data不是prop,因此vue不會(huì)拋出錯(cuò)誤,相當(dāng)于繞過(guò)了vue對(duì)于不允許修改prop的檢測(cè)機(jī)制。

data

父組件代碼如下:

<template>
  <div style="background-color: skyblue;">
    <h3>通過(guò)賦值到data實(shí)現(xiàn)修改prop</h3>
    <div>父obj:{{ obj }}</div>
    <div>父msg:{{ msg }}</div>
    <dataChild :obj="obj" :msg.sync="msg" />
  </div>
</template>

<script>
import dataChild from './components/dataChild'

export default {
  name: 'dataUpdate',
  components: {
    dataChild
  },
  data () {
    return {
      obj: {
        name: 'zhangsan',
        age: 18
      },
      msg: 'hello'
    }
  }
}
</script>

子組件代碼如下:

<template>
  <div style="background-color: pink;">
    <div>
      <span>修改name:</span>
      <!-- 這里因?yàn)槲覀冎苯影裵rop賦值給data了,所以可以直接用v-model雙向綁定修改數(shù)據(jù) -->
      <input type="text" v-model="dataObj.name">
    </div>
    <div>
      <span>修改age:</span>
      <input type="text" v-model="dataObj.age">
    </div>
    <div>
      <span>修改msg:</span>
      <!-- 這里提供另一種修改基本數(shù)據(jù)類型的思路,可以通過(guò)watch偵聽(tīng)器實(shí)現(xiàn) -->
      <input type="text" v-model="dataMsg">
    </div>
  </div>
</template>

<script>
export default {
  name: 'dataChild',
  props: {
    obj: {
      type: Object,
      default: () => {}
    },
    msg: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      // 引用數(shù)據(jù)類型直接賦值時(shí)是淺拷貝,只會(huì)復(fù)制內(nèi)存地址,修改其中一個(gè)會(huì)影響另一個(gè)
      dataObj: this.obj,
      // 基本數(shù)據(jù)類型直接賦值時(shí)是復(fù)制值,修改其中一個(gè)不會(huì)影響另一個(gè)
      dataMsg: this.msg
    }
  },
  watch: {
    // 這里偵聽(tīng)data中復(fù)制過(guò)來(lái)的dataMsg,當(dāng)修改時(shí)執(zhí)行emit通知父組件進(jìn)行更新
    dataMsg (newVal) {
      this.$emit('update:msg', newVal)
    }
  }
}
</script>

4.通過(guò)計(jì)算屬性computed實(shí)現(xiàn)修改prop

前提:只有引用數(shù)據(jù)類型可以實(shí)現(xiàn)

原理:

  • 在子組件中直接通過(guò)計(jì)算屬性computed監(jiān)聽(tīng)父組件傳入的prop,此時(shí)計(jì)算屬性computed和prop兩邊的變量指向的都是同一個(gè)內(nèi)存地址,所以修改計(jì)算屬性computed等于修改prop。
  • vue2開(kāi)始不允許直接修改prop,但此時(shí)我們表面修改的是計(jì)算屬性computed不是prop,因此vue不會(huì)拋出錯(cuò)誤,相當(dāng)于繞過(guò)了vue對(duì)于不允許修改prop的檢測(cè)機(jī)制。

computed

父組件代碼如下:

<template>
  <div style="background-color: skyblue;">
    <h3>通過(guò)計(jì)算屬性監(jiān)聽(tīng)實(shí)現(xiàn)修改prop</h3>
    <div>父obj:{{ obj }}</div>
    <div>父msg:{{ msg }}</div>
    <computedChild :obj="obj" :msg.sync="msg" />
  </div>
</template>

<script>
import computedChild from './components/computedChild'

export default {
  name: 'computedUpdate',
  components: {
    computedChild
  },
  data () {
    return {
      obj: {
        name: 'zhangsan',
        age: 18
      },
      msg: 'hello'
    }
  }
}
</script>

子組件代碼如下:

<template>
  <div style="background-color: pink;">
    <div>
      <span>修改name:</span>
      <!-- 這里因?yàn)槲覀冎苯油ㄟ^(guò)計(jì)算屬性computed監(jiān)聽(tīng)prop了,所以可以直接用v-model雙向綁定修改數(shù)據(jù) -->
      <input type="text" v-model="computedObj.name">
    </div>
    <div>
      <span>修改age:</span>
      <input type="text" v-model="computedObj.age">
    </div>
    <div>
      <span>修改msg:</span>
      <!-- 這里提供另一種修改基本數(shù)據(jù)類型的思路,可以通過(guò)計(jì)算屬性computed的setter實(shí)現(xiàn) -->
      <input type="text" v-model="computedMsg">
    </div>
  </div>
</template>

<script>
export default {
  name: 'computedChild',
  props: {
    obj: {
      type: Object,
      default: () => {}
    },
    msg: {
      type: String,
      default: ''
    }
  },
  computed: {
    computedObj () {
      // 這里直接return引用數(shù)據(jù)類型obj,此時(shí)computedObj相當(dāng)于obj
      // 所以是淺拷貝,只會(huì)復(fù)制內(nèi)存地址,修改其中一個(gè)會(huì)影響另一個(gè)
      return this.obj
    },
    computedMsg: {
      get () {
        // 這里prop每次更新時(shí),都會(huì)觸發(fā)計(jì)算屬性的getter方法獲取最新的值
        // 直接return基本數(shù)據(jù)類型時(shí)是復(fù)制值,修改其中一個(gè)不會(huì)影響另一個(gè)
        return this.msg
      },
      set (newVal) {
        // 這里利用計(jì)算屬性的setter方法,監(jiān)聽(tīng)到值修改時(shí)觸發(fā)emit通知父組件更新值
        this.$emit('update:msg', newVal)
      }
    }
  }
}
</script>

到此這篇關(guān)于vue通過(guò)子組件修改父組件prop的幾種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)vue子組件修改父組件prop內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue面包屑組件的封裝方法

    vue面包屑組件的封裝方法

    這篇文章主要為大家詳細(xì)介紹了vue面包屑組件的封裝方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 詳解vue2.0 使用動(dòng)態(tài)組件實(shí)現(xiàn) Tab 標(biāo)簽頁(yè)切換效果(vue-cli)

    詳解vue2.0 使用動(dòng)態(tài)組件實(shí)現(xiàn) Tab 標(biāo)簽頁(yè)切換效果(vue-cli)

    本篇文章主要介紹了詳解vue2.0 使用動(dòng)態(tài)組件實(shí)現(xiàn) Tab 標(biāo)簽頁(yè)切換效果(vue-cli),具有一定的參考價(jià)值,有需要的可以了解下
    2017-08-08
  • vue3+vite項(xiàng)目中按需引入vant報(bào)錯(cuò):Failed?to?resolve?import的解決方案

    vue3+vite項(xiàng)目中按需引入vant報(bào)錯(cuò):Failed?to?resolve?import的解決方案

    最近在vue項(xiàng)目中引入vant的時(shí)候發(fā)現(xiàn)報(bào)錯(cuò)了,經(jīng)過(guò)嘗試發(fā)現(xiàn)了問(wèn)題,現(xiàn)將完整引入流程提供給大家參考,下面這篇文章主要給大家介紹了關(guān)于vue3+vite項(xiàng)目中按需引入vant報(bào)錯(cuò):Failed?to?resolve?import的解決方案,需要的朋友可以參考下
    2022-12-12
  • Vue3 directive自定義指令內(nèi)部實(shí)現(xiàn)示例

    Vue3 directive自定義指令內(nèi)部實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了Vue3 directive自定義指令內(nèi)部實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Vue中render方法的使用詳解

    Vue中render方法的使用詳解

    這篇文章主要為大家詳細(xì)介紹了Vue中render方法的使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • Vue 組件間的樣式?jīng)_突污染

    Vue 組件間的樣式?jīng)_突污染

    本篇文章主要介紹了Vue 組件間的樣式?jīng)_突污染,當(dāng)多個(gè)樣式出現(xiàn)時(shí),就會(huì)導(dǎo)致樣式?jīng)_突,本文介紹了具體解決方法
    2017-08-08
  • Vue使用虛擬鍵盤(pán)及中英文切換功能

    Vue使用虛擬鍵盤(pán)及中英文切換功能

    這篇文章主要給大家介紹了關(guān)于Vue使用虛擬鍵盤(pán)及中英文切換的相關(guān)資料,有時(shí)候在大型觸屏設(shè)備(如雙屏設(shè)備)中往往就沒(méi)有鍵盤(pán)去操作,所以就需要去建立一個(gè)虛擬鍵盤(pán)去操作,需要的朋友可以參考下
    2023-06-06
  • vue實(shí)現(xiàn)將圖像文件轉(zhuǎn)換為base64

    vue實(shí)現(xiàn)將圖像文件轉(zhuǎn)換為base64

    這篇文章主要介紹了vue實(shí)現(xiàn)將圖像文件轉(zhuǎn)換為base64,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • vue拖拽組件使用方法詳解

    vue拖拽組件使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了vue拖拽組件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Vue實(shí)現(xiàn)小購(gòu)物車功能

    Vue實(shí)現(xiàn)小購(gòu)物車功能

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)小購(gòu)物車功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12

最新評(píng)論

白水县| 辉县市| 宣汉县| 铁岭县| 阳春市| 禄丰县| 垦利县| 济宁市| 凤台县| 唐河县| 肇州县| 大冶市| 贡觉县| 白河县| 芜湖市| 宜都市| 丰都县| 余庆县| 罗甸县| 武宣县| 秦安县| 汾西县| 丹凤县| 伊宁市| 苍溪县| 台前县| 伊金霍洛旗| 香港| 定襄县| 通化市| 许昌县| 诸暨市| 繁昌县| 华坪县| 三明市| 永宁县| 高碑店市| 皮山县| 磐安县| 芒康县| 呼和浩特市|