您的位置:首页 > 文旅 > 美景 > 网站部署_电脑如何下载网页视频文件_网络营销是什么_最新新闻热点话题

网站部署_电脑如何下载网页视频文件_网络营销是什么_最新新闻热点话题

2025/1/9 5:08:11 来源:https://blog.csdn.net/friend_ship/article/details/143475614  浏览:    关键词:网站部署_电脑如何下载网页视频文件_网络营销是什么_最新新闻热点话题
网站部署_电脑如何下载网页视频文件_网络营销是什么_最新新闻热点话题

组件的通信

父子组件通信

父子组件通信可以理解成:
父组件向子组件传值。
父组件调用子组件的方法。

子组件向父组件传值。
子组件调用父组件的方法。

1.props: 利用props属性实现父组件向子组件传值。

parent.vue文件


<template><div>父组件<!-- 子组件在不同的父组件中传递 --><children data="我是父组件传递的值" ></children><children data="我是父组件传递的值" :num="18"></children></div>
</template>
<script setup lang="ts">
import children from '@/components/children.vue'
</script>

children.vue 文件

<template><div>子组件:{{data}}<div>年龄: {{num}}</div></div>
</template>
<script lang="ts">
import { defineComponent } from "vue";export default defineComponent({name: 'children',props: {data: String,num: {type: Number,default: () => 20},}
})
</script>

props不仅可以传字符串、数字、数组、对象、boolean的值,在传递时props也可以定义数据校验,以此来限制接收的数据类型等。
父传子的方式形成了一个单向下行绑定,叫做单向数据流。父级props的更新也会向下流程到接收这个props的子组件中,触发对应的更新,但是反过来则不行。如果遇到确实需要改变props值的应用场合,则采用下面的解决方法:

children.vue文件

<template><div><div>必须被修改的值第一种:  {{myData}}</div><div>必须被修改的值第二种:  {{childData}}</div></div>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from "vue";export default defineComponent({name: 'children',props: {data: String,num: {type: Number,default: () => 20},},setup(props) {// 第一种const myData = ref(props.data)myData.value = '通过初始化的方式进行修改'// 第二种const childData = computed(() => {return props.data + '通过computed属性实现修改'})return {myData,childData}}
})
</script>

2. $refs: 利用$refs属性可以实现父组件调用子组件的方法。通常用于直接操作子组件,但不推荐用于数据传递。

Vue2的写法

    <refChild ref="childRef"></refChild>this.$refs.refChild?.childFn()

Vue3的写法
parent.vue文件

<template><div class="mt15">  $refs通信的子组件<refChild ref="compontentRef"></refChild></div>
</template>
<script lang="ts">
import refChild from '@/components/refChild.vue'
import { defineComponent, onMounted, ref } from 'vue'export default defineComponent({name: 'parent',components: {refChild},setup() {const compontentRef = ref(null)const getRefChild = () => {compontentRef.value?.childFn();}onMounted(() => {getRefChild();})return {compontentRef,getRefChild}}
})

refChild.vue文件

<template><div>$refs紫组件</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";export default defineComponent({name: 'refChild',setup(props, context) {const childFn = () => {console.log('fn的方法被调用')}// 第一种写法context.expose({ childFn: childFn })// 第二种写法 defineExpose不需要引入,直接使用// defineExpose({ childFn: childFn })}
})
</script>

3.slot: 通过插槽实现父组件向子组件传值。关于插槽

// 父组件<div><slotChild>默认传值的方式</slotChild></div>
// 子组件
<template><div><slot></slot></div>
</template>

4.$emit: 触发当前组件实例上的事件,可以理解成子组件触发了绑定在父组件上的自定义事件。

parent.vue文件

 <children data="我是父组件传递的值" :num="18" @fromGreet="fromGreet"></children>
import { defineComponent, onMounted, ref } from 'vue'
import children from '@/components/children.vue'
import refChild from '@/components/refChild.vue'
import slotChild from '@/components/slotChild.vue'export default defineComponent({name: 'parent',components: {children,},setup() {const fromGreet = (data) => {console.log('来自子组件的调用', data)}return {fromGreet}}
})

children.vue文件

<template><div>子组件:{{data}} <a-button type="primary" @click="greet">打招呼</a-button></div>
</template>
import { computed, defineComponent, ref } from "vue";export default defineComponent({name: 'children',props: {data: String,},setup(props, context) {const greet = () => {context.emit('fromGreet', 'hello')}return {greet}}
})

