組件系統(tǒng)是 Vue.js 其中一個(gè)重要的概念,它提供了一種抽象,讓我們可以使用獨(dú)立可復(fù)用的小組件來構(gòu)建大型應(yīng)用檐盟。在 Vue.js 應(yīng)用程序開發(fā)過程中常常需要處理組件傳值的問題,下面詳細(xì)列舉幾種常見的組件傳值方法。
1. props
父組件代碼:
<template>
? <child-component title="子組件標(biāo)題"></child-component> // 傳輸靜態(tài)值
? <child-component v-bind:title="title"></child-component> // 傳輸動(dòng)態(tài)值
</template>
<script>
import ChildComponent from './ChildComponent'
export default {
? components: { ChildComponent },
? data() {
? ? return {
? ? ? title: '子組件標(biāo)題'
? ? }
? }
}
</script>
子組件 ChildComponent.vue 代碼:
<template>
? <h1>{{title}}</h1>
</template>
<script>
export default {
? props: ['title']
}
</script>
1
2
3
4
5
6
7
8
9
10
所有的 prop 都使得其父子 prop 之間形成了一個(gè)單向下行綁定:父級(jí) prop 的更新會(huì)向下流動(dòng)到子組件中惨撇,但是反過來則不行。這樣會(huì)防止從子組件意外改變父級(jí)組件的狀態(tài)府寒,從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解魁衙。
2. vm.$refs
適用于父組件獲取子組件的值。
父組件代碼:
<template>
? <div>
? ? <child-component ref="child"></child-component>
? ? <button @click="getChildProp()">獲取子組件的屬性的值</button>
? ? <button @click="getChildMethod()">獲取子組件的方法</button>
? </div>
</template>
<script>
import ChildComponent from './components/ChildComponent.vue'
export default {
? components:{ ChildComponent },
? methods: {
? ? getChildProp () {
? ? ? alert(this.$refs.child.msg) // 子組件child的值
? ? },
? ? getChildMethod () {
? ? ? this.$refs.child.func() // 子組件child的方法
? ? }
? }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
子組件 ChildComponent.vue 代碼:
<template>
<div></div>
</template>
<script>
export default {
? data () {
? ? return {
? ? ? msg: "子組件child的值"
? ? }
? },
? methods: {
? ? func () {
? ? ? alert("子組件child的方法")
? ? }
? }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
注意:因?yàn)?ref 本身是作為渲染結(jié)果被創(chuàng)建的株搔,在初始渲染的時(shí)候你不能訪問它們 - 它們還不存在剖淀!$refs 也不是響應(yīng)式的,因此你不應(yīng)該試圖用它在模板中做數(shù)據(jù)綁定纤房。
3. vm.$parent
適用于子組件獲取父組件的值纵隔。
父組件代碼:
<template>
? <child-component></child-component>
</template>
<script>
import ChildComponent from './components/ChildComponent.vue'
export default {
? components:{ ChildComponent },
? data () {
? ? return {
? ? ? title: '標(biāo)題'
? ? }
? }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
子組件 ChildComponent.vue 代碼:
<script>
export default {
? created () {
? ? alert(this.$parent.title) // 標(biāo)題
? }
}
</script>
1
2
3
4
5
6
7
8
4. vm.$emit(eventName, […args])
適用于子組件向父組件傳值,子組件可以通過觸發(fā)父組件事件傳遞參數(shù)炮姨。
父組件代碼:
<template>
? <child-component v-on:handleClick="handleEvent"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent'
export default {
? components: { ChildComponent },
? methods: {
? ? handleEvent (value) {
? ? ? alert(value) // 'abc'
? ? }
? }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
子組件 ChildComponent.vue 代碼:
<template>
? <button v-on:click="handleClickEvent"></button>
</template>
<script>
export default {
? methods: {
? ? handleClickEvent () {
? ? ? this.$emit('handleClick', 'abc')
? ? }
? }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
5.vm.emit/vm.$on
適用于父子組件及兄弟組件傳值捌刮。
通過 $emit 觸發(fā)當(dāng)前實(shí)例上的事件,并將參數(shù)傳遞給監(jiān)聽器,通過 o n 監(jiān) 聽 當(dāng) 前 實(shí) 例 上 的 自 定 義 事 件 舒岸。 下 面 介 紹 通 過 v m . on 監(jiān)聽當(dāng)前實(shí)例上的自定義事件绅作。下面介紹通過 vm.on監(jiān)聽當(dāng)前實(shí)例上的自定義事件。下面介紹通過vm.emit / vm.$on 實(shí)現(xiàn)兄弟組件傳值:
main.js代碼:
import Vue from 'vue'
import App from './App.vue'
var bus = new Vue() // 定義公共實(shí)例
export default bus
new Vue({
? render: h => h(App),
}).$mount('#app')
1
2
3
4
5
6
7
8
9
父組件 App.vue 代碼:
<template>
? <div>
? ? <child-one></child-one>
? ? <child-two></child-two>
? </div>
</template>
<script>
import ChildOne from './components/ChildOne.vue'
import ChildTwo from './components/ChildTwo.vue'
export default {
? components:{ ChildOne, ChildTwo }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
子組件 ChildOne.vue 代碼:
<template>
? <button @click="btnClick">點(diǎn)擊按鈕</button>
</template>
<script>
import bus from '../main.js'
export default {
? methods: {
? ? btnClick () {
? ? ? bus.$emit('getTitle', '標(biāo)題')
? ? }
? }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
子組件 ChildTwo.vue 代碼:
<template>
? <div></div>
</template>
<script>
import bus from '../main.js'
export default {
? mounted () {
? ? bus.$on('getTitle', (value) => {
? ? ? alert(value) // 標(biāo)題
? ? })
? }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
注意: vm.e m i t / v m . emit / vm.emit/vm.on 自定義事件必須是在一個(gè)公共的實(shí)例上才能觸發(fā)蛾派。
6. provide / inject
適用于祖先組件向其所有子孫后代組件傳值俄认。
祖先組件通過 provide 定義變量后,無論組件層次有多深洪乍,它的子孫后代組件都能夠通過 inject 獲取變量值眯杏。
父組件代碼:
<template>
? <child></child>
</template>
<script>
import Child from './Child.vue'
export default {
? provide: { title: "標(biāo)題" },
? components:{ Child }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
子組件 Child.vue 代碼:
<template>
? <div>
? ? {{title}} // 標(biāo)題
? ? <grandson></grandson>
? </div>
</template>
<script>
import Grandson from './Grandson.vue'
export default {
? inject: ['title'],
? components:{ Grandson }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
子組件的子組件 Grandson.vue 代碼:
<template>
? <div>{{title}}</div> // 標(biāo)題
</template>
<script>
export default {
? inject: ['title']
}
</script>
1
2
3
4
5
6
7
8
9
10
注意:provide 和 inject 主要為高階插件/組件庫(kù)提供用例。并不推薦直接用于應(yīng)用程序代碼中典尾。
7. 路由
通過路由地址參數(shù)傳值役拴,適用于組件路由切換場(chǎng)景
路由傳參的方式有多種,詳細(xì)信息可以查看 Vue Router 官網(wǎng)钾埂,下面簡(jiǎn)單介紹一種:
跳轉(zhuǎn)前的組件相關(guān)代碼:
this.$router.push({
? path: '/App',
? query: {
? ? title: '標(biāo)題'
? }
})
1
2
3
4
5
6
7
對(duì)應(yīng)路由相關(guān)配置:
{
? path: '/app',
? name: 'App',
? component: App
1
2
3
4
5
跳轉(zhuǎn)后組件調(diào)用方法:
this.$route.query.title // 標(biāo)題
1
2
注意:避免敏感數(shù)據(jù)通過路由地址傳參顯示在頁(yè)面url后面河闰。
8. localStorage / sessionStorage
適用于組件間任意傳值科平,常用于存儲(chǔ)客戶端臨時(shí)信息。
localStorage 生命周期是永久的姜性,可以實(shí)現(xiàn)同一瀏覽器下不同窗口傳值瞪慧。而 sessionStorage 的生命周期為當(dāng)前窗口或標(biāo)簽頁(yè),一旦窗口或標(biāo)簽頁(yè)關(guān)閉部念,通過 sessionStorage 存儲(chǔ)的信息則會(huì)被清空弃酌。以 localStorage 為例:
組件存儲(chǔ)信息調(diào)用方法:
var obj = {'title': '標(biāo)題'}
localStorage.setItem('info', JSON.stringify(obj));
1
2
3
組件獲取信息調(diào)用方法:
var info = JSON.parse(localStorage.getItem('info')) // {'title': '標(biāo)題'}
1
2
9. Vuex
適用于組件間任意傳值,常用于開發(fā)大型頁(yè)面應(yīng)用中儡炼。
Vuex 是專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理器妓湘,可以簡(jiǎn)單理解為一個(gè)全局變量,在 Vuex 中定義的變量可以被各個(gè)組件使用乌询。但是我們不能像傳統(tǒng) JS 的那種直接賦值形式來修改榜贴,我們必須得按照 Vuex 給我們提供的規(guī)則來修改。
————————————————
版權(quán)聲明:本文為CSDN博主「姜天生i」的原創(chuàng)文章妹田,遵循CC 4.0 BY-SA版權(quán)協(xié)議唬党,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_37041819/article/details/105550147