vue组件通信几种方式,vue3.0组件通信

  vue组件通信几种方式,vue3.0组件通信

  主要介绍了Vue3中10多种组件的通信方法的总结,通过实例代码进行了非常详细的介绍,对大家的学习或工作有一定的参考价值。有需要的朋友就跟着下面的边肖学习吧。

  

目录

   PropSemitsexpose/ref非props单根元素case多元素case v-model单值case多v-model绑定v-model修饰符slot slot默认slot命名Slot作用域Slot提供/注入总线BusgetCurrentInstanceVuexStateGetAuthorization操作模块penia安装注册mitt.js安装和使用本文解释了Vue 3.2组件的各种通信方法的基本用法,并使用了单文件组件脚本设置。

  众所周知,Vue.js中很重要的一个知识点就是组件通信。无论是业务类还是组件库的开发,都有自己的通信方式。

  本文适用于:

  有Vue 3基础的读者。打算开发组件库的读者。本文将涉及的知识点:

  semitexpose/ref non-propsv-model slot slot provide/inject bus busgetcurrentinstallancevexpansitt . js我会把上面列出的所有知识点写成一个简单的演示。这篇文章的目的是让大家知道这些方法都是有的,所以就不去深究每一个知识点了。

  建议读者通过再次键入代码来跟随本文,然后根据本文给出的链接深入挖掘每个知识点。

  

Props

  父组件将值传递给子组件(缩写:parent将值传递给child)。

  道具文档

  父组件

  //Parent.vue

  模板

  !-使用子组件-

  Child :msg=message /

  /模板

  脚本设置

  从导入。/components/child . vue //引入子组件

  消息=雷猴

  /脚本

  子组件

  //Child.vue

  模板

  差异

  {{ msg }}

  /div

  /模板

  脚本设置

  const props=defineProps({

  消息:{

  类型:字符串,

  默认值:“”

  }

  })

  Console.log(props.msg) //需要在js中使用props.xxx。在html中使用道具不是必需的

  /脚本

  在脚本设置中,必须使用defineProps API来声明Props,该API具有完整的推理,在脚本设置中直接可用。

  有关更多详细信息,请参见文档。

  在脚本设置中,不需要单独引入defineProps。

  Props其实可以做很多事情,比如设置默认值、类型验证类型、requiring required、自定义验证函数validator等等。

  可以去官网看看。这是必须掌握的知识点!

  道具文档

  

emits

  子组件通知父组件触发事件,并可以向父组件传递一个值。(缩写:从儿子到父亲)

  发出文档

  父组件

  //Parent.vue

  模板

  父div组件:{{ message }}/div

  !-自定义changeMsg事件-

  child @ changeMsg= change message /

  /模板

  脚本设置

  从“vue”导入{ ref }

  从导入子级。/components/Child.vue

  Let message=ref(雷猴)

  //更改消息的值,数据从子组件传递。

  函数变化消息(数据){

  message.value=data

  }

  /脚本

  子组件

  //Child.vue

  模板

  差异

  组件:button @click=handleClick 按钮/子组件的按钮

  /div

  /模板

  脚本设置

  //注册一个自定义事件名,告诉父组件向上传递时要触发的事件。

  const emit=define emits([ changeMsg ])

  函数handleClick() {

  //参数1:事件名称

  //参数2:传递给父组件的值

  发出( changeMsg , shark pepper )

  }

  /脚本

  与props一样,您必须在脚本设置中使用defineEmits API来声明emits,它具有完整的推理,并且在脚本设置中直接可用。有关更多详细信息,请参见文档。

  在脚本设置中,不需要单独引入定义限制。

  

