上一篇關於vue面試的文章 (面試時面試官想要聽到什麼答案) 中提到了多種組件傳值方式,本文對幾種傳值方式如何使用具體說明一下。html
props、$emit、eventbus、vuex、$parent / $children / ref、sessionStorage、localStorage、路由傳參(也是傳值) 這些傳值方式都太常見了,並且每個使用vue的人都不可能不知道,因此本文就不一一說明了,如今介紹幾種平時不常見的傳值方式。若是對以上幾個有疑問的能夠在評論中留言,感謝撥冗翻閱拙做,敬請斧正。vue
父組件中經過provide來提供變量, 而後再子組件中經過inject來注入變量。
注意: 這裏不論子組件嵌套有多深, 只要調用了inject 那麼就能夠注入provide中的數據,而不侷限於只能從當前父組件的props屬性中回去數據
假設A爲父組件B和C均爲A的子組件,D爲B的子組件,則在A組件中使用provide定義變量,在B、C、D組件中都可經過inject拿到傳過來的值。(provide中定義的變量不可在父組件中 使用)面試
注:provide 和 inject 主要爲高階插件/組件庫提供用例。並不推薦直接用於應用程序代碼中。(官方文檔描述)vuex
export default {
data () {
return {}
},
provide: {
index: '來自index的數據'
}
}
複製代碼
export default {
data () {
return {}
},
inject: ['index'] // 直接能夠在頁面使用index或在js中進行賦值
}
複製代碼
在父組件A中調用子組件three:<custom-three :custom="custom" :custon="custon" />
,子組件three使用props進行接收,未被子組件使用props接收的能夠使用$attrs拿到傳遞的值,即three組件分爲如下狀況
bash
此時,在three組件中引入four子組件,並使用v-bind將$attrs綁定在組件上<custom-four v-bind="$attrs" />
便可在four中使用props或$attrs接收,按此規律可一直傳遞。session
<div custon="ton">
<p>three---tom</p> >
<p>attr---{}</p>
</div>
複製代碼
在子組件中添加inheritAttrs能夠將div標籤的 custon="ton" 隱藏,inheritAttrs默認值爲true,將其設爲false便可隱藏。注意:將inheritAttrs設爲false並不會影響$attrs的使用。ide
2中講述的是使用$attrs將父組件的值隔代傳給子組件,本小節中的$listeners就是將方法從父組件隔代傳給子組件,實現子組件調用時將子組件的值隔代傳給父組件。函數
首先在父組件A中調用子組件three:<custom-three @customEvent="customEvent" />
,此時在子組件A中使用$listeners接收,拿到的是一個對象{customEvent: function(){...}},在three組件中再調用子組件four,並使用v-on將$listeners綁定在子組件上`` ,此時在子組件four中便可直接直接訪問customEvent或使用$listeners訪問customEvent。post
<template>
<div>
<custom-three :custom="custom" :custon="custon" @customEvent="customEvent"></custom-three>
</div>
</template>
<script>
import customThree from './chuanzhi/three'
export default {
data () {
return {
custom: 'tom',
custon: 'ton'
}
},
components: {
customThree
},
mounted () {},
methods: {
customEvent(data) {
console.log('data', data)
}
}
}
</script>
複製代碼
<template>
<div>
<p>three---{{ custom }}</p>
<p>attr---{{$attrs}}</p>
<p>-------------------------------------</p>
<custom-four v-bind="$attrs" v-on="$listeners"></custom-four>
</div>
</template>
<script>
import customFour from './four'
export default {
data() {
return {}
},
components: {
customFour
},
props: ['custom'],
inheritAttrs:false
created() {
console.log('1', this.$listeners)
}
}
</script>
複製代碼
<template>
<div>
<p>four---{{ custon }}</p>
<p>attr---{{$attrs}}</p>
<el-button @click="fashe">發射</el-button>
</div>
</template>
<script>
export default {
data() {
return {}
},
props: ['custon'],
inheritAttrs:false
created() {
console.log('2', this.$listeners)
},
methods: {
fashe() {
this.$emit('customEvent', 'piupiupiu')
}
}
}
</script>
複製代碼
observable讓一個對象可響應。Vue 內部會用它來處理 data 函數返回的對象。ui
返回的對象能夠直接用於渲染函數和計算屬性內,而且會在發生改變時觸發相應的更新。也能夠做爲最小化的跨組件狀態存儲器,用於簡單的場景:
在組件1中調用setCount使count加1或減1,各個組件內調用的count都將進行改變,並會觸發組件刷新
import vue from 'vue';
export const store = vue.observable({count: 0});
export const mutation = {
setCount( count ){
store.count = count;
}
}
複製代碼
<template>
<div class="hello">
<p @click="setCount(testCount + 1)">+</p>
<p @click="setCount(testCount - 1)">-</p>
<test />
<p>{{testCount}}</p>
</div>
</template>
<script>
import test from './test'
import { store, mutation} from './store.js'
export default {
name: 'HelloWorld',
components: {
test
},
methods: {
setCount: mutation.setCount
},
computed: {
testCount(){
return store.count
}
}
}
複製代碼
<template>
<div>test{{testCount}}</div>
</template>
<script>
import { store } from './store.js';
export default {
computed: {
testCount(){
return store.count
}
}
}
</script>
複製代碼