5.$parent: 在子组件直接获取父组件的实例,从而调用父组件中的方法,类似于$refs获取子组件的方法。

因Vue3的组合式API设计原则,应该尽量避免直接使用$parent,可能会导致组件之间的耦合度过高。推荐下面的实现方法:

parent.vue文件

    <children @call-parent-method="toChildClick"></children>
    const toChildClick = (data) => {console.log('来自子组件的调用', data)}

children.vue文件

  <a-button danger @click="getParentFn">调用父组件的方法</a-button>
import { computed, defineComponent, ref } from "vue";export default defineComponent({name: 'children',emits: ['call-parent-method'],setup(props, context) {const getParentFn = () => {context.emit('call-parent-method');}return {getParentFn}}
})

Vue2的写法可参考$refs。

6. 事件总线EventBus/mitt实现兄弟组件通信

在Vue2中,可以采用EventBus这种方法。利用一个空的Vue实例来作为桥梁,实现事件分发,它的工作原理是发布/订阅方法,通常称为Pub/Sub,也就是发布和订阅的模式。

var bus = new Vue()// 组件A
bus.$emit('event', 'hello from component A')// 组件B
bus.$on('event', (message) => {console.log(message); // 'hello from component A'
}) 

在Vue3中,采用第三方事件总线库mitt取代了EventBus事件。mitt的使用方法和EventBus非常类似,同样是基于Pub/Sub模式,并且更加简单,可以在需要进行通信的地方直接使用。

首先需要安装:

npm install mitt

创建一个工具包 eventBus.ts

import mitt from 'mitt';
export const emitter = mitt();

在componentA组件

<a-button type="primary" @click="sendMessage">发送消息给兄弟组件</a-button>
import { emitter } from '@/utils/eventBus'
export default defineComponent({setup(props, context) {const sendMessage = () => {// 发布一个事件emitter.emit('sendMessage', 'hello from component A')}return {sendMessage}}
})

在componetB组件

<div>message from component A: {{ message }}
</div>
import { defineComponent, onMounted, onUnmounted, ref } from "vue";
import { emitter } from '@/utils/eventBus'export default defineComponent({setup(props, context) {const message = ref('')onMounted(() => {emitter.on('sendMessage', (msg) => {message.value = msg;})})onUnmounted(() => {emitter.off('sendMessage')})return {message}}
})

事件总线的方式进行通信使用起来非常简单,可以实现任意组件之间的通信,其中没有多余的业务逻辑,只需要在状态变化组件触发一个事件,随后在处理逻辑组件监听该事件即可。

7. provide/inject AP实现跨级组件

provide/inject是一种跨组件传递数据的方式,允许祖先组件向其所有子孙后代注入依赖,而不必一层层地通过props传递。

import { defineComponent, provide, ref } from 'vue'
export default defineComponent({setup(props, context) {const theme = ref('dark')provide('theme', theme)}
})
<div>主题: {{ theme }}
</div>
import { defineComponent, ref, inject } from "vue";export default defineComponent({setup(props, context) {const theme = inject('theme')return {theme}}
})

8.vuex状态管理

对于一些大型的项目,要实现复杂的组件通信和状态管理。
组合式API的写法

import { createStore } from 'vuex'export default createStore({state: {message: 'vue'},mutations: {UPDATE_MESSAGE(state, newMessage) {state.message = newMessage},},actions: {updateMessage({ commit }, message) {commit('UPDATE_MESSAGE', message)},},getters: {message: state => state.message;}
})// 在组件中获取信息
const store = useStore()const message = computed(() => store.getters.message)const updateMessage = () => {store.dispatch('updateMessage','New Message')
}

9.pinia状态管理

Pinia主打简单和轻量,其大小仅有1KB。
组合式API写法

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', () => {const count = ref(0)const doubleCount = computed(() => count.value * 2)const increment = () => {count.value++}return { count, doubleCount, increment }
})// 在文件中引入
import { useCounterStore } from '@/stores/counter'export default defineComponent({setup() {const counter = useCounterStore()counter.count++;// 两种写法// 第一种counter.$patch({ count: counter.count + 1})// 第二种counter.increment();}
})

前3种解释了父组件向子组件传值的不同写法,4,5解释了子组件向父组件传值及调用方法。6解释了兄弟组件之间的通信,7解释了不同组件之间通信,8,9状态管理适合用于大型应用,组件众多,状态零散地分布在需要组件和组件之间的交互操作中,复杂度也不断增长的项目。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com