Vue組件間傳值的實(shí)現(xiàn)解析
1. 父組件向子組件傳值
1.1 描述
父組件以屬性的形式綁定值到子組件身上。
子組件通過(guò)使用屬性 props 接收(props 是單向數(shù)據(jù)流【只讀屬性】:當(dāng)父組件的屬性變化時(shí),將傳導(dǎo)給子組件,但是反過(guò)來(lái)不會(huì),即子組件中不可以修改父組件的值,應(yīng)該通過(guò)給子組件傳數(shù)據(jù)的父組件修改)
1.2 props接收數(shù)據(jù)
語(yǔ)法:
props: 數(shù)組 | 對(duì)象
數(shù)組方式接收:
此方式,一般用于你自己定義組件給自己所用,是一種簡(jiǎn)寫(xiě)方式
數(shù)組中的元素就是你自定義的屬性名稱(注意這里是自定義的屬性名稱,而不是父組件數(shù)據(jù)源中的數(shù)據(jù)名稱)
示例:
子組件(child.vue):
<template> <div> <div class="title">child</div> <br /> <div>{{ title }}</div> </div> </template> <script> export default { // 在vue中接受父組件通過(guò)自定義屬性傳過(guò)來(lái)的數(shù)據(jù),通過(guò)配置props來(lái)接受 props: ["title"], // 在方法中得到數(shù)據(jù) created() { console.log(this.title); }, }; </script> <style lang="scss" scoped> .title { color: red; } </style>
父組件(App.vue):
<template> <div> <h3 class="title">App組件</h3> <hr /> <!-- vue中父組件中的數(shù)據(jù)可以通過(guò)自定義屬性的方式向子組件傳遞 --> <!-- 第一個(gè) title 是我們自定義的屬性名稱;第二個(gè) title 是當(dāng)前組件 data 中的數(shù)據(jù)名稱 --> <!-- 兩個(gè)名稱可以不一樣,但是一般情況下,我們寫(xiě)成一樣的 --> <child :title="title" /> </div> </template> <script> import child from "./components/child.vue"; export default { components: { child, }, data() { return { title: "我是一個(gè)顯示內(nèi)容", }; }, }; </script> <style lang="scss" scoped></style>
對(duì)象方式接收:
一般用于,封裝的組件提供給別人使用,它可以限制屬性的類型和默認(rèn)值
示例:
子組件(child.vue):
<template> <div> <div class="title">child組件</div> <br /> <div>{{ title }}--{{ age }}</div> </div> </template> <script> export default { props: { // key名稱就是你自定義屬性名稱 // 類型首字母大寫(xiě) // attrtitle: String title: { // 接收的數(shù)據(jù)類型 type: String, // 直接給值 [基礎(chǔ)類型] | 回調(diào)函數(shù) [基礎(chǔ)類型和引用類型都可以,引用類型設(shè)置默認(rèn)值必須是此方案] default: "我是一個(gè)字符串", }, // 自定義方法驗(yàn)證接收的數(shù)據(jù) age: { type: Number, default: () => 10, // 驗(yàn)證操作 validator: (value) => { if (value > 90) { // 返回一個(gè)警告 return false; } return true; } }, }, }; </script> <style lang="scss" scoped> .title { color: red; } </style>
父組件(App.vue):
<template> <div> <h3 class="title">App組件</h3> <hr /> <child :title="title" :age="100" /> <child /> <child :title="'100'" /> </div> </template> <script> import child from "./components/child.vue"; export default { components: { child, }, data() { return { title: "我是一個(gè)顯示內(nèi)容", }; }, }; </script> <style lang="scss" scoped></style>
2. 子組件向父組件傳值
上文提到props 是單向數(shù)據(jù)流,子組件中不可以修改父組件的值,應(yīng)該通過(guò)給子組件傳數(shù)據(jù)的父組件修改,這樣設(shè)計(jì)是為了防止子和父在修改數(shù)據(jù)時(shí),造成的數(shù)據(jù)混亂。
在 Vue 中,如果子組件修改了父組件傳過(guò)來(lái)的數(shù)據(jù),控制臺(tái)會(huì)報(bào)一個(gè)警告,但在 React 中會(huì)直接報(bào)錯(cuò)。
那么子組件要怎么向父組件傳值呢?
有兩種方式:
- 子組件用
$emit()
定義自定義事件,$emit()
第一個(gè)參數(shù)為 自定義的事件名稱 第二個(gè)參數(shù)為需要傳遞的數(shù)據(jù);父組件用v-on(@)
綁定子組件定義的自定義事件名,監(jiān)聽(tīng)子組件的事件,實(shí)現(xiàn)通信 - 父組件直接把修改數(shù)據(jù)的方法以屬性的方式傳給子組件(通過(guò)形參方式傳遞)
方法2實(shí)現(xiàn):
父組件:
<template> <div> <h3 class="title">App組件</h3> <hr /> <!-- 把修改age的方法以屬性的方式傳給子組件 --> <child :title="title" :age="age" :setAge="setAge" /> </div> </template> <script> import child from "./components/child.vue"; export default { components: { child, }, data() { return { title: "我是一個(gè)顯示內(nèi)容", age: 80, }; }, methods: { setAge(n = 1) { this.age += n; }, }, }; </script> <style lang="scss" scoped></style>
子組件:
<template> <div> <div class="title">child組件</div> <br /> <div>{{ title }}--{{ age }}</div> <br /> <button @click="addAge">+++++</button> </div> </template> <script> export default { props: { title: { // 接收的數(shù)據(jù)類型 type: String, // 直接給值 [基礎(chǔ)類型] | 回調(diào)函數(shù) [基礎(chǔ)類型和引用類型都可以,引用類型設(shè)置默認(rèn)值必須是此方案] default: "我是一個(gè)字符串", }, // 自定義方法驗(yàn)證接收的數(shù)據(jù) age: { type: Number, default: () => 10, // 驗(yàn)證操作 validator: (value) => { if (value > 90) { // 返回一個(gè)警告 return false; } return true; }, }, setAge: Function, }, methods: { addAge() { this.setAge(2); }, }, }; </script> <style lang="scss" scoped> .title { color: red; } </style>
方法1實(shí)現(xiàn):
子組件:
<template> <div> <div class="title">child組件</div> <br /> <div>{{ title }}--{{ age }}</div> <br /> <button @click="addAge">+++++</button> </div> </template> <script> export default { props: { title: { // 接收的數(shù)據(jù)類型 type: String, // 直接給值 [基礎(chǔ)類型] | 回調(diào)函數(shù) [基礎(chǔ)類型和引用類型都可以,引用類型設(shè)置默認(rèn)值必須是此方案] default: "我是一個(gè)字符串", }, // 自定義方法驗(yàn)證接收的數(shù)據(jù) age: { type: Number, default: () => 10, // 驗(yàn)證操作 validator: (value) => { if (value > 200) { // 返回一個(gè)警告 return false; } return true; }, }, setAge: Function, }, methods: { addAge() { // 通過(guò)給當(dāng)前的組件定義一個(gè)自定義的事情,完成子向父 // 參數(shù)1:自定義事件的名稱,參數(shù)2以后,它是傳過(guò)去的數(shù)據(jù) // this.$emit('onSetAge',......參數(shù)) this.$emit("onSetAge", 10); }, }, }; </script> <style lang="scss" scoped> .title { color: red; } </style>
父組件:
<template> <div> <h3 class="title">App組件</h3> <hr /> <!-- 父組件實(shí)現(xiàn)子組件創(chuàng)建的onSetAge自定義事件 --> <child :title="title" :age="age" @onSetAge="setAge" /> </div> </template> <script> import child from "./components/child.vue"; export default { components: { child, }, data() { return { title: "我是一個(gè)顯示內(nèi)容", age: 80, }; }, methods: { setAge(n = 1) { this.age += n; }, }, }; </script> <style lang="scss" scoped></style>
3. 兄弟組件間傳值
概述:
兄弟間組件傳值,通過(guò)公共的父組件來(lái)進(jìn)行。這種方式使得兩個(gè)兄弟組件共用的數(shù)據(jù)得到提升,即狀態(tài)提升。
子組件通過(guò)修改父組件中自己和兄弟的公共數(shù)據(jù),來(lái)和自己的兄弟組件傳值。
示例:
子組件1:
<template> <div> <h3>child1 -- {{ age }}</h3> <button @click="$emit('onAddAge', 1)">++++</button> </div> </template> <script> export default { props: ["age"], }; </script> <style lang="scss" scoped> </style>
子組件2:
<template> <div> <h3>child2 -- {{ age }}</h3> </div> </template> <script> export default { props: ["age"], }; </script> <style lang="scss" scoped> </style>
父組件:
<template> <div> <h3 class="title">App組件</h3> <hr /> <child1 :age="age" @onAddAge="addAge" /> <child2 :age="age" /> </div> </template> <script> import child1 from "./components/child1.vue"; import child2 from "./components/child2.vue"; export default { components: { child1, child2, }, data() { return { age: 80, }; }, methods: { addAge(n = 1) { this.age += n; }, }, }; </script> <style lang="scss" scoped></style>
4. 事件總線
概述:
兄第組件間通過(guò)狀態(tài)提升的方式來(lái)進(jìn)行傳值,適用于父子場(chǎng)景中,一旦涉及到子孫場(chǎng)景,狀態(tài)提升的操作就變得很復(fù)雜,這時(shí)候我們就要用到 Vue2 中給我們提供的事件總線來(lái)處理。
什么是事件總線?
非父子組件或更多層級(jí)間組件間傳值,在Vue中通過(guò)單獨(dú)的事件中心來(lái)管理組件間的傳值。
它相當(dāng)于一個(gè)全局的倉(cāng)庫(kù),任何組件都可以去這個(gè)倉(cāng)庫(kù)里獲取事件,它就類似溝通橋梁的概念,就像是所有組件共用相同的事件中心,可以向該中心注冊(cè)發(fā)送事件或接收事件,所以組件都可以上下平行的通知其他組件來(lái)進(jìn)行通信。
簡(jiǎn)單來(lái)說(shuō)就是,假設(shè)現(xiàn)在有一個(gè)組件 a 往全局倉(cāng)庫(kù)中塞數(shù)據(jù),另一個(gè)組件 b 只要訂閱了全局倉(cāng)庫(kù),就可以收到更新的數(shù)據(jù)。
事件總線只能進(jìn)行通知,不能進(jìn)行數(shù)據(jù)的存儲(chǔ)功能。
注意:實(shí)現(xiàn)事件總線的前提條件是,必須先訂閱和發(fā)布
語(yǔ)法:
- 建立統(tǒng)一的事件中心:
const bus = new Vue()
- 傳遞數(shù)據(jù)方,通過(guò)一個(gè)事件觸發(fā):
bus.$emit(方法名,傳遞的數(shù)據(jù))
- 接收數(shù)據(jù)方,在生命周期函數(shù)中,通過(guò)
bus.$on(方法名,(參數(shù))=>{})
來(lái)監(jiān)聽(tīng) - 銷毀事件,在接受數(shù)據(jù)方,通過(guò)
bus.$off(方法名)
銷毀,銷毀之后無(wú)法監(jiān)聽(tīng)數(shù)據(jù)
示例:
建立統(tǒng)一的事件中心(即全局對(duì)象)可以在主 js 文件中寫(xiě)入如下代碼:
import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false // 事件總線 --- 是當(dāng)前文件的私有變量 // 因?yàn)樗薪M件對(duì)象都能看到 Vue 原型對(duì)象上的屬性和方法,所以我們可以在Vue的原型對(duì)象上通過(guò)設(shè)定一個(gè)eventBus對(duì)象, // Vue.prototype.bus = new Vue(),此時(shí)所有的組件對(duì)象都能看到eventBus屬性對(duì)象。 const eventBus = new Vue() Vue.prototype.$eventBus = eventBus new Vue({ render: h => h(App), }).$mount('#app')
也可以使用插件的方式,建立全局對(duì)象:
新建一個(gè) bus.js 文件:
export default Vue => { Vue.prototype.$eventBus = new Vue() }
在 main.js 中導(dǎo)入:
import Vue from 'vue' import App from './App.vue' import bus from './plugin/bus' Vue.config.productionTip = false Vue.use(bus) new Vue({ render: h => h(App), }).$mount('#app')
父組件:
<template> <div> <h3 class="title">App組件</h3> <hr /> <child1 :age="age" /> <child2 :age="age" /> </div> </template> <script> import child1 from "./components/child1.vue"; import child2 from "./components/child2.vue"; export default { components: { child1, child2, }, data() { return { age: 80, }; }, // 讓父組件也訂閱子組件的頻道,作為介質(zhì)向子組件2傳遞數(shù)據(jù) created() { this.$eventBus.$on("age", (value) => (this.age += value)); }, // 在訂閱的地方都要銷毀,相當(dāng)于關(guān)閉頻道 beforeDestroy() { this.$eventBus.$off("age"); }, }; </script> <style lang="scss" scoped></style>
子組件1(發(fā)布者):
<template> <div> <h3>child1 -- {{ age }}</h3> <button @click="setAge">+++++</button> </div> </template> <script> export default { props: ["age"], methods: { setAge() { // 傳遞數(shù)據(jù)方 // 這里的作用是,往全局對(duì)象中塞數(shù)據(jù) // 參數(shù)1:頻道名稱,不能重復(fù) // 參數(shù)2-N,傳過(guò)去的數(shù)據(jù) this.$eventBus.$emit("age", 10); }, }, }; </script> <style lang="scss" scoped> </style>
子組件2(訂閱者):
<template> <div> <h3>child2 -- {{ age }}</h3> </div> </template> <script> export default { props: ["age"], // 接收數(shù)據(jù)方 // 這里相當(dāng)于子組件2訂閱了 age 頻道,可以接收到更新后的數(shù)據(jù) created() { this.$eventBus.$on("age", (value) => { console.log(value); }); }, beforeDestroy() { this.$eventBus.$off("age"); } }; </script> <style lang="scss" scoped> </style>
5. Ref
概述:
ref 被用來(lái)給元素或子組件注冊(cè)引用信息。引用信息將會(huì)注冊(cè)在父組件的 $refs 對(duì)象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實(shí)例。
ref 它不但可以實(shí)現(xiàn)組件通信,而且它還可以獲取dom對(duì)象。
使用ref來(lái)獲取普通元素的dom對(duì)象:
<template> <div> <h3 class="title">App組件</h3> <hr /> <!-- ref它可以實(shí)現(xiàn)組件通信,而且它還可以獲取dom對(duì)象 --> <!-- 使用ref來(lái)獲取普通元素的dom對(duì)象 --> <div ref="username">張三</div> <button @click="getUsernameDom">獲取張三dom</button> </div> </template> <script> export default { components: { }, data() { return { } }, methods: { getUsernameDom() { // ref 獲取dom對(duì)象 console.log(this.$refs['username'].innerHTML) } } } </script> <style lang="scss" scoped></style>
ref 獲取的 dom 列表并不是真實(shí)的 dom,因?yàn)楂@取 dom 是同步的,而視圖渲染是異步的。我們需要用到$nextTick
,該方法用于獲取最新的dom的方法 等待視圖渲染完畢后才觸發(fā)執(zhí)行,得到真實(shí)dom。
ref 綁定到自定義組件:
父組件:
<template> <div> <h3 class="title">App組件 -- {{ ptitle }}</h3> <hr /> <!-- ref 實(shí)現(xiàn)組件通信 如果ref綁定在自定義組件上,通可以得到當(dāng)前組件實(shí)例對(duì)象 --> <child ref="childRef" /> <button @click="getChild">父獲取child組件中的數(shù)據(jù)</button> </div> </template> <script> import child from './components/child.vue' export default { components: { child }, data() { return { age: 100, ptitle: '' } }, methods: { getChild() { // this.$refs.childRef.title = 'aaaaa' // this.ptitle = this.$refs.childRef.title this.ptitle = this.$refs.childRef.setTitle('afewfewfew') } }, // 寫(xiě)在 mounted 中也可以實(shí)現(xiàn) // mounted(){ // // console.log(this.$refs.childRef?.title) // this.ptitle = this.$refs.childRef.title // } } </script> <style lang="scss" scoped></style>
子組件:
<template> <div> <h3>child組件</h3> </div> </template> <script> export default { data() { return { title: '我是child組件中的數(shù)據(jù)' } }, methods: { setTitle(title) { this.title = title+'#####3' return this.title } } } </script> <style lang="scss" scoped></style>
6. root/parent/children
概述:
獲取父組件對(duì)象或子組件對(duì)象集合。
三個(gè)方法:
this.$root
this.$parent
this.$children
示例:
父組件:
<template> <div> <h3 class="title">App組件</h3> <button @click="getChild">父獲取child組件中的數(shù)據(jù)</button> <hr /> <child /> </div> </template> <script> import child from './components/child.vue' export default { components: { child }, data() { return { title: 'parent' } }, methods: { getChild() { console.log(this.$root,"---父組件中獲取"); // console.log(this.$children); // 獲取子元素中的數(shù)據(jù) // console.log(this.$children[0].title); // 如果有多個(gè)孩子 this.$children.forEach(node => { // console.log(node?.title) // 短路運(yùn)算 console.log(node.title && node.title) }) } } } </script> <style lang="scss" scoped></style>
子組件:
<template> <div> <h3>child組件</h3> <button @click="getParent">獲取父組件中的數(shù)據(jù)</button> </div> </template> <script> export default { data() { return { title: '我是child組件中的數(shù)據(jù)' } }, methods: { getParent() { // 獲取到根上的元素(main.js),在任何層級(jí)都可以獲取 console.log(this.$root,"---子組件中獲取") // 子組件獲取父組件 console.log(this.$parent.title) } } } </script> <style lang="scss" scoped></style>
7. provide/inject
概述:
provide 和 inject 主要為高階插件/組件庫(kù)提供用例。并不推薦直接用于應(yīng)用程序代碼中。
這對(duì)選項(xiàng)需要一起使用,以允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴,不論組件層次有多深,并在起上下游關(guān)系成立的時(shí)間里始終生效。
比如我們現(xiàn)在想要封裝一個(gè)組件,組件內(nèi)層級(jí)很多,我們想在組件內(nèi)實(shí)現(xiàn)很方便的通信,卻又想要與外界隔絕,這時(shí)候就需要用到 provide/inject。
父組件向子組件傳值:
父組件:
<template> <div> <h3 class="title">App組件</h3> <hr /> <child /> </div> </template> <script> import child from "./components/child.vue"; export default { components: { child, }, data() { return { msg: 'app中的標(biāo)題' }; }, // 發(fā)布,父組件的后代無(wú)論在哪個(gè)層級(jí)都能收到 // 寫(xiě)法1: // provide: { // title: "app中的標(biāo)題", // }, // 如果你要使用當(dāng)前組件中的數(shù)據(jù)或方法,就需要把provide寫(xiě)成函數(shù)方式且返回一個(gè)對(duì)象 // 寫(xiě)法2: provide() { return { title: this.msg, }; }, methods: {}, }; </script>
子組件:
<template> <div> <h3>child組件 --- {{ title }}</h3> </div> </template> <script> export default { // 注入 // 數(shù)組方式接收 寫(xiě)的比較的多 // inject: ['title'], // 對(duì)象方式接收 inject: { title: { // 默認(rèn)值 default: () => '默認(rèn)值' }, }, data() { return {}; }, methods: {}, }; </script>
provide 和 inject 綁定并不是可響應(yīng)的,如果想要變成響應(yīng)式的,可以在父組件中 provide 返回一個(gè)函數(shù),并且在子組件中接收:
父組件:
<template> <div> <h3 class="title">App組件</h3> <input v-model="msg" /> <hr /> <child /> </div> </template> <script> import child from "./components/child.vue"; export default { components: { child, }, data() { return { msg: 'app中的標(biāo)題' }; provide() { return { title: () => this.msg }; }, methods: {}, }; </script>
子組件:
<template> <div> <h3>child組件 --- {{ title() }}</h3> </div> </template> <script> export default { // 對(duì)象方式接收 inject: { title: { // 默認(rèn)值 default: () => () => "默認(rèn)值", }, }, data() { return {}; }, methods: {}, }; </script>
8. $attrs/$listeners
概述:
$attrs 獲取沒(méi)有在 props 中定義的屬性,把 props 沒(méi)有接收到的屬性進(jìn)行接收
$listeners 獲取父組件給子組件自定義事件
示例:
父組件:
<template> <div> <h3 class="title">App組件</h3> <hr /> <child :msg="msg" uid="1" @setTitle="setTitle" /> </div> </template> <script> import child from './components/child.vue' export default { components: { child }, data() { return { msg: 'app中的標(biāo)題' } }, methods: { setTitle(title) { this.msg = title } } } </script>
子組件:
<template> <div> <h3>child組件 --- {{ $attrs.msg }}</h3> <button @click="setMsg">修改msg</button> </div> </template> <script> export default { props: ['uid'], data() { return {} }, methods: { setMsg() { // console.log(this.$listeners) this.$listeners.setTitle(Date.now()) } } } </script>
利用 attrs 來(lái)處理所以的自定義屬性數(shù)據(jù):
簡(jiǎn)單來(lái)說(shuō),就是拿一個(gè)組件(數(shù)據(jù)層容器)包裹另一個(gè)組件(最終顯示在頁(yè)面上的組件),增強(qiáng)了組件能力。
父組件:
<template> <div> <h3 class="title">App組件</h3> <hr /> <child :phone="phone" :uid="100" /> </div> </template> <script> import child from './components/child.vue' export default { components: { child }, data() { return { phone: '1323125125' } }, methods: {} } </script>
子組件(數(shù)據(jù)層容器,進(jìn)行數(shù)據(jù)包裝和處理):
<template> <div> <h3>child組件</h3> <showphone :attrs="attrs" /> </div> </template> <script> import showphone from './showphone.vue' export default { components: { // child 組件不直接顯示數(shù)據(jù),而是將數(shù)據(jù)進(jìn)行包裝處理后,交給自己的子組件 showphone 來(lái)顯示 // 這時(shí)的 child 相當(dāng)于一個(gè)數(shù)據(jù)層容器,包裹了 showphone 進(jìn)行了相關(guān)的數(shù)據(jù)處理 showphone }, data() { return { attrs: {} } }, created() { this.attrs = { ...this.$attrs, phone: 'abc ---' + this.$attrs.phone } } } </script>
子組件的子組件(最終顯示在頁(yè)面數(shù)據(jù)的組件):
<template> <div> <h3>showphone顯示手機(jī)號(hào)碼 --- {{ attrs.phone }}</h3> </div> </template> <script> export default { props: ['attrs'] } </script>
9. v-model綁定到自定義組件中
默認(rèn)用法:
父組件:
<template> <div> <h3 class="title">App組件</h3> <!-- v-model它可以對(duì)于表單項(xiàng)進(jìn)行數(shù)據(jù)的雙項(xiàng)綁定 --> <!-- <input type="text" v-model="title" /> --> <hr /> <!-- v-model它是一個(gè)語(yǔ)法糖,它是 value和事件[input[默認(rèn)]]的集合體 --> <!-- v-model語(yǔ)法糖的作用相當(dāng)于下面這一句 --> <!-- <child :value="title" @input="setTitle" /> --> <child v-model="title" /> </div> </template> <script> import child from './components/child.vue' export default { components: { child }, data() { return { title: '我是父組件的title' } }, // v-model相當(dāng)于寫(xiě)有這個(gè)方法 // methods: { // setTitle(title) { // this.title = title // } // } } </script>
子組件:
<template> <div> <!-- 默認(rèn)的 --> <h3>child組件 -- {{ value }}</h3> <!-- 默認(rèn)的 --> <button @click="$emit('input', Date.now())">修改value數(shù)據(jù)</button> </div> </template> <script> export default { // 默認(rèn)的 props: ['value'], data() { return {}; }, }; </script>
除了使用默認(rèn)的用法,還可以自定義屬性名稱和事件名稱:
只需要修改子組件:
<template> <div> <!-- 默認(rèn)的 --> <!-- <h3>child組件 -- {{ value }}</h3> --> <h3>child組件 -- {{ title }}</h3> <!-- 默認(rèn)的 --> <!-- <button @click="$emit('input', Date.now())">修改value數(shù)據(jù)</button> --> <button @click="$emit('change', Date.now())">修改value數(shù)據(jù)</button> </div> </template> <script> export default { // 默認(rèn)的 // props: ['value'], props: ["title"], model: { // 修改v-model中的綁定的屬性名稱,默認(rèn)為value prop: "title", // 修改v-model它的自定義事件的名稱,默認(rèn)為input event: "change", }, data() { return {}; }, }; </script>
10. sync同步動(dòng)態(tài)屬性數(shù)據(jù)
上文說(shuō)到 props 是單向數(shù)據(jù)流,子組件不能修改父組件的數(shù)據(jù),但是加上 sync 修飾符就可以實(shí)現(xiàn)修改 。
父組件:
<template> <div> <h3 class="title">App組件</h3> <hr /> <!-- sync修飾符,它是一語(yǔ)法糖 動(dòng)態(tài)屬性和 update:屬性名稱 事件 --> <child :title.sync="title" /> </div> </template> <script> import child from './components/child.vue' export default { components: { child }, data() { return { title: '我是父組件的title' } }, methods: {} } </script>
子組件:
<template> <div> <h3>child組件 -- {{ title }}</h3> <button @click="setTitle">修改Title</button> </div> </template> <script> export default { props: ['title'], data() { return {} }, methods: { setTitle() { // 這里的update事件是固定寫(xiě)法 this.$emit('update:title', Date.now()) } } } </script>
11. localStorage / sessionStorage
這種通信比較簡(jiǎn)單,缺點(diǎn)是數(shù)據(jù)和狀態(tài)比較混亂,不太容易維護(hù)。
通過(guò)window.localStorage.getItem(key)
獲取數(shù)據(jù)
通過(guò)window.localStorage.setItem(key,value)
存儲(chǔ)數(shù)據(jù)
注意用JSON.parse() / JSON.stringify()
做數(shù)據(jù)格式轉(zhuǎn)換
localStorage / sessionStorage可以結(jié)合vuex,實(shí)現(xiàn)數(shù)據(jù)的持久保存,同時(shí)使用vuex解決數(shù)據(jù)和狀態(tài)混亂問(wèn)題。
到此這篇關(guān)于Vue組件間傳值的實(shí)現(xiàn)解析的文章就介紹到這了,更多相關(guān)Vue組件間傳值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue如何解決sass-loader的版本過(guò)高導(dǎo)致的編譯錯(cuò)誤
這篇文章主要介紹了vue如何解決sass-loader的版本過(guò)高導(dǎo)致的編譯錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06ElementUI多個(gè)子組件表單的校驗(yàn)管理實(shí)現(xiàn)
這篇文章主要介紹了ElementUI多個(gè)子組件表單實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11vue實(shí)現(xiàn)動(dòng)態(tài)給data函數(shù)中的屬性賦值
這篇文章主要介紹了vue實(shí)現(xiàn)動(dòng)態(tài)給data函數(shù)中的屬性賦值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09如何監(jiān)聽(tīng)Vue項(xiàng)目報(bào)錯(cuò)的4種方式?
本文主要介紹了如何監(jiān)聽(tīng)Vue項(xiàng)目報(bào)錯(cuò)的4種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04Vue-resource攔截器判斷token失效跳轉(zhuǎn)的實(shí)例
下面小編就為大家?guī)?lái)一篇Vue-resource攔截器判斷token失效跳轉(zhuǎn)的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10Vue3?Watch踩坑實(shí)戰(zhàn)之watch監(jiān)聽(tīng)無(wú)效
Vue.js中的watch選項(xiàng)用于監(jiān)聽(tīng)Vue實(shí)例上某個(gè)特定的數(shù)據(jù)變化,下面這篇文章主要給大家介紹了關(guān)于Vue3?Watch踩坑實(shí)戰(zhàn)之watch監(jiān)聽(tīng)無(wú)效的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05