本文主要是介绍Vue09 五一前 组件通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
store组合式写法
count.ts组合式写法
import { reactive } from 'vue'
export const useLoveTalkStore = defineStore('talk', () => {const talkList = reactive(JSON.parse(localStorage.getItem('talkList') as string) || [])//getATalk函数相当于actionasync function getATalk() {//发请求,下面这行写法是:连续解构+重命名let { data: { content: title } } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')// //把请求回来的字符,包装成一个对象let obj = { id: nanoid(), title } //简单写成title:content 上面let可以result改成 {data:{content}};还可以进一步 title {data:{content:title}}// //放到数组中talkList.unshift(obj)}//必须有return,不然无效return { talkList, getATalk }
})
选项式写法
import { defineStore } from 'pinia'
import axios from 'axios'
import { nanoid } from 'nanoid'export const useLoveTalkStore = defineStore('talk', {actions: {async getATalk() {//发请求,下面这行写法是:连续解构+重命名let { data: { content: title } } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')// //把请求回来的字符,包装成一个对象let obj = { id: nanoid(), title } //简单写成title:content 上面let可以result改成 {data:{content}};还可以进一步 title {data:{content:title}}// //放到数组中this.talkList.unshift(obj)}},//state真正存储数据的地方state() {return {talkList: JSON.parse(localStorage.getItem('talkList') as string) || []// talkList: [// { id: 'ftrfasdf01', title: '今天天气好' },// { id: 'ftrfasdf02', title: '今天天气好2' },// { id: 'ftrfasdf03', title: '今天天气好3' }// ]}}
})
组件通信_方式1_props
- 父传子:属性值是非函数
<template><div class="father"><h3>父组件</h3><h4>汽车:{{ car }}</h4><!-- 传递,子需要接收 --><Child :car="car" :sendToy="getToy"/></div>
</template>
子组件需要接收
<script setup lang="ts" name="Child">import {ref} from 'vue'// 数据let toy = ref('奥特曼')// 声明接收propsdefineProps(['car','sendToy'])
</script>
- 子传父:属性值是函数
<template><div class="father"><h3>父组件</h3><h4>汽车:{{ car }}</h4><!-- v-show、v-if条件渲染 不传递参数就不显示 --><h4 v-show="toy">子给的玩具:{{ toy }}</h4><Child :car="car" :sendToy="getToy"/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref} from 'vue'// 数据let car = ref('奔驰')let toy = ref('')// 方法function getToy(value:string){toy.value = value}
</script>
<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><h4>父给的车:{{ car }}</h4><button @click="sendToy(toy)">把玩具给父亲</button></div>
</template><script setup lang="ts" name="Child">import {ref} from 'vue'// 数据let toy = ref('奥特曼')// 声明接收propsdefineProps(['car','sendToy'])
</script>
组件通信_方式2__自定义事件
<template><div class="father"><h3>父组件</h3><h4>{{ str }}</h4><button @click="test">点我</button><!-- 给子组件Child绑定事件 --><Child/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import { ref } from "vue";// 数据let str = ref('你好')function test() {str.value = '哈哈'}
</script>
可以简化写法
<template><div class="father"><h3>父组件</h3><h4>{{ str }}</h4><button @click="str = '哈哈'">点我</button><!-- 给子组件Child绑定事件 --><Child/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import { ref } from "vue";// 数据let str = ref('你好')
</script>
$seven 特殊占位符 这是一个事件对象
<template><div class="father"><h3>父组件</h3><h4>{{ str }}</h4><button @click="str = $event">点我</button><!-- 给子组件Child绑定事件 --><Child/></div>
</template>
子传父
<template><div class="father"><h3>父组件</h3><h4 v-show="toy">子给的玩具:{{ toy }}</h4><!-- 给子组件Child绑定事件 --><Child @send-toy="saveToy"/></div>
</template>
<Child @send-toy=“saveToy”/>
给组件绑定send-toy事件,只要这个事件被触发,saveToy就会被调用
如何触发事件
需要在子组件里面声明,用一个宏函数,defineEmits
还需要加上emit。这个可以放在任何想要触发的地方
<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><button @click="emit('send-toy',toy)">测试</button></div>
</template><script setup lang="ts" name="Child">import { ref } from "vue";// 数据let toy = ref('奥特曼')// 声明事件const emit = defineEmits(['send-toy'])// onMounted(() => {// setTimeout(() => {// emit('send-toy')// }, 3000);// })
</script>
案例
父组件
<template><div class="father"><h3>父组件</h3><h4 v-show="toy">子给的玩具:{{ toy }}</h4><!-- 给子组件Child绑定事件 --><Child @send-toy="saveToy"/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import { ref } from "vue";// 数据let toy = ref('')// 用于保存传递过来的玩具function saveToy(value:string){console.log('saveToy',value)toy.value = value}
</script>
子组件
<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><button @click="emit('send-toy',toy)">测试</button></div>
</template><script setup lang="ts" name="Child">import { ref } from "vue";// 数据let toy = ref('奥特曼')// 声明事件const emit = defineEmits(['send-toy'])
</script>
组件通信_方式3__mitt
pubsub
$bus
mitt
接收数据:提前绑定好事件(提前订阅事件)
提供数据:在合适的时候触发事件(发布消息)
案例
哥哥传递玩具给弟弟
<template><div class="child1"><h3>子组件1</h3><h4>玩具:{{ toy }}</h4><button @click="emitter.emit('send-toy',toy)">玩具给弟弟</button></div>
</template><script setup lang="ts" name="Child1">import {ref} from 'vue'import emitter from '@/utils/emitter';// 数据let toy = ref('奥特曼')
</script>
<template><div class="child2"><h3>子组件2</h3><h4>电脑:{{ computer }}</h4><h4>哥哥给的玩具:{{ toy }}</h4></div>
</template><script setup lang="ts" name="Child2">import {ref,onUnmounted} from 'vue'import emitter from '@/utils/emitter';// 数据let computer = ref('联想')let toy = ref('')// 给emitter绑定send-toy事件emitter.on('send-toy',(value:any)=>{toy.value = value})// 在组件卸载时解绑send-toy事件;对内存友好onUnmounted(()=>{emitter.off('send-toy')})
</script>
组件通信_方式4__v-model
双向绑定
v-model用在html标签上
<template><div class="father"><h3>父组件</h3><!-- v-model用在html标签上 --><!-- <input type="text" v-model="username"> --><!-- :value数据来到页面,@input页面来到数据 --><input type="text" :value="username" @input="username = (<HTMLInputElement>$event.target).value"></div>
</template>
v-model用在组件标签上
father.Vue
<template><div class="father"><h3>父组件</h3><!-- v-model用在组件标签上 --><AtguiguInput v-model="username"/><!-- <AtguiguInput :modelValue="username" @update:modelValue="username = $event"/> --></div>
</template><script setup lang="ts" name="Father">import { ref } from "vue";import AtguiguInput from './AtguiguInput.vue'// 数据let username = ref('zhansgan')
</script>
<template><input type="text" :value="modelValue"@input="emit('update:modelValue',(<HTMLInputElement>$event.target).value)">
</template><script setup lang="ts" name="AtguiguInput">defineProps(['modelValue'])const emit = defineEmits(['update:modelValue')
</script>
$event到底是什么,什么时候可以用.target
对于原生事件,$event就是事件对象——能.target
对于自定义事件,$event就是触发事件时,所传递的数据——不能.target
组件通信_v-model的细节
update:modelValue名称太长 可以更改名字
如果value可以更换,可以再组件标签上多次使用v-model
<template><div class="father"><h3>父组件</h3><h4>{{ username }}</h4><h4>{{ password }}</h4> <!-- 修改modelValue --><AtguiguInput v-model:ming="username" v-model:mima="password"/></div>
</template><script setup lang="ts" name="Father">import { ref } from "vue";import AtguiguInput from './AtguiguInput.vue'// 数据let username = ref('zhansgan')let password = ref('123456')
</script>
组件
<template><input type="text" :value="ming"@input="emit('update:ming',(<HTMLInputElement>$event.target).value)"><br><input type="text" :value="mima"@input="emit('update:mima',(<HTMLInputElement>$event.target).value)">
</template><script setup lang="ts" name="AtguiguInput">defineProps(['ming','mima'])const emit = defineEmits(['update:ming','update:mima'])
</script>
组件通信_方式5__$attrs
概念:$attrs用于实现当前组件的父组件,向当前组件的子组件的通信(祖—孙)
祖-孙
father.vue
<template><div class="father"><h3>父组件</h3><h4>a:{{a}}</h4><h4>b:{{b}}</h4><h4>c:{{c}}</h4><h4>d:{{d}}</h4><Child :a="a" :b="b" :c="c" :d="d" v-bind="{x:100,y:200}" /></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref} from 'vue'let a = ref(1)let b = ref(2)let c = ref(3)let d = ref(4)</script>
child.vue 把祖所有值都传递给孙
<template><div class="child"><h3>子组件</h3><!-- <h4>a:{{ a }}</h4><h4>其他:{{ $attrs }}</h4> --><GrandChild v-bind="$attrs"/></div>
</template><script setup lang="ts" name="Child">import GrandChild from './GrandChild.vue'// defineProps(['a'])
</script>
grandchild.vue
<template><div class="grand-child"><h3>孙组件</h3><h4>a:{{ a }}</h4><h4>b:{{ b }}</h4><h4>c:{{ c }}</h4><h4>d:{{ d }}</h4><h4>x:{{ x }}</h4><h4>y:{{ y }}</h4></div>
</template><script setup lang="ts" name="GrandChild">defineProps(['a','b','c','d','x','y'])
</script>
孙-组
father.vue
<template><div class="father"><h3>父组件</h3><h4>a:{{a}}</h4><Child :a="a" :updateA="updateA"/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref} from 'vue'let a = ref(1)function updateA(value:number){a.value += value}
</script>
grandchild.vue
<template><div class="grand-child"><h3>孙组件</h3><h4>a:{{ a }}</h4><button @click="updateA(6)">点我将爷爷那的a更新</button></div>
</template><script setup lang="ts" name="GrandChild">defineProps(['a','updateA'])
</script>
组件通信_方式6__ r e f s 与 refs与 refs与parent
father.vue
<template><div class="father"><h3>父组件</h3><h4>房产:{{ house }}</h4><button @click="changeToy">修改Child1的玩具</button><button @click="changeComputer">修改Child2的电脑</button><button @click="getAllChild($refs)">让所有孩子的书变多</button><Child1 ref="c1"/><Child2 ref="c2"/></div>
</template><script setup lang="ts" name="Father">import Child1 from './Child1.vue'import Child2 from './Child2.vue'import { ref,reactive } from "vue";let c1 = ref()let c2 = ref()// 数据let house = ref(4)// 方法function changeToy(){c1.value.toy = '小猪佩奇'}function changeComputer(){c2.value.computer = '华为'}function getAllChild(refs:{[key:string]:any}){console.log(refs)for (let key in refs){refs[key].book += 3}}// 向外部提供数据defineExpose({house})
</script>
child1.vue
<template><div class="child1"><h3>子组件1</h3><h4>玩具:{{ toy }}</h4><h4>书籍:{{ book }} 本</h4><button @click="minusHouse($parent)">干掉父亲的一套房产</button></div>
</template><script setup lang="ts" name="Child1">import { ref } from "vue";// 数据let toy = ref('奥特曼')let book = ref(3)// 方法function minusHouse(parent:any){parent.house -= 1}// 把数据交给外部defineExpose({toy,book})</script>
child2.vue
<template><div class="child2"><h3>子组件2</h3><h4>电脑:{{ computer }}</h4><h4>书籍:{{ book }} 本</h4></div>
</template><script setup lang="ts" name="Child2">import { ref } from "vue";// 数据let computer = ref('联想')let book = ref(6)// 把数据交给外部defineExpose({computer,book})
</script>
$refs 父传子
父得到子数据
<template><div class="father"><h3>父组件</h3><h4>房产:{{ house }}</h4><button @click="changeToy">修改Child1的玩具</button><button @click="getAllChild($refs)">让所有孩子的书变多</button><Child1 ref="c1"/></div>
</template><script setup lang="ts" name="Father">import Child1 from './Child1.vue'import Child2 from './Child2.vue'import { ref,reactive } from "vue";let c1 = ref()// 数据let house = ref(4)// 方法function changeToy(){c1.value.toy = '小猪佩奇'}function getAllChild(refs:{[key:string]:any}){for (let key in refs){refs[key].book += 3}}
</script>
子必须把数据传递出去
<script setup lang="ts" name="Child1">import { ref } from "vue";// 数据let toy = ref('奥特曼')let book = ref(3)// 把数据交给外部defineExpose({toy,book})</script>
$parent 子传父
<template><div class="child1"><h3>子组件1</h3><h4>玩具:{{ toy }}</h4><h4>书籍:{{ book }} 本</h4><button @click="minusHouse($parent)">干掉父亲的一套房产</button></div>
</template><script setup lang="ts" name="Child1">import { ref } from "vue";// 数据let toy = ref('奥特曼')let book = ref(3)// 方法function minusHouse(parent:any){parent.house -= 1}</script>
说明 | 属性 |
---|---|
$refs | 值为对象,包含所有被ref属性标识的DOM元素或组件实例 |
$parent | 值为对象,当前组件的父组件实例对象 |
一个注意点
<script setup lang="ts" name="Father">
// 注意点:当访问obj.c的时候,底层会自动读取value属性,因为c是在obj这个响应式对象中的let obj = reactive({a:1,b:2,c:ref(3)})let x = ref(4)console.log(obj.a)console.log(obj.b)console.log(obj.c) //自动拆包解包console.log(x) //这不是4
</script>
组件通信_方式7__provide_inject
如何不打扰儿子,直接传递给孙 区别attrs
father.vue
<template><div class="father"><h3>父组件</h3><h4>银子:{{ money }}万元</h4><h4>车子:一辆{{car.brand}}车,价值{{car.price}}万元</h4><Child/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref,reactive,provide} from 'vue'let money = ref(100)let car = reactive({brand:'奔驰',price:100})function updateMoney(value:number){money.value -= value}// 向后代提供数据 不能是money.value 否则传递的就是个数字 无法改变provide('moneyContext',{money,updateMoney})provide('car',car)</script>
GrandChild.vue
<template><div class="grand-child"><h3>我是孙组件</h3><h4>银子:{{ money }}</h4><h4>车子:一辆{{car.brand}}车,价值{{car.price}}万元</h4><button @click="updateMoney(6)">花爷爷的钱</button></div>
</template><script setup lang="ts" name="GrandChild">import { inject } from "vue";let {money,updateMoney} = inject('moneyContext',{money:0,updateMoney:(param:number)=>{}})let car = inject('car',{brand:'未知',price:0})
</script>
这篇关于Vue09 五一前 组件通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!