expose / ref

  组件可以通过expose公开它们自己的方法和数据。

  父组件通过ref获取子组件,并调用其方法或访问数据。

  公开文档

  用例子说话

  父组件

  //Parent.vue

  模板

  父组件:获取子组件的消息数据:{{ msg }}/div

  Button @click=callChildFn 调用子组件/按钮的方法

  整点

  Child ref=com /

  /模板

  脚本设置

  从“vue”导入{ ref,onMounted }

  从导入子级 components/Child.vue

  const com=ref(null) //通过模板裁判员绑定子组件

  const msg=ref( )

  onMounted(()={

  //在加载完成后,将子组件的消息赋值给味精

  msg.value=com.value.message

  })

  函数callChildFn() {

  //调用子组件的更改消息方法

   com.value.changeMessage(蒜头王八)

  //重新将子组件的消息赋值给味精

  msg.value=com.value.message

  }

  /脚本

  子组件

  //Child.vue

  模板

  差异子组件:{{ message }}/div

  /模板

  脚本设置

  从“vue”导入{ ref }

  const message=ref(蟑螂恶霸)

  函数变化消息(数据){

  message.value=data

  }

  使用定义展示向外暴露指定的数据和方法

  defineExpose({

  消息,

  更改消息

  })

  /脚本

  在脚本设置中,定义展示不需要另外引入。

  揭露文档

  定义展示文档

  

Non-Props

  所谓的非道具就是非支柱的属性。

  意思是在子组件中,没使用支柱或发出定义的属性,可以通过$attrs来访问。

  常见的有类别、风格和身份证。

  非支柱的属性文档

  还是举个例子会直观点

  

单个根元素的情况

  父组件

  //Parent.vue

  模板

  子邮件=雷猴世界!name=鲨鱼辣椒 /

  /模板

  脚本设置

  从“vue”导入{ ref }

  从导入子级 components/Child.vue

  /脚本

  子组件

  //Child.vue

  模板

  差异子组件:打开控制台看看/div

  /模板

  打开控制台可以看到,属性被挂到超文本标记语言元素上了。

  

多个元素的情况

  但在Vue3中,组件已经没规定只能有一个根元素了。如果子组件是多个元素时,上面的例子就不生效了。

  //Child.vue

  模板

  差异子组件:打开控制台看看/div

  差异子组件:打开控制台看看/div

  /模板

  此时可以使用$attrs的方式进行绑定。

  //Child.vue

  模板

  div :message=$attrs.msg 只绑定指定值/div

  div v-bind=$attrs 全绑定/div

  /模板

  

v-model

  v型车是某视频剪辑软件的一个语法糖。在Vue3中的玩法就更多(晕)了。

  

单值的情况

  组件上的v型车使用模型值作为支柱和更新:模型值作为事件。

  v型车参数文档

  父组件

  //Parent.vue

  模板

  子v-model=message /

  /模板

  脚本设置

  从“vue”导入{ ref }

  从导入子级 components/Child.vue

  const message=ref(雷猴)

  /脚本

  子组件

  //Child.vue

  模板

  div @ click= handle click"{模型值} }/div

  /模板

  脚本设置

  从“vue”导入{ ref }

  //接收

  const props=defineProps([

  模型值//接收父组件使用v型车传进来的值,必须用模型值这个名字来接收

  ])

  const emit=define发出([ update:model value ])//必须用更新:模型值这个名字来通知父组件修改值

  函数handleClick() {

  //参数1:通知父组件修改值的方法名

  //参数2:要修改的值

  发出(更新:模型值,喷射河马)

  }

  /脚本

  你也可以这样写,更加简单

  子组件

  //Child.vue

  模板

  div @ click= $ emit( update:model value ,喷射河马) {{modelValue}}/div

  /模板

  脚本设置

  从“vue”导入{ ref }

  //接收

  const props=defineProps([

  模型值//接收父组件使用v型车传进来的值,必须用模型值这个名字来接收

  ])

  /脚本

  

