Vue組件間傳值的實(shí)現(xiàn)解析
1. 父組件向子組件傳值
1.1 描述
父組件以屬性的形式綁定值到子組件身上。
子組件通過使用屬性 props 接收(props 是單向數(shù)據(jù)流【只讀屬性】:當(dāng)父組件的屬性變化時(shí),將傳導(dǎo)給子組件,但是反過來不會(huì),即子組件中不可以修改父組件的值,應(yīng)該通過給子組件傳數(shù)據(jù)的父組件修改)
1.2 props接收數(shù)據(jù)
語法:
props: 數(shù)組 | 對(duì)象
數(shù)組方式接收:
此方式,一般用于你自己定義組件給自己所用,是一種簡(jiǎn)寫方式
數(shù)組中的元素就是你自定義的屬性名稱(注意這里是自定義的屬性名稱,而不是父組件數(shù)據(jù)源中的數(shù)據(jù)名稱)
示例:
子組件(child.vue):
<template>
<div>
<div class="title">child</div>
<br />
<div>{{ title }}</div>
</div>
</template>
<script>
export default {
// 在vue中接受父組件通過自定義屬性傳過來的數(shù)據(jù),通過配置props來接受
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ù)可以通過自定義屬性的方式向子組件傳遞 -->
<!-- 第一個(gè) title 是我們自定義的屬性名稱;第二個(gè) title 是當(dāng)前組件 data 中的數(shù)據(jù)名稱 -->
<!-- 兩個(gè)名稱可以不一樣,但是一般情況下,我們寫成一樣的 -->
<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名稱就是你自定義屬性名稱
// 類型首字母大寫
// 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)該通過給子組件傳數(shù)據(jù)的父組件修改,這樣設(shè)計(jì)是為了防止子和父在修改數(shù)據(jù)時(shí),造成的數(shù)據(jù)混亂。
在 Vue 中,如果子組件修改了父組件傳過來的數(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)聽子組件的事件,實(shí)現(xiàn)通信 - 父組件直接把修改數(shù)據(jù)的方法以屬性的方式傳給子組件(通過形參方式傳遞)
方法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() {
// 通過給當(dāng)前的組件定義一個(gè)自定義的事情,完成子向父
// 參數(shù)1:自定義事件的名稱,參數(shù)2以后,它是傳過去的數(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. 兄弟組件間傳值
概述:
兄弟間組件傳值,通過公共的父組件來進(jìn)行。這種方式使得兩個(gè)兄弟組件共用的數(shù)據(jù)得到提升,即狀態(tài)提升。
子組件通過修改父組件中自己和兄弟的公共數(shù)據(jù),來和自己的兄弟組件傳值。
示例:
子組件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. 事件總線
概述:
兄第組件間通過狀態(tài)提升的方式來進(jìn)行傳值,適用于父子場(chǎng)景中,一旦涉及到子孫場(chǎng)景,狀態(tài)提升的操作就變得很復(fù)雜,這時(shí)候我們就要用到 Vue2 中給我們提供的事件總線來處理。
什么是事件總線?
非父子組件或更多層級(jí)間組件間傳值,在Vue中通過單獨(dú)的事件中心來管理組件間的傳值。
它相當(dāng)于一個(gè)全局的倉(cāng)庫(kù),任何組件都可以去這個(gè)倉(cāng)庫(kù)里獲取事件,它就類似溝通橋梁的概念,就像是所有組件共用相同的事件中心,可以向該中心注冊(cè)發(fā)送事件或接收事件,所以組件都可以上下平行的通知其他組件來進(jìn)行通信。
簡(jiǎn)單來說就是,假設(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ā)布
語法:
- 建立統(tǒng)一的事件中心:
const bus = new Vue() - 傳遞數(shù)據(jù)方,通過一個(gè)事件觸發(fā):
bus.$emit(方法名,傳遞的數(shù)據(jù)) - 接收數(shù)據(jù)方,在生命周期函數(shù)中,通過
bus.$on(方法名,(參數(shù))=>{})來監(jiān)聽 - 銷毀事件,在接受數(shù)據(jù)方,通過
bus.$off(方法名)銷毀,銷毀之后無法監(jiān)聽數(shù)據(jù)
示例:
建立統(tǒng)一的事件中心(即全局對(duì)象)可以在主 js 文件中寫入如下代碼:
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 事件總線 --- 是當(dāng)前文件的私有變量
// 因?yàn)樗薪M件對(duì)象都能看到 Vue 原型對(duì)象上的屬性和方法,所以我們可以在Vue的原型對(duì)象上通過設(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,傳過去的數(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 被用來給元素或子組件注冊(cè)引用信息。引用信息將會(huì)注冊(cè)在父組件的 $refs 對(duì)象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實(shí)例。
ref 它不但可以實(shí)現(xiàn)組件通信,而且它還可以獲取dom對(duì)象。
使用ref來獲取普通元素的dom對(duì)象:
<template>
<div>
<h3 class="title">App組件</h3>
<hr />
<!--
ref它可以實(shí)現(xiàn)組件通信,而且它還可以獲取dom對(duì)象
-->
<!-- 使用ref來獲取普通元素的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')
}
},
// 寫在 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ā)布,父組件的后代無論在哪個(gè)層級(jí)都能收到
// 寫法1:
// provide: {
// title: "app中的標(biāo)題",
// },
// 如果你要使用當(dāng)前組件中的數(shù)據(jù)或方法,就需要把provide寫成函數(shù)方式且返回一個(gè)對(duì)象
// 寫法2:
provide() {
return {
title: this.msg,
};
},
methods: {},
};
</script>子組件:
<template>
<div>
<h3>child組件 --- {{ title }}</h3>
</div>
</template>
<script>
export default {
// 注入
// 數(shù)組方式接收 寫的比較的多
// 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 獲取沒有在 props 中定義的屬性,把 props 沒有接收到的屬性進(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 來處理所以的自定義屬性數(shù)據(jù):
簡(jiǎn)單來說,就是拿一個(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 來顯示
// 這時(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è)語法糖,它是 value和事件[input[默認(rèn)]]的集合體
-->
<!-- v-model語法糖的作用相當(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)于寫有這個(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ù)
上文說到 props 是單向數(shù)據(jù)流,子組件不能修改父組件的數(shù)據(jù),但是加上 sync 修飾符就可以實(shí)現(xiàn)修改 。
父組件:
<template>
<div>
<h3 class="title">App組件</h3>
<hr />
<!--
sync修飾符,它是一語法糖 動(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事件是固定寫法
this.$emit('update:title', Date.now())
}
}
}
</script>
11. localStorage / sessionStorage
這種通信比較簡(jiǎn)單,缺點(diǎn)是數(shù)據(jù)和狀態(tài)比較混亂,不太容易維護(hù)。
通過window.localStorage.getItem(key)獲取數(shù)據(jù)
通過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)混亂問題。
到此這篇關(guān)于Vue組件間傳值的實(shí)現(xiàn)解析的文章就介紹到這了,更多相關(guān)Vue組件間傳值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue如何解決sass-loader的版本過高導(dǎo)致的編譯錯(cuò)誤
這篇文章主要介紹了vue如何解決sass-loader的版本過高導(dǎo)致的編譯錯(cuò)誤問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
ElementUI多個(gè)子組件表單的校驗(yàn)管理實(shí)現(xiàn)
這篇文章主要介紹了ElementUI多個(gè)子組件表單實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
vue實(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)聽Vue項(xiàng)目報(bào)錯(cuò)的4種方式?
本文主要介紹了如何監(jiān)聽Vue項(xiàng)目報(bào)錯(cuò)的4種方式,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
Vue-resource攔截器判斷token失效跳轉(zhuǎn)的實(shí)例
下面小編就為大家?guī)硪黄猇ue-resource攔截器判斷token失效跳轉(zhuǎn)的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
Vue3?Watch踩坑實(shí)戰(zhàn)之watch監(jiān)聽無效
Vue.js中的watch選項(xiàng)用于監(jiān)聽Vue實(shí)例上某個(gè)特定的數(shù)據(jù)變化,下面這篇文章主要給大家介紹了關(guān)于Vue3?Watch踩坑實(shí)戰(zhàn)之watch監(jiān)聽無效的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05

