概述
vue中元件之間的傳值傳值情況主要有以下三種
- 父元件向子元件傳值
- 子元件向父元件傳值
- 兄弟元件之間相互傳值或者是兩個沒有關係的元件之間的傳值
在開始介紹之前我們先建立3個vue檔案,檔名分別為:Parent.vue , Child1.vue , Child2.vue
父元件向子元件傳值
這種情況是三種傳值方案中最簡單的, 通過在子元件中使用 props就可以實現
父元件Parent.vue中的程式碼
<template>
<div>
<child-1 :btnName="btnName"/>
</div>
</template>
<script>
import Child1 from './Child1'
export default {
name: 'Parent',
components: {
'child-1': Child1
},
data () {
return {
btnName: ' 我是一個button'
}
}
}
</script>
複製程式碼
子元件Child1.vue
<template>
<button > {{btnName}}</button>
</template>
<script>
export default {
name: 'Child1',
props: ['btnName']
}
</script>
<style>
button{
padding:5px 10px;
margin:2px;
background-color:#fff;
border-radius: 5px;
}
</style>
複製程式碼
關鍵點就是需要在子元件中 使用 props 關鍵字 來接收父元件傳過來的值
顯示效果如下
子元件向父元件傳值
在子元件向父元件傳值時需要使用 vue 中的 $on 和 $emit ,使用$emit 可以觸發 $on 中監聽的事件,現在我們來實現一個可以統計按鈕點選次數的功能
在父元件中有個 count 欄位用於統計,button點選的次數
首先我們需要在Parent.vue的data中定義count變數,預設值為0,程式碼如下:
data () {
return {
btnName: ' 我是一個button',
count: 0
}
}
複製程式碼
然後將count加入到template中便於顯示, 此時parent.vue的template的程式碼如下
<template>
<div>
<p>點選次數: {{count}}</p>
<child-1 :btnName="btnName"/>
</div>
</template>
複製程式碼
count加上後頁面的顯示效果如下:
接下來我們需要在父元件中增加一個可以改變count值的事件,同時在 中加上監聽事件<template>
<div>
<p>點選次數: {{count}}</p>
<child-1 :btnName="btnName" @update:count="changeCount"/>
</div>
</template>
<script>
import Child1 from './Child1'
export default {
name: 'Parent',
components: {
'child-1': Child1
},
data () {
return {
btnName: ' 我是一個button',
count: 0
}
},
methods: {
changeCount () {
++this.count
}
}
}
</script>
複製程式碼
子元件Child1.vue
<template>
<button @click="clickHandle"> {{btnName}}</button>
</template>
<script>
export default {
name: 'Child1',
props: ['btnName'],
methods: {
clickHandle () {
this.$emit('update:count')
}
}
}
</script>
複製程式碼
現在通過點選button即可實現改變count的值
兄弟元件之間的傳值
兄弟元件之間傳值有兩種方式:
- 將需要改變的值放到父元件中,子元件通過props來獲取父元件的值
- 通過eventbus 來實現兄弟元件之間的傳值,其原理還是通過$on和$emit來時實現的,區別是現在全域性建立一個空的vue物件,然後將事件繫結到該空物件上,最後通過該空物件來觸發$on監聽的事件
現在還是通過上面的例子來實現說明這兩種情況
在開始之前需要新建一個元件Child2,然後將count移動到child2中,然後在parent中引入child2
Child2.vue
<template>
<p>點選次數: {{count}}</p>
</template>
<script>
export default{
name: 'Child2',
props: ['count']
}
</script>
複製程式碼
Parent.vue
<template>
<div>
<child-2 />
<child-1 :btnName="btnName"/>
</div>
</template>
<script>
import Child1 from './Child1'
import Child2 from './Child2'
export default {
name: 'Parent',
components: {
'child-1': Child1,
'child-2': Child2
},
data () {
return {
btnName: ' 我是一個button'
}
}
}
</script>
複製程式碼
此時點選button 即可實現統計功能,但是這種方式不太好的地方是它會通過父元件來進行過度,那樣就會涉及到對父元件的修改,如果要改變的變數很多,則需要在父元件中宣告很多變數,然後在傳到子元件中進行修改,既然是兄弟元件之間的傳值,那麼有沒有辦法直接跳過父元件,讓兄弟元件之間直接進行交流,這個時候就需要用到eventbus 首先建立一個bus.js的檔案 ,在檔案中我們需要建立一個空vue物件,程式碼如下:
import Vue from 'vue'
export default new Vue()
複製程式碼
然後在 Child1和Child2中引入該檔案
此時parent.vue , child1.vue , child2.vue 他們的程式碼分別如下
Parent.vue
<template>
<div>
<child-2 />
<child-1 :btnName="btnName"/>
</div>
</template>
<script>
import Child1 from './Child1'
import Child2 from './Child2'
export default {
name: 'Parent',
components: {
'child-1': Child1,
'child-2': Child2
},
data () {
return {
btnName: ' 我是一個button'
}
}
}
</script>
複製程式碼
Child1.vue
<template>
<button @click="clickHandle"> {{btnName}}</button>
</template>
<script>
import Event from '../bus'
export default {
name: 'Child1',
props: ['btnName'],
methods: {
clickHandle () {
Event.$emit('update:count')
}
}
}
</script>
<style>
button{
padding:5px 10px;
margin:2px;
background-color:#fff;
border-radius: 5px;
}
</style>
複製程式碼
Child2.vue
<template>
<p>點選次數: {{count}}</p>
</template>
<script>
import Event from '../bus'
export default{
name: 'Child2',
data () {
return {
count: 0
}
},
created () {
Event.$on('update:count', () => {
++this.count
})
}
}
</script>
複製程式碼
eventbus這種方式不僅可以用到兄弟元件之間,它還可以用到任意兩個不想關聯的元件之間,但是如果大量使用的話不太利於管理,比如可能會照成命名的衝突。在比較複雜的系統中可以考慮是用vuex
在上面的例子中$on ,$emit 並沒有直接傳值過去,如果需要傳值,可用如下格式:
this.$on('test', function (msg) {
console.log(msg)
})
this.$emit('test', 'hi')
// => "hi"
複製程式碼
附錄
vue中的事件型別(轉載自官網):
vm.$on( event, callback )
引數:
- {string | Array} event (陣列只在 2.2.0+ 中支援)
- {Function} callback
用法: 監聽當前例項上的自定義事件。事件可以由vm.$emit觸發。回撥函式會接收所有傳入事件觸發函式的額外引數。
示例:
vm.$on('test', function (msg) {
console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"
複製程式碼
vm.$once( event, callback )
引數:
- {string} event
- {Function} callback
用法: 監聽一個自定義事件,但是隻觸發一次,在第一次觸發之後移除監聽器
vm.$off( [event, callback] )
引數:
- {string | Array} event (只在 2.2.2+ 支援陣列)
- {Function} [callback]
用法:
- 移除自定義事件監聽器。
- 如果沒有提供引數,則移除所有的事件監聽器;
- 如果只提供了事件,則移除該事件所有的監聽器;
- 如果同時提供了事件與回撥,則只移除這個回撥的監聽器。
vm.$emit( event, […args] )
引數:
- {string} event
- [...args]
觸發當前例項上的事件。附加引數都會傳給監聽器回撥。