vue组件间通信
1、 props 和 $emit
props: 主要用在父组件向子组件传递信息的时候,它既可以传递基本类型的数据,也可以传递数组或对象等引用类型的数据,但对于js引用类型, 父子组件会使用同一个数据,比较容易造成数据的混乱。
$emit: 子组件通过自定义函数的方式向父组件返回信息
用法
<!--父组件-->
<template>
<div id="app">
<!--基本类型-->
<child :message='message' @childEmit='childEmit'></child>
<!--props为对象类型-->
<child :obj.sync='obj'></child>
</div>
</tempate>
<script>
export default {
data () {
return () {
message: '父传子信息',
obj: {
name: 'hehe',
age: 20
}
}
},
methods: {
childEmit (data) {
console.log('子组件传递上来的message', data)
}
}
}
</script>
<!--子组件-->
<template>
<div @click='up'></div>
</template>
<script>
export default {
// props 可以配置,自行查阅官方文档
props: {
message: {
type: String,
default: '默认值'
},
obj: {
type: Object,
// 当时引用类型的时候,default必须是函数
default () {
return {}
}
}
},
data () {
return {
message: '子组件自身的数据'
}
}
methods: {
up () {
// 传递基本类型数据
this.$emit('childEmit', this.message)
// 传递引用类型(也可以传递基本类型,只要想实现父子组件数据双向绑定)
this.$emit('update:obj', this.obj)
}
}
}
</script>
2、ref
主要功能
1. 将其绑定在某个标签上,可以获取该标签的DOM对象 2. 将其绑在子组件上,可以得到该组件的引用, 之后可以方便的操作子组件中的数据还是拿上面的程序举例子(以下只是父组件,子组件继续沿用上边的那个)
<!--父组件-->
<template>
<div id="app">
<!--基本类型-->
<child ref='child' @click='changeMessage'></child>
</div>
</tempate>
<script>
export default {
data () {
return () {}
},
methods: {
changeMessage () {
this.$refs.child.message1 = '直接修改子组件的数据'
}
}
}
</script>
3、routes 路由传参
路由传参主要分为两大类: 1. 编程式导航 2. 声明式导航
1. 编程式导航
this.$router.push({
name: '路由名称',
params: {
id: 'xxx'
}
}) // --> 路由名称/id
this.$router.push({
path: '路由路径',
query: {
id: 'xxx'
}
}) // -->/路由路径?id=xxx
2. 声明式导航
<router-link :to="{ name: 'news', params: {userId: 1111}}">click to news page</router-link>
<router-link :to="{ name: 'news', query: {userId: 1111}}">click to new page</router-link>
两者的主要区别在于显示在浏览器地址栏中的信息不一样, query代表参数,拼接在url的后面,类似于get请求时的请求接口地址。而params传递的参数是url的一部分。 上述1,2 中注释已经说明了
4、vueBus
我一直理解的vueBus是一个小型的vuex, 通过一个新的vue实例去完成各个组件间的信息通信。
用法
<!-- APP.vue -->
<template>
<div id="app">
<!-- 如下有两个兄弟组件-->
<brother-item1></brother-item1>
==============华丽的分割线========
<brother-item2></brother-item2>
</div>
</template>
// main.js
import Vue from 'vue'
// 定义一个vueBus实例
var eventBus = {
install (Vue, options) {
Vue.prototype.$bus = new Vue()
}
}
Vue.use(eventBus)
<!-- brother-item1 -->
<template>
<div>
<h1>我是兄弟组件1</h1>
<button @click="busOnClick1">我要去看我弟</button>
<button @click="busOnClick2">我要走了</button>
</div>
</template>
<script>
export default {
methods: {
busOnClick1: function () {
// vueBus 触发事件
this.$bus.$emit('sendMessage1', '哥哥来看你了')
},
busOnClick2: function () {
this.$bus.$emit('sendMessage2', '哥哥我要走了')
}
}
}
</script>
<!-- brother-item2 -->
<template>
<div>
<h1>我是兄弟组件2</h1>
<div>我在此接收我哥给我的数据: </div>
</div>
</template>
<script>
export default {
data () {
return {
message: ''
}
},
created () {
// vueBus绑定事件
this.$bus.$on('sendMessage1', (params) => {
this.message = params
})
this.$bus.$on('sendMessage2', params => {
this.message = params
})
},
beforeDestroy () {
// 页面销毁的时候需要解除事件
this.$bus.$off('sendMessage1')
this.$bus.$off('sendMessage2')
}
}
</script>
5、 vuex
6、 $attrs 和 $listeners 和 inheritAttrs
$attrs 包含了父作用域不作为prop被识别的特性绑定(style和class除外),当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定,并且可以通过 v-bind=”$attrs 传入内部组件——在创建更高层次的组件时非常有用。
$listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件——在创建更高层次的组件时非常有用。
inheritAttrs 默认值为true, 没有被子组件继承的父组件属性,不会当做特性展示在子组件根元素上面,即如果为true, 不是通过props传到子组件的属性,会自动当做普通属性绑定在子组件的根标签上,这对于深层的组件传递会产生不可预知的bug。
例子
<!--父组件-->
<template>
<div class="parent">
<child
:message='message'
placeholder='请输入账号'
aa='14'
@focus="handleInput">
</child>
</div>
</template>
<script>
import child from './child'
export default {
components: {
child
},
data () {
return {
message: '父元素信息',
placeholder: '子组件的placeholder'
}
},
methods: {
handleInput () {
console.log('父组件 handleInput')
}
}
}
</script>
<!--子组件-->
<template>
<div class="child">
<input type="text" v-bind="$attrs" v-on="$listeners">
</div>
</template>
<script>
export default {
inheritAttrs: false, // 如果不设置为false,则没有被子组件继承的父组件属性都会绑定在子组件根元素上
props: {
message: {
type: String,
default: ''
}
},
mounted () {
console.log('attrs', this.$attrs)
}
}
</script>