多个 v-model 绑定

  多个v型车绑定文档

  父组件

  //Parent.vue

  模板

  子虚拟模型:msg1=message1 虚拟模型:msg2=message2 /

  /模板

  脚本设置

  从“vue”导入{ ref }

  从导入子级 components/Child.vue

  const message1=ref(雷猴)

  const message2=ref(蟑螂恶霸)

  /脚本

  子组件

  //Child.vue

  模板

  divbutton @click=changeMsg1 修改msg1/button {{msg1}}/div

  divbutton @click=changeMsg2 修改msg2/button {{msg2}}/div

  /模板

  脚本设置

  从“vue”导入{ ref }

  //接收

  const props=defineProps({

  msg1:字符串,

  msg2:字符串

  })

  const emit=define发出([ update:msg 1 , update:msg2])

  函数changeMsg1() {

  Emit(更新:msg1 ,鲨鱼胡椒)

  }

  函数changeMsg2() {

  Emit(更新:msg2 ,蝎子来来)

  }

  /脚本

  

v-model 修饰符

  V-model也可以通过以下方式引入装饰.

  v-模型修改文档

  父组件

  //Parent.vue

  模板

  子v-model.uppercase=message /

  /模板

  脚本设置

  从“vue”导入{ ref }

  从导入子级。/components/Child.vue

  const message=ref(hello )

  /脚本

  子组件

  //Child.vue

  模板

  div{{modelValue}}/div

  /模板

  脚本设置

  从“vue”导入{ ref,onMounted }

  const props=defineProps([

  模型值,

  模型修改器

  ])

  const emit=define emits([ update:model value ])

  onMounted(()={

  //判断是否有大写修饰符,如果有,执行toUpperCase()方法。

  if(props . model modifiers . upper case){

  emit(update:modelValue ,props.modelValue.toUpperCase())

  }

  })

  /脚本

  

插槽 slot

  Slot可以理解为将一个HTML片段传输给一个子组件。子组件以槽元素作为承载分布式内容的出口。

  文档槽

  本文打算谈谈日常生活中常用的三种槽:默认槽、命名槽和作用域槽。

  

默认插槽

  插槽的基本用法非常简单。只需使用子组件中的slot标签来呈现来自父组件的HTML内容。

  默认插槽文档

  父组件

  //Parent.vue

  模板

  儿童

  Div雷猴/div

  /孩子

  /模板

  子组件

  //Child.vue

  模板

  差异

  插槽/插槽

  /div

  /模板

  

具名插槽

  具名插槽是在默认插槽的基础上分类的,可以理解为对应座次。

  命名插槽文档

  父组件

  //Parent.vue

  模板

  儿童

  模板v形槽:猴子

  Div雷猴/div

  /模板

  纽扣鲨鱼辣椒/纽扣

  /孩子

  /模板

  子组件

  //Child.vue

  模板

  差异

  !-默认插槽-

  插槽/插槽

  !-命名插槽-

  插槽名称= monkey /插槽

  /div

  /模板

  父组件需要使用模板标签,并在标签上使用v-solt: name。

  接收子组件时,需要在插槽标签中包含name=name。

  这是对号入座

  最后需要注意的是,槽位内容的排版顺序是以子组件里的排版为准

  上面的例子就是这种情况。可以仔细观察子组件的进来顺序和子组件的排版顺序。

  

作用域插槽

  如果你用过Element-Plus之类的UI框架表,你应该能理解什么是scope slot。

  范围插槽文档

  父组件

  //Parent.vue

  模板

  !-v-slot= {scope} 获取子组件上传的数据-

  !-:list= list 将列表传递给子组件-

  子v-slot=“{ scope }”:list=“list”

  差异

  Div名称:{{ scope.name }}/div

  Div职业:{{ scope.occupation }}/div

  整点

  /div

  /孩子

  /模板

  脚本设置

  从“vue”导入{ ref }

  从导入子级。/components/Child.vue

  const list=ref([

  {姓名:雷猴,职业:雷 },

  {姓名:鲨椒,职业:游泳 },

  {姓名:蟑螂霸,职业:扫地 },

  ])

  /脚本

  子组件

  //Child.vue

  模板

  差异

  !-use: scope=item 返回每个项目-

  slot v-for=列表中的项:scope=item /

  /div

  /模板

  脚本设置

  const props=defineProps({

  列表:{

  类型:数组,

  默认值:()=[]

  }

  })

  /脚本

  我没有写风格,所以懒的用hr元素,视觉上很清晰。

  

