组件通信
1. 父子组件
a. 通过发送和接受消息
父组件
例如
通过v-bind或:实现把父组件的数据传给子组件
通过v-on或@,实现监听子组件事件和接收数据
<son :uname="uname" @update-uname="uname = $event"></son>
子组件
例如
export default {
//通过props接收父组件传过来的数据
props: ['uname'],
methods: {
handle(){
//通过$emit触发事件,发送数据给父组件
this.$emit('update-uname','ls')
}
}
}
语法糖
v-model
父组件
<son v-model="uname"></son>
子组件
export default {
props: ['value'],
methods: {
handle(){
this.$emit('input','ls')
}
}
}
.sync
父组件
<son :uname.sync="uname"></son>
子组件
export default {
props: ['uname'],
methods: {
handle(){
this.$emit('update:uname','ls')
}
}
}
b.通过组件实例直接通信
父->子
通过ref和$refs
<template>
<son ref="sonRef"></son>
</template>
<script>
export default = {
methods: {
handle(){
this.$refs.sonRef.uname //访问数据
this.$refs.sonRef.updateUname('ls')//访问方法
}
}
}
</script>
子->父
通过$parent
export default {
methods: {
handle(){
this.$parent.uname //访问数据
this.$parent.upateUname('ls') //访问方法
}
}
}
2. 兄弟组件
a通过事件中心
事件中心
例如
import Vue from 'vue'
const eventBus = new Vue()
export funtion on(eventName, fn){
eventBus.$on(eventName, fn)
}
export funtion emit(eventName, data){
eventBus.$emit(eventName, data)
}
兄弟A
例如
import {emit} from '@/utils/eventBus.js'
export default {
methods: {
handle(){
//发消息
emit('add-success', 4)
}
}
}
兄弟B
例如
import {on} from '@/utils/eventBus.js'
export default {
data(){
return {
list: [1,2,3]
}
},
mounted(){
//接受消息
on('add-success', function(data){
this.list.push(data)
})
}
}
b.通过父组件通信(通过消息和直接通信)
父组件
例如
<template>
<son-a @add-success="handle"><son-a>
<son-b ref="sonbRef"><son-b>
</template>
<script>
export defalut {
methods: {
handle(data){
//父组件之间操作子组件实例实现通信
this.$refs.sonbRef.list.push(data)
}
}
}
</script>
兄弟A
例如
export default {
methods: {
handle(){
//发消息
this.$emit('add-success', 4)
}
}
}
兄弟B
例如
export default {
data(){
return {
list: [1,2,3]
}
}
}
c.通过父组件通信(通过消息)
父组件
例如
<template>
<son-a @add-success="handle"><son-a>
<son-b :list="list"><son-b>
</template>
<script>
export defalut {
data(){
list: []
},
methods: {
handle(data){
//父子组件通过数据绑定实现通信
this.list.push(data)
}
}
}
</script>
兄弟A
例如
export default {
methods: {
handle(){
//发消息
this.$emit('add-success', 4)
}
}
}
兄弟B
例如
export default {
props: {
//通过props接收父组件传过来的数据
list: {
type: Array,
default: ()=>[]
}
}
}
d.通过插槽
父组件
<template>
<son-a><button @click="handle(4)">add</button><son-a>
<son-b :list="list"><son-b>
</template>
<script>
export defalut {
data(){
return {
list: [1,2,3]
}
},
methods: {
handle(data){
//父组件之间操作子组件实例实现通信
this.list.push(data)
}
}
}
</script>
兄弟A
例如
<template>
<div class="son-a">
<slot></slot>
</div>
</template>
兄弟B
例如
export default {
props: {
//通过props接收父组件传过来的数据
list: {
type: Array,
default: ()=>[]
}
}
}
3. 爷孙组件
a.通过父子通信
<body>
<div id="app">
<grand-father></grand-father>
</div>
</body>
<script>
// 爷爷组件
Vue.component('grand-father', {
data() {
return {
money: 1000
}
},
template: `
<div>
<div>爷爷</div>
<father :money="money" @pay="money-=$event"/>
</div>
`
})
// 父亲组件
Vue.component('father', {
props: ['money'],
template: `
<div>
<div>父亲</div>
<son :money="money" @pay="$emit('pay',$event)"/>
</div>
`
})
// 孙子组件
Vue.component('son', {
props: ['money'],
template: `
<div>
<div>孙子-{{money}}</div>
<button @click="$emit('pay', 100)">-100</button>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
},
methods: {
},
mounted() {
},
})
b.通过$parent
<body>
<div id="app">
<grand-father></grand-father>
</div>
</body>
<script>
// 爷爷组件
Vue.component('grand-father', {
data() {
return {
money: 1000
}
},
template: `
<div>
<div>爷爷</div>
<father ref="father"/>
</div>
`,
methods: {
pay(num){
if(this.money>num){
this.money -= num
}
}
}
})
// 父亲组件
Vue.component('father', {
template: `
<div>
<div>父亲</div>
<son/>
</div>
`
})
// 孙子组件
Vue.component('son', {
template: `
<div>
<div>孙子-{{$parent.$parent.money}}</div>
<!--可以,但是不要做-->
<!--<button @click="$parent.$parent.money-=100">-100</button>-->
<button @click="$parent.$parent.pay(100)">-100</button>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
},
methods: {
},
mounted() {
},
})
</script>
c.通过provide和inject
<body>
<div id="app">
<grand-father></grand-father>
</div>
</body>
<script>
// 爷爷组件
Vue.component('grand-father', {
data() {
return {
money: 1000
}
},
provide(){
return {
grandFather: this
}
},
template: `
<div>
<div>爷爷</div>
<father/>
</div>
`,
methods: {
pay(num){
if(this.money>num){
this.money -= num
}
}
}
})
// 父亲组件
Vue.component('father', {
template: `
<div>
<div>父亲</div>
<son/>
</div>
`
})
// 孙子组件
Vue.component('son', {
inject: ['grandFather'],
mounted() {
},
template: `
<div>
<div>孙子-{{grandFather.money}}</div>
<button @click="grandFather.pay(100)">-100</button>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
},
methods: {
},
mounted() {
},
})
</script>
4. 没关系组件
通过vuex
定义store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// 定义数据
state: {
count: 0
},
// 同步代码
mutations: {
addCount (state) {
state.count++
},
//接受参数
addCountN (state, payload) {
state.count += payload
}
},
// 异步代码
actions: {
addCountSync (context) {
setTimeout(() => {
context.commit('addCount')
}, 1000)
},
// 接受参数
addCountNSync (context, payload) {
setTimeout(() => {
context.commit('addCountN', payload)
}, 1000)
}
},
// 计算属性
getters: {
showCount (state) {
return `当前的count值=${state.count}`
},
// 简化模块中state的获取
token (state) {
return state.user.token
}
},
// 模块化
modules: {
user: {
// 命名空间
namespaced: true,
state: {
token: 'abc'
},
mutations: {
updateToken () {
console.log('2')
}
}
}
}
})
访问state
标准写法
<div>{{$store.state.count}}</div>
简化写法
<template>
<div>{{count}}</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
computed: {
...mapState(['count'])
}
}
</script>
访问mutations
标准写法
<button @click="$store.commit('addCount')">+1</button>
<button @click="$store.commit('addCountN', 3)">+N</button>
简化写法
<template>
<div>
<button @click="addCount">+1</button>
<button @click="addCountN(3)">+N</button>
</div>
</template>
<script>
import {mapMutations} from 'vuex'
export default {
methods: {
...mapMutations(['addCount', 'addCountN'])
}
}
</script>
访问actions
标准写法
<button @click="$store.dispatch('addCountSync')">+1 sync</button>
<button @click="$store.dispatch('addCountNSync', 3)">+N sync</button>
简化写法
<template>
<div>
<button @click="addCountSync">+1 sync</button>
<button @click="addCountNSync(3)">+N sync</button>
</div>
</template>
<script>
import {mapActions} from 'vuex'
export default {
methods: {
...mapActions(['addCountSync', 'addCountNSync']),
}
}
</script>
访问getters
标准写法
<div>{{$store.getters.showCount}}</div>
简化写法
<template>
<div>{{showCount}}</div>
</template>
<script>
import {mapActions} from 'vuex'
export default {
computed: {
...mapGetters(['showCount'])
},
}
</script>
访问模块state
标准写法
<div>token={{$store.state.user.token}}</div>
简化写法
<template>
<div>{{token}}</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['token'])
}
}
</script>
访问模块mutations
标准写法
<button @click="$store.commit('user/updateToken')">updateToken</button>
简化写法
通过mapMutations('命令空间名/mutations名')
<template>
<button @click="()=>this['user/updateToken']()">updateToken</button>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations(['user/updateToken'])
}
}
</script>
通过mapMutations('命令空间名',['mutations名'])
<template>
<button @click="updateToken">updateToken</button>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations('user', ['updateToken']),
}
}
</script>
通过createNamespacedHelpers
<template>
<button @click="updateToken">updateToken</button>
</template>
<script>
import { createNamespacedHelpers } from 'vuex'
const { mapMutations } = createNamespacedHelpers('user')
export default {
methods: {
...mapMutations(['updateToken'])
}
}
</script>
本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。
在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。
本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。
除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。
在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!