父 => 子
父组件向子组件传值比较简单,直接使用v-bind:key = val
1 2 3 4
| //父组件 <template> <child :name = "'tom'" :age="'12'" /> </template>
|
1 2 3 4 5 6 7 8 9 10
| //子组件 <template> <div> {{name}} --- {{age}} <div> </template>
<sctipt> props:["name","age"] </sctipt>
|
这样在子组件中可以显示父组件给子组件传的值。
值得注意的是:在子组件中可以对父组件穿的值进行检验。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| //子组件 <template> <div> {{name}} --- {{age}}----{{id}}----{{address}}---{{email}} <div> </template>
<sctipt> props:{ //验证为字符串 "name":String, //验证为数字 "age":Number, //验证为字符串或者数组 "id":[String,Number], //验证为必须传递的字段,并且默认值为北京 "address":{ required:true, default:function(){ return "北京" } }, //进行高级验证 "email":{ validator: function(val){ return /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(val) } } } </sctipt>
|
子 => 父
一般不推荐子组件向父组件传值,即父 => 子的单向数据流会使整个项目更加容易维护。否则无法维护项目的整体性,组件内的状态可能会发生不在预期之内的改变。
但有时又必须通过子组件来改变父组件的值,则Vue官方提供了子组件与父组件通信的方法。借用这个通信的方法可以顺势进行传值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| //父组件 <template> <!-- 通过组件事件进行传值 --> <child @getData = getData/> {{val}} </template>
<script> export default { data () { return { val:"父组件的值" } }, methods:{ getData(val){ this.val = val; } }, mounted(){ //或者直接挂载在vue实例上 this.$on('getData', this.) } } </script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| //子组件 <template> <button @click="sendData"> 向父组件传值 </button> </template>
<script> export default { data () { return { val:"子组件的值" } }, methods:{ sendData(val){ this.$emit("getData",this.val); } } } </script>
|
即利用v-on为子组件 添加一个自定义时间,并将父组件的特定方法传入这个监听事件。
在子组件中调用this.$emit('funcName',args...)
来调用父组件的方法,并利用参数将值传入至父组件。
兄弟组件
兄弟组件或者跨多级组件则可以使用vuex来进行数组的传输。具体就不在这里讨论vuex的用法。
跨级组件通信
Vuex
$attrs、$listeners
Provide、inject
$attrs、$listeners
2.4.0 新增
2.4.0 新增
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <template> <div class="test"> <child v-bind="{name, sex, age}" v-on="{changeName,changeAge}"></child> </div> </template>
<script> import child from './child'
export default { data() { return { name: '张三', sex: '男', age: 11, } }, components: { child }, methods: { changeName(name) { this.name = name }, changeAge(age) { this.age = age } } } </script>
|
子组件child.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <div class="child"> child组件的$attrs {{$attrs}} <child-child v-bind="$attrs" v-on="$listeners" @showAttrs="showAttrs"></child-child> </div> </template>
<script> import childChild from './child-child' export default { name: "child", props: ['name'], inheritAttrs: false, created() { console.log('child', this.$listeners) }, components: { childChild }, methods: { showAttrs() { console.log(this.$attrs) } } } </script>
|
孙子组件:child-child.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <template> <div class="child-child"> child-child组件的$attrs {{$attrs}} </div> </template>
<script> export default { name: "child-child", inheritAttrs: false, created() { console.log('child-child',this.$listeners) } } </script>
|
利用$attrs、$listeners
可以实现层级传递,将跨级组件的值传递下去。
Provide、inject
2.2.0 新增
类型:
- provide:
Object | () => Object
- inject:
Array<string> | { [key: string]: string | Symbol | Object }
详细:
provide
和 inject
主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。
provide
选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的 property。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 Symbol
和 Reflect.ownKeys
的环境下可工作。
inject
选项应该是:
- 一个字符串数组,或
- 一个对象,对象的 key 是本地的绑定名,value 是:
- 在可用的注入内容中搜索用的 key (字符串或 Symbol),或
- 一个对象,该对象的:
from
property 是在可用的注入内容中搜索用的 key (字符串或 Symbol)
default
property 是降级情况下使用的 value
提示:provide
和 inject
绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| var Provider = { provide: { foo: 'bar' }, }
var Child = { inject: ['foo'], created () { console.log(this.foo) } }
var grandson = { inject: ['foo'], created () { console.log(this.foo) } }
|