provide / inject

  说到多层传值,道具和emit的使用方式会比较别扭。此时,您可以使用提供和注入。

  在父组件中使用Provide,值可以向下传递。

  Inject用在子(后代)组件中,可以在线访问。

  无论组件层次有多深,父组件都可以充当所有子组件的依赖提供者。

  提供/注入文档

  父组件

  //Parent.vue

  模板

  孩子/孩子

  /模板

  脚本设置

  从“vue”导入{ ref,provide,readonly }

  从导入子级。/components/Child.vue

  Const name=ref(老虎下山)

  Const msg=ref(雷猴)

  //使用readonly会使子组件无法直接修改,需要调用provide download的方法来修改。

  提供( name ,readonly(name))

  提供(消息,消息)

  提供( changeName ,(值)={

  name.value=值

  })

  /脚本

  子组件

  //Child.vue

  模板

  差异

  divmsg: {{ msg }}/div

  divname: {{name}}/div

  按钮@click=handleClick 修改/按钮

  /div

  /模板

  脚本设置

  从“vue”导入{ inject }

  Const name=inject (name , hello )//看看有没有值。如果没有值,将应用默认值(这里的默认值是hello)

  const msg=inject(msg )

  const changeName=inject( changeName )

  函数handleClick() {

  //这样写不合适,因为vue里推荐单向数据流。当父级使用readonly时,这行代码不会生效。用了才生效。

  //name.value=雷猴

  //正确的方式

  ChangeName(“虎躯一震”)

  //因为msg不是readonly,所以可以直接修改值

  Msg.value= world

  }

  /脚本

  Provide可以与readonly一起使用。详情请参考以上例子和评论。

  事实上,提供和注入主要用于在深层关系中传递值。上面的例子只有父子两层,只是为了说明我懒。

  

总线 bus

  Vue2中有一个总线传输方法,我们也可以在Vue3中自己模拟。

  这个方法其实有点像Vuex或者Pinia,做一个独立的工具来控制数据。

  但是这个我们自己写的方法和Vuex或者Pinia相比,并没有数据追踪等好的特性。

  原理

  我们创建一个Bus.js文件来控制数据和注册事件。

  Bus.js中有一个总线类

  EventList是必需的,用于存储事件列表。除了eventList,构造函数都是自定义数据,公共数据都存在这里。$on方法用于注册事件。$emit方法可以调用$on中的事件。$off方法可以注销eventList中的事件。然后,所有需要使用总线的组件都导入到Bus.js中,就可以一起操作一个数据了。

  Bus.js

  从“vue”导入{ ref }

  类别总线{

  构造函数(){

  //收集订阅信息,调度中心

  This.eventList={},//事件列表,必选。

  //以下都是自定义值

  This.msg=ref(这是公共汽车的信息)

  }

  //订阅

  $on(name,fn) {

  this . event list[name]=this . event list[name] []

  this.eventList[name]。推动(fn)

  }

  //发布

  $emit(名称,数据){

  if (this.eventList[name]) {

  this.eventList[name]。forEach((fn)={

  fn(数据)

  });

  }

  }

  //取消订阅

  $off(name) {

  if (this.eventList[name]) {

  删除此. eventList[name]

  }

  }

  }

  导出默认新总线()

  父组件

  //Parent.vue

  模板

  差异

  父组件:

  span style= margin-right:30px;消息:{{ message }}/span

  spanmsg: {{ msg }}/span

  /div

  孩子/孩子

  /模板

  脚本设置

  从“vue”导入{ ref }

  从导入总线。/Bus.js

  从导入子级。/components/Child.vue

  const msg=ref(Bus.msg)

  const message=ref(hello )

  //以监控的形式编写

  公交车。$on(changeMsg ,data={

  message.value=data

  })

  /脚本

  子组件

  //Child.vue

  模板

  差异

  子组件:

  Button @click=handleBusEmit 触发总线。$ emit/按钮

  Button @click=changeBusMsg 修改总线中的消息/按钮

  /div

  /模板

  脚本设置

  导入总线自./Bus.js

  函数handleBusEmit() {

  公交车。$emit(changeMsg ,雷猴)

  }

  函数changeBusMsg() {

  //console.log(Bus.msg)

  Bus.msg.value=在子组件中修改了总线的值

  }

  /脚本

  其实这个方法挺好用的,只是光看可能有点傻。请一定要自己敲代码来练习。

  

