組件系統是 Vue.js 其中一個重要的概念,它提供了一種抽象,讓我們可以使用獨立可復用的小組件來構建大型應用。在 Vue.js 應用程序開發過程中常常需要處理組件傳值的問題,下面詳細列舉幾種常見的組件傳值方法。
1. props
父組件代碼:
<template>
? <child-component title="子組件標題"></child-component> // 傳輸靜態值
? <child-component v-bind:title="title"></child-component> // 傳輸動態值
</template>
<script>
import ChildComponent from './ChildComponent'
export default {
? components: { ChildComponent },
? data() {
? ? return {
? ? ? title: '子組件標題'
? ? }
? }
}
</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 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,但是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態,從而導致你的應用的數據流向難以理解。
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
注意:因為 ref 本身是作為渲染結果被創建的,在初始渲染的時候你不能訪問它們 - 它們還不存在!$refs 也不是響應式的,因此你不應該試圖用它在模板中做數據綁定。
3. vm.$parent
適用于子組件獲取父組件的值。
父組件代碼:
<template>
? <child-component></child-component>
</template>
<script>
import ChildComponent from './components/ChildComponent.vue'
export default {
? components:{ ChildComponent },
? data () {
? ? return {
? ? ? title: '標題'
? ? }
? }
}
</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) // 標題
? }
}
</script>
1
2
3
4
5
6
7
8
4. vm.$emit(eventName, […args])
適用于子組件向父組件傳值,子組件可以通過觸發父組件事件傳遞參數。
父組件代碼:
<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 觸發當前實例上的事件,并將參數傳遞給監聽器,通過 o n 監 聽 當 前 實 例 上 的 自 定 義 事 件 。 下 面 介 紹 通 過 v m . on 監聽當前實例上的自定義事件。下面介紹通過 vm.on監聽當前實例上的自定義事件。下面介紹通過vm.emit / vm.$on 實現兄弟組件傳值:
main.js代碼:
import Vue from 'vue'
import App from './App.vue'
var bus = new Vue() // 定義公共實例
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">點擊按鈕</button>
</template>
<script>
import bus from '../main.js'
export default {
? methods: {
? ? btnClick () {
? ? ? bus.$emit('getTitle', '標題')
? ? }
? }
}
</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) // 標題
? ? })
? }
}
</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 自定義事件必須是在一個公共的實例上才能觸發。
6. provide / inject
適用于祖先組件向其所有子孫后代組件傳值。
祖先組件通過 provide 定義變量后,無論組件層次有多深,它的子孫后代組件都能夠通過 inject 獲取變量值。
父組件代碼:
<template>
? <child></child>
</template>
<script>
import Child from './Child.vue'
export default {
? provide: { title: "標題" },
? components:{ Child }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
子組件 Child.vue 代碼:
<template>
? <div>
? ? {{title}} // 標題
? ? <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> // 標題
</template>
<script>
export default {
? inject: ['title']
}
</script>
1
2
3
4
5
6
7
8
9
10
注意:provide 和 inject 主要為高階插件/組件庫提供用例。并不推薦直接用于應用程序代碼中。
7. 路由
通過路由地址參數傳值,適用于組件路由切換場景
路由傳參的方式有多種,詳細信息可以查看 Vue Router 官網,下面簡單介紹一種:
跳轉前的組件相關代碼:
this.$router.push({
? path: '/App',
? query: {
? ? title: '標題'
? }
})
1
2
3
4
5
6
7
對應路由相關配置:
{
? path: '/app',
? name: 'App',
? component: App
1
2
3
4
5
跳轉后組件調用方法:
this.$route.query.title // 標題
1
2
注意:避免敏感數據通過路由地址傳參顯示在頁面url后面。
8. localStorage / sessionStorage
適用于組件間任意傳值,常用于存儲客戶端臨時信息。
localStorage 生命周期是永久的,可以實現同一瀏覽器下不同窗口傳值。而 sessionStorage 的生命周期為當前窗口或標簽頁,一旦窗口或標簽頁關閉,通過 sessionStorage 存儲的信息則會被清空。以 localStorage 為例:
組件存儲信息調用方法:
var obj = {'title': '標題'}
localStorage.setItem('info', JSON.stringify(obj));
1
2
3
組件獲取信息調用方法:
var info = JSON.parse(localStorage.getItem('info')) // {'title': '標題'}
1
2
9. Vuex
適用于組件間任意傳值,常用于開發大型頁面應用中。
Vuex 是專為 Vue.js 應用程序開發的狀態管理器,可以簡單理解為一個全局變量,在 Vuex 中定義的變量可以被各個組件使用。但是我們不能像傳統 JS 的那種直接賦值形式來修改,我們必須得按照 Vuex 給我們提供的規則來修改。
————————————————
版權聲明:本文為CSDN博主「姜天生i」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_37041819/article/details/105550147