vue3的组件通信
1: v-model实现vue的通信
A组件
<template>
<h1>我是父组件--{{title}}</h1>
<hr>
<B v-model="title"></B>
</template>
<script setup>
import { ref } from 'vue'
import B from "./components/B.vue";
let title = ref("张三")
</script>
<style>
</style>
B组件
<template>
<div class="hello">
<h1>我是子组件--{{title}}</h1>
<button @click="mutateParentTitle">修改父组件的title值</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
modelValue:String
})
const title = ref(props.modelValue)
const emit = defineEmits(["update:modelValue"])
const mutateParentTitle = ()=>{
title.value = title.value == '张三' ? '李四' : '张三'
emit("update:modelValue",title.value)
}
</script>
<style scoped>
</style>
2: provide和inject
<template>
<h1>我是父组件--{{title}}</h1>
<hr>
<B ></B>
</template>
<script setup>
import { ref,provide } from 'vue'
import B from "./components/B.vue";
let title = ref("张三")
provide("sendTitle",title.value)
</script>
<style>
</style>
<template>
<div class="hello">
<h1>我是子组件--{{title}}</h1>
</div>
</template>
<script setup>
import { ref,inject } from 'vue'
const title = inject("sendTitle")
</script>
<style scoped>
</style>
3: pinia(vuex5版本)
main.js(yarn add -D pinia)
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
let app = createApp(App)
app.use(pinia)
app.mount('#app')
新建store,新建count.js和index.js
import { defineStore } from 'pinia'
// 定义 Store, 命名建议: useXxxxStore
// 参数1:Store 的唯一标识
// 参数2:配置对象,可以提供 state actions getters
const useCounterStore = defineStore('counter', {
// 相当于组件 data
state() {
return {
count: 0,
}
},
// 相当于组件 computed
getters: {
double() {
console.log(this) // 代表实例化的pinia
return this.count * 2
},
},
// 相当于组件 methods 在 pinia中 没有mutations,只有 actions,不管是同步还是异步的代码,都可以在actions中完成。
actions: {
add() {
this.count++
},
addAsync() {
setTimeout(() => {
this.count++
}, 1000)
},
},
})
// 导出 Store
export default useCounterStore
import useCounterStore from './count'
// 统一导出 useStore 方法
export default function useStore() {
return {
counter: useCounterStore(),
}
}
<template>
<h1>轻量状态管理库 Pinia</h1>>
<hr>
<h1>解构pinia如何得到响应式数据-storeToRefs</h1>
<h1>{{ count }}</h1>
<h3>{{ double }}</h3>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import useStore from './store/index.js'
// 使用 Store
const { counter } = useStore()
// storeToRefs 的使用 如果直接从pinia中解构数据,会丢失响应式, 使用storeToRefs可以保证解构出来的数据也是响应式的
const { count, double } = storeToRefs(counter)
</script>
<style>
</style>
4: emit组件通信
-子组件
<template>
<div class="home">
<button @click="mutateHandler">修改父组件的值</button>
</div>
</template>
<script setup>
const emit = defineEmits(['myClick'])
const mutateHandler = () =>{
emit("myClick",222)
}
</script>
-父组件
<template>
{{title}}
<Home @click="myClick"></Home>
</template>
<script setup>
// @ is an alias to /src
import Home from '@/views/HomeView.vue'
import { ref } from 'vue'
const title = ref("张三")
const myClick = ()=>{
title.value = "李四"
}
</script>
<style>
</style>
5: bus组件通信
- bus.js
import mitt from 'mitt'
const bus = mitt()
export default bus
-组件A
<template>
{{title}}
<Home @click="myClick"></Home>
<button @click="busEmit">bus组件通信</button>
</template>
<script setup>
// @ is an alias to /src
import Home from '@/views/HomeView.vue'
import bus from '@/utils/bus.js'
import { ref } from 'vue'
const busEmit = ()=>{
console.log("this",this)
bus.emit('busEmit', "你好");
}
</script>
-组件B
<template>
<div class="home">
<button @click="mutateHandler">修改父组件的值</button>
</div>
</template>
<script setup>
import { onMounted,onBeforeUnmount } from 'vue';
import bus from '@/utils/bus.js'
onMounted(()=>{
bus.on('busEmit', (data) => {
console.log("data====",data)
});
})
onBeforeUnmount(()=>{
bus.off('busEmit');
})
</script>
6:ref通信
-组件A
<template>
<div class="home">
<button>我是Home组件的标题{{title}}</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const title = ref("小张三")
const mutateHandler = ()=>{
title.value = "小李四"
}
defineExpose({
mutateHandler
})
</script>
-组件B
<template>
<Home ref="children"></Home>
<button @click="myClick">修改Home组件的title</button>
</template>
<script setup>
import Home from '@/views/HomeView.vue'
import { ref } from 'vue'
const children = ref(null)
const myClick = ()=>{
children.value.mutateHandler()
}
</script>
7: props通信
-组件A
<template>
<Home :title="title"></Home>
</template>
<script setup>
import Home from '@/views/HomeView.vue'
import { ref } from 'vue'
const title = ref("张三")
</script>
-组件Home
<template>
<div class="home">
<button>我是子组件的标题{{title}}</button>
</div>
</template>
<script setup>
defineProps({
title:{
type: String
}
})
</script>
未完待续~