上一篇关于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>
复制代码