getCurrentInstance

  Getcurrentinstance是vue提供的方法,支持访问内部组件实例。

  GetCurrentInstance只对高级使用场景公开,比如库。强烈反对在应用代码中使用getCurrentInstance。请不要使用它作为在组合API中获得它的替代方法。

  说白了,这种方法适合在开发组件库的情况下使用不适合日常业务开展。

  getCurrentInstance **只能在设置或生命周期挂钩中调用。**

  Getcurrentinstance文档

  在脚本设置中,我模拟了类似$parent和$儿童的方式。

  父组件

  //Parent.vue

  模板

  差异父组件消息的值:{{ message }}/div

  button @click=handleClick 获取子组件/按钮

  孩子/孩子

  孩子/孩子

  /模板

  脚本设置

  从“vue”导入{ ref,getCurrentInstance,onMounted }

  从导入子级 components/Child.vue

  const message=ref(雷猴啊)

  让实例=空

  onMounted(()={

  instance=getCurrentInstance()

  })

  //子组件列表

  let childrenList=[]

  //注册组件

  函数注册Com(com) {

  childrenList.push(com)

  }

  函数handleClick() {

  if (childrenList.length 0) {

  childrenList.forEach(item={

  console.log(组件实例:,项目)

  console.log(组件名(名称):,item.type.name)

  console.log(组件输入框的值:,项。devtoolsrawsetupstate。输入值)

  console.log( -)

  })

  }

  }

  /脚本

  子组件

  //Child.vue

  模板

  差异

  分区-/分区

  子组件:button @click=handleClick 获取父组件的值/按钮

  英国铁路公司

  输入类型=文本五-模型=输入值

  /div

  /模板

  脚本

  导出默认值{

  名称:" ccccc "

  }

  /脚本

  脚本设置

  从“vue”导入{ getCurrentInstance,onMounted,nextTick,ref }

  const inputValue=ref( )

  让实例=空

  onMounted(()={

  instance=getCurrentInstance()

  nextTick(()={

  实例。父母。devtoolsrawsetupstate。注册com(实例)

  })

  })

  函数handleClick() {

  设msg=instance。父母。devtoolsrawsetupstate。消息

  msg.value=哈哈哈哈哈哈

  }

  /脚本

  可以将代码复制到你的项目中运行试试看,最好还是敲一遍咯。

  

