# Vue 组件通信方式
# 常规形式
# props/$emit
父组件通过 props
的方式向子组件传递数据,而子组件通过 $emit
向父组件传递数据
// 父向子组件传递title属性
<comA :title="title" @update="updateTitle"></comA>
// 子组件向父组件传递数据
this.$emit('update', 'newTitle')
# @update:[Prop]
@update:myPropName
相当于绑定事件的 v-on
的简写方式,省去了定义接收子组件更新的函数,可以直接对属性进行更新
// 父向子组件传递title属性
<comA @update:title="title = $event"></comA>
// 子组件向父组件传递数据
this.$emit('update:title', 'newTitle')
# :[Prop].sync
相当于 props/$emit
的简写
// 父向子组件传递title组件
<comA :title.sync="title"></comA>
// 子组件向父组件传递数据
this.$emit('update:title', 'newTitle')
传递了一个
title
属性绑定了一个
v-on
监听器
适合范围:相临父子组件
# provide/inject
这对选项需要一起使用,允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深
// 父组件通过 provide 传递数擗
provide () {
return {
provideData: this.provideData
}
},
data:function () {
return {
show: false,
arr: [1,2,3],
provideData: {
name: 'lanjz'
}
}
}
// 子组件通过 inject 接收数据
inject: ['provideData']
provide
: 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的属性。在该对象中你可以使用Symbols
作为key
,但是只在原生支持Symbol
和Reflect.ownKeys
的环境下可工作inject
: 选项应该是:一个字符串数组
一个对象,对象的
key
是本地的绑定名,value
是:在可用的注入内容中搜索用的
key
(字符串或Symbol
)一个对象,该对象的:
from
属性是在可用的注入内容中搜索用的key
(字符串或Symbol
)default
属性是降级情况下使用的value
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
// ...
}
// 子组件注入 'foo'
var Child = {
inject: ['foo'],
created () {
console.log(this.foo) // => "bar"
}
// ...
}
// 利用 `ES2015 Symbols`、函数 `provide` 和对象 `inject`
const s = Symbol()
const Provider = {
provide () {
return {
[s]: 'foo'
}
}
}
const Child = {
inject: { s },
// ...
}
//设置默认值
const Child = {
inject: {
foo: { default: 'foo' }
}
}
// 如果它需要从一个不同名字的 property 注入,则使用 from 来表示其源 property:
const Child = {
inject: {
foo: {
from: 'bar',
default: 'foo'
}
}
}
// 对非原始值使用一个工厂方法:
const Child = {
inject: {
foo: {
from: 'bar',
default: () => [1, 2, 3]
}
}
}
// 使用一个注入的值作为一个 property 的默认值:
const Child = {
inject: ['foo'],
props: {
bar: {
default () {
return this.foo
}
}
}
}
// 使用一个注入的值作为数据入口:
const Child = {
inject: ['foo'],
data () {
return {
bar: this.foo
}
}
}
注意点:
如果
provide
里的属性要使用组件实例中的数据,则必需使用函数的形式,如果只是静态数据则可以使用对象的形式如果希望
provide
是响应式的,即子组件能跟着父组件的provide
变化而变化,那么provide
的值需要是一个对象,那么这个对象里的属性将是可更新官方解释:
provide
和inject
绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的
通信范围:父传子,且可多层
# 跨组件通过
# eventBus
eventBus
又称为事件总线,在 Vue 中可以使用它来作为沟通桥梁的概念, 就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所以组件都可以通知其他组件
// 初始化一个事件总线 event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
// 发送事件
import {EventBus} from './event-bus.js'
EventBus.$emit('addition', {})
// 接收事件
import {EventBus} from './event-bus.js'
EventBus.$on('addition', param => {})
// 移除事件总线
mport { EventBus } from './event-bus.js'
EventBus.$off('addition', {})
//移除所有事件总线
EventBus.$off()
适合范围:任意位置的组件,可跨级
# VueX
# 获取组件实例
通过获取组件实例的方式来访问这个实例中的属性和方法
# ref/$refs
ref
被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs
对象上。
如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素
如果用在子组件上,引用就指向组件实例
<!-- `vm.$refs.p` will be the DOM node -->
<p ref="p">hello</p>
<!-- `vm.$refs.child` will be the child hllComponent instance -->
<child-component ref="child"></child-component>
注意点
如果有同名的
ref
定义,则这个ref
指向最后渲染出来的那个// 初始时 show=false <p ref="hi" v-if="show">hi</p> <p ref="hi">hello</p> // moutned 钩子中打印 this.$refs.hi // <p ref="hi">hello</p> this.show = true this.$refs.hi // <p ref="hi" v-if="show">hi</p> this.show = false // 销毁 dom 后,这个 refs.hi 并不会赋值成其它名为 `hi` 的元素,而是等于 undefind this.$refs.hi // undefind
当
v-for
用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组<span v-for="(item) in list" ref="hi">{{item}}</span> // this.$refs.hi // [<span>, ...]
# $children/$parent
$children
:当前组件包含的子组件实例数组。需要注意$children
并不保证顺序,也不是响应式的。$parent
: 当前组件对应的父组件实例
使用 $children
和 $parent
要注意的点
边界情况,如在
#app
上拿$parent
得到的是new Vue()
的实例,在这实例上再拿$parent
得到的是undefined
在最底层的子组件拿
$children
是个空数组也要注意得到
$parent
和$children
的值不一样,$children
的值是数组,而$parent
是个对象
适合范围:相临父子组件
# 其它
# $attrs/$listeners
$listeners
: 包含了父作用域中的 (不含.native
修饰器的)v-on
事件监听器。它可以通过v-on="$listeners"
传入内部组件——在创建更高层次的组件时非常有用$attrs
: 包含了父作用域中不作为prop
被识别 (且获取) 的attribute
绑定 (class
和style
除外)。当一个组件没有声明任何prop
时, 这里会包含所有父作用域的绑定 (class
和style
除外),并且可以通过v-bind="$attrs"
传入内部组件——在创建高级别的组件时非常有
// 父组中
<com
name="lanjz"
class="com"
age="18"
@click="callback"
v-on:event-one="callback"
v-on:event-two="callback"
/>
// com组件
mounted() {
console.log(this.$attrs) // {age: "18", name: "lanjz"}
console.log(this.$listeners) // {click: ƒ invoker(), event-one:ƒ invoker(),event-two: ƒ invoker()}
}