首页 > 其他分享 >v2和v3组件通信方式的区别

v2和v3组件通信方式的区别

时间:2023-06-19 21:46:38浏览次数:39  
标签:const 插槽 v2 v3 let vue3 组件 emitter

https://gitee.com/jch1011/vue3_communication.git

通信方式

vue2

  • props:父子组件、子父组件、甚至兄弟组件
  • 自定义事件:可以实现子父组件
  • $bus:任意组件通信
  • pubsub:发布订阅,任意组件通信
  • vuex:集中式状态管理容器,实现任意组件通信
  • ref:获取子组件的响应式数据及方法
  • slot:插槽(默认、具名、作用域)实现父子组件通信
  • ......

vue3

  1. props 使用defineProps
  2. 自定义事件
    1. 原生dom事件
    2. vue2中 @click是自定义事件,原生要加.navite
    3. vue3中@click为原生DOM事件
    4. vue3:原生的DOM事件不管是放在标签身上还是组件标签身上,都是原生DOM事件
    5. @click其实是给子组件的根节点绑定
    6. 子组件给父组件传递 @xxx='()=>{}'
    7. 声明:let $emit = defineEmits(['xxx'])
    8. 使用:$emit('xxx','东风')
    9. 第一个参数:事件类型,接下来的参数为注入数据
    10. 如果在defineEmits声明'click',@click就会变成自定义事件
    11. 这个 emits 选项还支持对象语法,它允许我们对触发事件的参数进行验证:
    <script setup>
    const emit = defineEmits({ 
    	submit(payload) { 
    	// 通过返回值为 `true` 还是为 `false` 来判断 
    	// 验证是否通过 
    	} 
    })
    </script>
    
    1. 如果你正在搭配 TypeScript 使用 <script setup>,也可以使用纯类型标注来声明触发的事件:
    <script setup lang="ts">
    const emit = defineEmits<{
      (e: 'change', id: number): void
      (e: 'update', value: string): void
    }>()
    </script>
    
  3. 全局事件总线(vue3使用mitt 代替$bus,因为没有this了)
    1. 安装mitt npm i -D mitt
    2. // 使用 ES6 模块 import mitt from 'mitt'
    3. 使用方法
    const emitter = mitt()
    // listen to an event
    emitter.on('foo', e => console.log('foo', e) )
    // listen to all events
    emitter.on('*', (type, e) => console.log(type, e) )
    // fire an event
    emitter.emit('foo', { a: 'b' })
    // clearing all events
    emitter.all.clear()
    // working with handler references:
    function onFoo() {}
    emitter.on('foo', onFoo)   // listen
    emitter.off('foo', onFoo)  // unlisten
    
  4. v-model 父子组件数据同步
    1. 父组件中使用<Child v-model:money="money">
    2. 子组件中使用
    let props = defineProps(["money"]);
    let $emit = defineEmits(["update:money"]);
    <Button>@click="$emit('update:pageSize', pageSize + 4)"<Button/>
    
  5. attrs vue3提供了一个方法,获取组件身上的属性和事件
    1. 使用
       let $attrs = useAttrs() 
       // vue3将$attrs和$linterners合并了
       <el-button :='$attrs'>按钮</el-button>
    
    1. 注意!如果使用props接收了,useAttrs方法就获取不到了
  6. 使用ref和$parent
    1. 子组件内部的数据默认关闭的,需要使用defineExpose({money})暴露
    2. son.value.money-=10;
    3. 子组件中使用$parent
  7. 父孙之间通信:Provide与Inject
    1. vue3提供provide(提供)和inject(注入),可以实现隔辈传递数据
    2. 例如
    	let car = ref('车');
    	provide('key',car);
    	// 使用(孙子)
    	let car = inject('key')
    	// 爷爷的数据和孙子的数据是同一个数据,所以可以修改
    
  8. pinia
    1. vuex:集中式管理状态容器,可以实现任意组件中间通信
      1. 核心概念:state、mutations、actions、getters、modules
    2. pinia:集中式状态管理容器,可以实现任意组件中间通信
      1. 核心概念:states、actions、getters
    3. 创建大仓库
    let store = createPinia();
    export default store;
    
    1. 安装
    import store from './store'
    app.use(store)
    
    1. 定义小仓库
    import { defineStore } from 'pinia' 
    // 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`) 
    // 第一个参数是你的应用中 Store 的唯一 ID。 
    export const useAlertsStore = defineStore('alerts', { 
    	state: () => ({ count: 0 }), 
    	getters: { 
    		double: (state) => state.count * 2, 
    	}, 
    	actions: { 
    		increment() { 
    			this.count++ 
    		}, 
    	},
    })
    
    1. 使用
    import useInfoStore from "../../store/modules/info";
    //获取小仓库对象
    let infoStore = useInfoStore();
    console.log(infoStore);
    //修改数据方法
    const updateCount = () => {
      //仓库调用自身的方法去修改仓库的数据
      infoStore.updateNum(66, 77);
    };
    
    1. 组合式api
    //定义组合式API仓库
    import { defineStore } from "pinia";
    import { ref, computed, watch } from "vue";
    //创建小仓库
    const useTodoStore = defineStore("todo", () => {
    	const todos = ref([
    	    { id: 1, title: "吃饭" },
    	    { id: 2, title: "睡觉" },
    	    { id: 3, title: "打豆豆" },
    	]);
    	const arr = ref([1, 2, 3, 4, 5]);
    	const total = computed(() => {
    	    return arr.value.reduce((prev, next) => {
    	      return prev + next;
    	    }, 0);
    	});
    //务必要返回一个对象:属性与方法可以提供给组件使用
    	 return {
    		todos,
    		arr,
    		total,
    		updateTodo() {
    			todos.value.push({ id: 4, title: "组合式API方法" });
    		},
    	};
    });
    export default useTodoStore;
    
  9. slot 插槽(默认插槽、具名插槽、作用域插槽)
    1. 默认插槽
    	<slot></slot>
    
    1. 具名插槽(v-slot可以简写成#
    	<slot name="a"></slot>
    	<h1>具名插槽填充数据</h1>
    	<h1>具名插槽填充数据</h1>
    	<!--使用-->
    	<!-- 具名插槽填充a -->
    	<template #a>
    	<div>我是填充具名插槽a位置结构</div>
    	</template>
    
    1. 作用域插槽
      1. 就是可以传递数据的插槽,子组件可以将数据回传给父组件,父组件可以决定这些回传的数据是以何种结构或者外观在子组件内部展示的!
      2. 例如
      <!--父-->
      <Test1>
      	<template v-slot='{$row,$index}'>
      		<h1>{{$row.title}}</h1> 
      	</template>
      </Test1>
      <!--子-->
      <ul>
      	<li v-for='(item,index) in todos' :key='item.id'>
      		<!--回传给父组件-->
      		<slot :$row='item' $index='index'></slot>
      	</li>
      </ul>
      

标签:const,插槽,v2,v3,let,vue3,组件,emitter
From: https://www.cnblogs.com/zhilutianji/p/17492251.html

相关文章

  • 常见k8s开源网络组件
    目前,已经有多个开源组件支持容器网络模型。常见的网络组件,包括Flannel、Open vSwitch、直接路由和Calico。1.FlannelFlannel之所以可以搭建k8s依赖的底层网络,是因为它能实现以下两个功能。(1)它能协助k8s,给每一个Node上的Docker容器分配互相不冲突的IP地址。(2)它能在这些IP地址之......
  • 记录--Vue3 封装 ECharts 通用组件
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助按需导入的配置文件配置文件这里就不再赘述,内容都是一样的,主打一个随用随取,按需导入。import*asechartsfrom"echarts/core";//引入用到的图表import{LineChart,typeLineSeriesOption}from"echarts/......
  • 【工程应用八】终极的基于形状匹配方案解决(小模型+预生成模型+无效边缘去除+多尺度+各
      我估摸着这个应该是关于形状匹配或者模版匹配的最后一篇文章了,其实大概是2个多月前这些东西都已经弄完了,只是一直静不下来心整理文章,提醒一点,这篇文章后续可能会有多次修改(但不会重新发文章,而是在后台直接修改或者增加),所以有需要的朋友可以随时重复查看。 这次带来的更新......
  • 在.Net Core6中使用log4net组件写日志到本地文件的操作流程
    原文链接:https://blog.csdn.net/kevin860/article/details/1068810621.引用包: Log4Net  Microsoft.Extensions.Logging.Log4Net.AspNetCore Microsoft.Extensions.Logging //loggingbuilder.AddFilter该方法需要引入Microsoft.Extensions.Logging名称空间 ......
  • StencilJs学习之组件装饰器
    stenciljs可以方便的构建交互式组件支持以下装饰器componentstatepropwatchmethodelementeventlistenComponent装饰器@Component是一个装饰器,它将TypeScript类指定为Stencil组件。每个模板组件在构建时都会转换为Webcomponent。import{Component}from......
  • (四)Boot组件
       ......
  • 你曾遇到的某大厂奇葩问题:Android组件化开发,组件间的Activity页面跳转
    组件化开发有什么好处?1、当项目越来越大时,app的业务越来越复杂,会出现业务功能复杂混乱,各功能块、页面相互依赖,相互调用太多导致耦合度高,而采用组件化开发,我们就可以将功能模块合理的划分,降低功能耦合度。2、不采用组件化开发时,编译速度缓慢,修改一个页面布局编译一下还得等几分钟。......
  • Jetpack组件库(含Jetpack Compose)从入门到精通全家桶【附Demo】
    前言开发应用程序就像搭积木。我们对产品业务及功能模块的划分和封装,就像在搭建积木一样。积木不能太大,这不利于修改和拆解;积木也不能太小,否则管理起来可能会很混乱。只有基于稳健、合理的架构,项目才能轻松应对需求的变化,才有可能健康成长。没有良好架构的应用程序,就像没有搭好底......
  • Tab切换以及倒计时组件封装
    1、Tab组件功能支持默认选中tab子元素可以是文本或者图片自定义tab的数量,并自适应展示实现方式用ul>li标签遍历传入的tabs数组参数渲染判断是否传入背景,未传则显示文字绑定点击事件特点简单易用可适配性2、倒计时组件功能常用于榜单或者活动结束倒计时......
  • 得到、微信、美团、爱奇艺APP组件化架构实践
    一、背景随着项目逐渐扩展,业务功能越来越多,代码量越来越多,开发人员数量也越来越多。此过程中,你是否有过以下烦恼?项目模块多且复杂,编译一次要5分钟甚至10分钟?太慢不能忍?改了一行代码或只调了一点UI,就要run整个项目,再忍受一次10分钟?合代码经常发生冲突?很烦?被人偷偷改了自己模块的代......