Vuex

  状态管理主要解决跨组件通信的问题。

  在Vue3中,需要使用Vuex v4.x版本。

  安装

  用新公共管理或者故事安装到项目中。

  新公共管理安装vuex@next -保存

  # 或

  纱线添加vuex@next -保存

  使用

  安装成功后,在科学研究委员会目录下创建商店目录,再在商店下创建索引。射流研究…文件。

  //商店/索引。射流研究…

  从" vuex "导入{ createStore }

  导出默认的createStore({

  状态:{

  },

  getters: {

  },

  突变:{

  },

  动作:{

  },

  模块:{

  }

  })

  在商店/索引。射流研究…下输入以上内容。

  状态:数据仓库,用来存数据的吸气剂:获取数据的,有点像计算的用法(个人觉得)。突变:更改状态数据的方法都要写在突变里106 .行动:异步异步异步,异步的方法都写在这里,但最后还是需要通过突变来修改状态的数据模块:分包。如果项目比较大,可以将业务拆散成独立模块,然后分文件管理和存放。然后在src/main。j中引入

  从“vue”导入{ createApp }

  从导入应用程序 App.vue

  从导入存储。/商店

  const app=createApp(App)

  应用。使用(存储)。挂载(#应用程序)

  

State

  store/index.js

  //商店/索引。射流研究…

  从" vuex "导入{ createStore }

  导出默认的createStore({

  状态:{

  消息: 雷猴

  }

  })

  组件

  //xxx.vue

  脚本设置

  从" vuex "导入{ useStore }

  const store=useStore()

  console.log(store.state.msg) //雷猴

  /脚本

  

Getter

  我觉得吸气剂方法和计算是有点像的。

  比如我们需要过滤一下数据,或者返回时组装一下数据,都可以用吸气剂方法。

  store/index.js

  //商店/索引。射流研究…

  从" vuex "导入{ createStore }

  导出默认的createStore({

  状态:{

  消息: 雷猴

  },

  getters: {

  getMsg(state) {

  返回 state.msg 世界!

  }

  }

  })

  组件

  //xxx.vue

  脚本设置

  从" vuex "导入{ useStore }

  const store=useStore()

  控制台。日志(存储。吸气剂。getmsg)//雷猴世界!

  /脚本

  

Mutation

  变化是修改状态数据的唯一方法,这样状态管理才可以跟踪数据流向。

  在组件中通过犯罪调用即可。

  store/index.js

  //商店/索引。射流研究…

  从" vuex "导入{ createStore }

  导出默认的createStore({

  状态:{

  消息: 雷猴

  },

  突变:{

  changeMsg(状态,数据){

  state.msg=data

  }

  }

  })

  组件

  //xxx.vue

  脚本设置

  从" vuex "导入{ useStore }

  const store=useStore()

  store.commit(changeMsg ,蒜头王八)

  console.log(store.state.msg) //蒜头王八

  /脚本

  

Action

  我习惯将异步的东西放在行动方法里写,然后在组件使用派遣方法调用。

  store/index.js

  //商店/索引。射流研究…

  从" vuex "导入{ createStore }

  导出默认的createStore({

  状态:{

  消息: 雷猴

  },

  突变:{

  changeMsg(状态,数据){

  state.msg=data

  }

  },

  动作:{

  fetchMsg(上下文){

  //模拟创建交互式、快速动态网页应用的网页开发技术请求

  setTimeout(()={

  context.commit(changeMsg ,鲨鱼辣椒)

  }, 1000)

  }

  }

  })

  组件

  //xxx.vue

  脚本设置

  从" vuex "导入{ useStore }

  const store=useStore()

  store.dispatch(fetchMsg )

  /脚本

  

Module

  组件就是传说中的分包了。这需要你将不同模块的数据拆分成一个个射流研究…文件。

  我举个例子,目录如下

  商店

  - index.js

  -模块/

  - user.js

  - goods.js

  索引。射流研究…对外的出口(主文件)模块/user.js用户相关模块模块/商品。射流研究…商品模块index.js

  从" vuex "导入{ createStore }

  从导入用户。/模块/用户

  从…进口货物。/模块/商品

  导出默认的createStore({

  状态:{},

  getter:{ },

  突变:{},

  动作:{},

  模块:{

  用户,

  商品

  }

  })

  user.js

  const user={

  状态:{

  },

  getters: {

  },

  突变:{

  },

  动作:{

  }

  }

  导出默认用户

  goods.js

  const goods={

  状态:{

  },

  getters: {

  },

  突变:{

  },

  动作:{

  }

  }

  出口违约商品

  然后在各个模块里放入相应的数据和方法就行。

  在组建中调用方法和访问数据,都和之前的用法差不多的。

  以上就是状态管理的基础用法。除此之外,Vuex还有各种语法糖,大家可以自行查阅官方文档

  

Pinia

  皮尼亚是最近比较火热的一个工具,也是用来处理

  strong>跨组件通信 的,极大可能成为 Vuex 5 。

  Pinia 文档

  从我使用 Pinia 一阵后的角度来看,Pinia 跟 Vuex 相比有以下优点:

  调用时代码跟简洁了。对 TS 更友好。合并了 Vuex 的 Mutation 和 Action 。天然的支持异步了。天然分包。除此之外,Pinia 官网还说它适用于 Vue2 和 Vue3。但我没试过在 Vue2 中使用 我懒得试。

  Pinia 简化了状态管理模块,只用这3个东西就能应对日常大多任务。

  state:存储数据的仓库getters:获取和过滤数据(跟 computed 有点像)actions:存放 “修改 state ”的方法我举个简单的例子

  

安装

  npm install pinia

  # 或

  yarn add pinia

  

注册

  在 src 目录下创建 store 目录,再在 store 里创建 index.js 和 user.js

  目录结构如下

  store

  - index.js

  - user.js

  index.js

  import { createPinia } from pinia

  const store = createPinia()

  export default store

  user.js

  常见的写法有2种,选其中一种就行。

  import { defineStore } from pinia

  // 写法1

  export const useUserStore = defineStore({

   id: user, // id必填,且需要唯一

   state: () => {

   return {

   name: 雷猴

   }

   },

   getters: {

   fullName: (state) => {

   return 我叫 + state.name

   }

   },

   actions: {

   updateName(name) {

   this.name = name

   }

   }

  })

  // 写法2

  export const useUserStore = defineStore(user,{

   state: () => {

   return {

   name: 雷猴

   }

   },

   getters: {

   fullName: (state) => {

   return 我叫 + state.name

   }

   },

   actions: {

   updateName(name) {

   this.name = name

   }

   }

  })

  然后在 src/main.js 中引入 store/index.js

  src/main.js

  import { createApp } from vue

  import App from ./App.vue

  import store from ./store

  const app = createApp(App)

  app

   .use(store)

   .mount(#app)

  在组件中使用

  组件

  // xxx.vue

  <template>

   <div>

   <div>name: {{ name }}</div>

   <div>全名:{{ fullName }}</div>

   <button @click="handleClick">修改</button>

   </div>

  </template>

  <script setup>

  import { computed } from vue

  import { storeToRefs } from pinia

  import { useUserStore } from @/store/user

  const userStore = useUserStore()

  // const name = computed(() => userStore.name)

  // 建议

  const { name, fullName } = storeToRefs(userStore)

  function handleClick() {

   // 不建议这样改

   // name.value = 蝎子莱莱

   // 推荐的写法!!!

   userStore.updateName(李四)

  }

  </script>

  啰嗦两句

  其实 Pinia 的用法和 Vuex 是挺像的,默认就是分包的逻辑,在这方面我支持 菠萝(Pinia)

  Pinia 还提供了多种语法糖,强烈建议阅读一下 官方文档。

  

mitt.js

  我们前面用到的 总线 Bus 方法,其实和 mitt.js 有点像,但 mitt.js 提供了更多的方法。

  比如:

  on:添加事件emit:执行事件off:移除事件clear:清除所有事件mitt.js 不是专门给 Vue 服务的,但 Vue 可以利用 mitt.js 做跨组件通信。

  github 地址

  npm 地址

  

安装

  npm i mitt

  

使用

  我模拟一下 总线Bus 的方式。

  我在同级目录创建3个文件用作模拟。

  Parent.vue

  Child.vue

  Bus.js

  Bus.js

  // Bus.js

  import mitt from mitt

  export default mitt()

  Parent.vue

  // Parent.vue

  <template>

   <div>

   Mitt

   <Child />

   </div>

  </template>

  <script setup>

  import Child from ./Child.vue

  import Bus from ./Bus.js

  Bus.on(sayHello, () => console.log(雷猴啊))

  </script>

  Child.vue

  // Child.vue

  <template>

   <div>

   Child:<button @click="handleClick">打声招呼</button>

   </div>

  </template>

  <script setup>

  import Bus from ./Bus.js

  function handleClick() {

   Bus.emit(sayHello)

  }

  </script>

  此时,点击 Child.vue 上的按钮,在控制台就会执行在 Parent.vue 里定义的方法。

  mitt.js 的用法其实很简单,建议跟着 官方示例 敲一下代码,几分钟就上手了。

  到此这篇关于Vue3中10多种组件通讯方法小结的文章就介绍到这了,更多相关Vue3 组件通讯内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: