目录
1.props和$emit
主要用于父子组件间通信,父组件向子组件传递数据是通过props传递的,子组件向父组件传递数据是通过$emit触发事件做到的
1)父组件向子组件传递数据(子组件通过props接收):
下面通过一个例子进行说明:
<!-- 父组件 -->
<template>
<div>
<Children1 :bookList="bookList"></Children1>
<Children2 :goods="goodList"></Children2>
</div>
</template>
<script>
import Children1 from './Children1.vue'
import Children2 from './Children2.vue'
export default {
name: 'Father',
components: { Children1, Children2 },
data () {
return {
bookList: ['重生', '红楼梦', '三国演义'],
goodList: ['雪花酥', '冰激淋', '草莓蛋糕']
}
}
}
</script>
<style>
</style>
<!-- 子组件 -->
<template>
<div>
<ul>
<li v-for="item in goods" :key="item.index">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Children2',
props: ['goods']//接受父组件传过来的goods,并进行遍历
}
</script>
<style>
</style>
说明:
在上面例子中,父组件需要先给需要传递数据的子组件绑定一个属性,属性值就是要传的数据,并且要在父组件中引入子组件。子组件通过props属性接收父组件传过来的值
2)子组件向父组件传递数据
$emit绑定一个自定义事件, 当这个语句被执行时, 就会将参数传递给父组件,父组件通过v-on监听并接收参数。
下面通过一个例子进行说明:
<!-- 父组件 -->
<template>
<div>
<Children1 :bookList="bookList" @message="message"></Children1>
<Children2 :goods="goodList"></Children2>
</div>
</template>
<script>
import Children1 from './Children1.vue'
import Children2 from './Children2.vue'
export default {
name: 'Father',
components: { Children1, Children2 },
data () {
return {
message1: '',
bookList: ['重生', '红楼梦', '三国演义'],
goodList: ['雪花酥', '冰激淋', '草莓蛋糕']
}
},
methods: {
message (recieveMessage) { // 获取子组件传来的数据
console.log('recieveMessage', recieveMessage)
}
}
}
</script>
<style>
</style>
<template>
<div>
<div v-for="item in bookList" :key="item.index">
{{item}}
</div>
<Button @click="handleClick">发送数据</Button>
</div>
</template>
<script>
export default {
name: 'Children1',
props: ['bookList'],
methods: {
handleClick () {
this.$emit('message', '冰冰')// 向父组件发射数据obj
}
}
}
</script>
<style>
</style>
说明:
在上面例子中,子组件通过$emit绑定一个自定义事件,并携带需要传递给父组件的数据,父组件通过v-on绑定该事件来监听子组件的触发事件
2.全局事件总线
本质上是自定义事件,只不过是给$bus绑定的事件,当然当前的$bus就是vm.
是一种组件间通信的方式,适用于任意组件间通信
1.安装全局事件总线
首先在main.js里面注册全局事件总线
new Vue({
el: '#app',
router,
i18n,
store,
//安装全局事件总线
beforeCreate()
{
Vue.prototype.$bus=this
},
render: h => h(App)
})
2.使用全局事件总线
1)接收数据,通过this.$bus.$on('事件名称',回调)
created () {
// 接收数据
// 或直接使用回调函数,切记是箭头函数,不然this不是当前组件
this.$bus.$on('data', (msg) => {
console.log('收到了数据', msg)
this.info = msg
})
}
2)提供数据,this.$bus.$emit('xxxx',数据)
3)最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件
实例代码:
busPage.vue(提供数据):
<template>
<div>Bus 提供数据 <Button type="primary" @click="givemessage">提供数据</Button></div>
</template>
<script>
export default {
name: 'busPage',
data () {
return {
info: {
name: '王俊凯',
age: 23
}
}
},
methods: {
givemessage () {
// 调用事件,发送数据
this.$bus.$emit('data', this.info)
console.log('发送了数据', this.info)
}
}
}
</script>
<style>
</style>
dataAnalysis.vue(接收数据):
<template>
<div>
接收到的数据: {{this.info}}
</div>
</template>
<script>
export default {
name: 'dataAnalysis',
data () {
return {
info: {}
}
},
created () {
// 接收数据
// 或直接使用回调函数,切记是箭头函数,不然this不是当前组件
this.$bus.$on('data', (msg) => {
console.log('收到了数据', msg)
this.info = msg
})
},
beforeDestroy () {
// 组件即将销毁时,解绑事件
this.$bus.$off('data')
}
}
</script>
<style>
</style>
3.v-model
为了实现数据的双向传递,即在父组件中更新,子组件会立即更新;在子组件中修改了值,父组件也会立即更新,此时v-model就可以实现这种需求,使用v-model的过程中,父组件我们还是需要正常将子组件引入,只是传值的方式变成了v-model
示例说明:
父组件:
<template>
<data-analysis v-model="fatherText"></data-analysis>
<p>这里显示的是父组件的fatherText值:{{this.fatherText}}</p>
</div>
</template>
<script>
import dataAnalysis from '../dataAnalysis/index.vue'
export default {
name: 'busPage',
components: {dataAnalysis},
data () {
return {
fatherText: '今天天气真好'
}
}
}
</script>
<style>
</style>
子组件:
model默认情况下:
prop: 默认绑定的是value
event: 默认触发的事件类型是input
<template>
<div >
<span>这里显示子组件input的value1值</span>
<input type="text" :value="fatherText" @input="handleInput">
</div>
</template>
<script>
export default {
name: 'dataAnalysis',
model: {
prop: 'fatherText',
event: 'handleClick'
},
props: {
fatherText: {
type: String
}
},
data () {
return {
}
},
methods: {
handleInput (e) {
this.$emit('handleClick', e.target.value)
}
}
}
</script>
<style>
</style>
4.$parent和$children
使用 this.$parent查找当前组件的父组件。
使用 this.$children查找当前组件的直接子组件,可以遍历全部子组件, 需要注意 $children 并不保证顺序,也不是响应式的。使用 this.$root查找根组件,并可以配合$children遍历全部组件。
使用 this.$refs查找命名子组件。
示例说明:
父组件:
busPage.vue:
<template>
<div>
{{msg}}
<data-analysis ref="dataAnalysis"></data-analysis>
<regional-manage ref="regionalManage"></regional-manage>
</div>
</template>
<script>
import dataAnalysis from '../dataAnalysis/index.vue'
import regionalManage from '../regionalManage/index.vue'
export default {
name: 'busPage',
components: {dataAnalysis, regionalManage},
data () {
return {
msg: '今天天气真好',
message: 'busPage'
}
},
mounted () {
console.log(this.$children[0].message)// dataAnalysis(读取子组件时,this.$children子组件的排序是不安全的)
console.log(this.$refs.regionalManage.message)// regionalManage(读取命名子组件数据)
console.log(this.$root.$children[0].message)// App组件
console.log(this.$root.$children[0].$children[0].message)
},
methods: {
}
}
</script>
<style>
</style>
子组件1:
dataAnalysis.vue:
<template>
<div >
数据统计分析
这是读取父组件中的数据:{{msg}}
</div>
</template>
<script>
// import regionalManage from '../regionalManage/index.vue'
export default {
name: 'dataAnalysis',
data () {
return {
message: 'dataAnalysis',
msg: ''
}
},
methods: {
},
created () {
this.msg = this.$parent.message
},
beforeDestroy () {
}
}
</script>
<style>
</style>
子组件2:
regionalManage.vue:
<template>
<div>
风险地区
</div>
</template>
<script>
export default {
name: 'regionalManage',
data () {
return {
message: 'regionalManage'
}
}
}
</script>
<style>
</style>
5.vuex
vuex比较重要,在另一篇笔记中单独说明