总结Vue3的11种传参通信方式,非常齐全

前言:

vue3出来很久了,也非常成熟了,平时项目只管用也没多想,直至今天想写一编关于vue3传参,然后我总结一下竟然总结出来11种方式那么多,11种我分别列了出来,由于vue3有两种setup写法,下面我将用最简洁 的代码例子针对主流的<script setup>写法对每一种用法进行细说。如果有那里不对或者有补充欢迎大佬指导。

  1. 父传子
  2. 子传父
  3. 兄弟组件传参(mitt)
  4. $attrs
  5. refs
  6. v-model
  7. provide/inject
  8. 路由传参
  9. vuex传参
  10. pinia传参
  11. 浏览器缓存

一、父传子

思路:父组件通过冒号:绑定变量,然后子组件用const props = defineProps({})进行接收参数。

父组件代码: 在第二行那里 :name="name" 把那么传给子组件

xml 复制代码
<template>
  <child :name="name"></child>
</template>

<script setup>
import { ref } from 'vue'
import child from './child.vue'

const name = ref('天天鸭')
</script>

子组件代码: const props = defineProps({})接收后直接在标签使用

xml 复制代码
<template>
  <div>{{ props.name }}</div>
</template>

<script setup>
import { defineProps } from 'vue'
const props = defineProps({
  name: {
    type: String,
    default: '',
  },
})
</script>

二、子传父

思路:子组件用 const emits = defineEmits(['触发的方法']) 注册某个在父组件的事件,然后通过emits('触发的事件', 参数) 触发父组件事件并且带上参数。

子组件代码: 注册 addEvent 事件后, 用 emits('addEvent', name.value) 触发父组件的 addEvent事件

xml 复制代码
<template>
  <div ></div>
</template>

<script setup>
import { ref, defineEmits } from 'vue'

const name = ref('天天鸭')
const emits = defineEmits(['addEvent'])
const handleSubmit = () => {
  emits('addEvent', name.value)
}
</script>

父组件代码: 触发addEvent事件后,在对应的方法里面直接能拿到传过来的参数

xml 复制代码
<template>
  <child @addEvent="handle"></child>
</template>

<script setup>
import { ref } from 'vue'
import child from './child.vue'

const handle = value => {
  console.log(value); // '天天鸭'
}
</script>

三、兄弟组件传参(mitt)

以前vue2是用EventBus事件总线跨组件实现兄弟组件通信的。但vue3中没有,所以vue3目前主流使用mitt.js插件来进行替代实现兄弟通信。

1、npm包引入

css 复制代码
 npm install --save mitt

2、在main.js文件进行全局挂载, $bus是自定义属性名

arduino 复制代码
import mitt from "mitt"

const app = createApp(App)

app.config.globalProperties.$bus = new mitt()

3、传参出去的兄弟组件代码

xml 复制代码
<script setup>
    import mitt from 'mitt'
    const emitter = mitt()
    emitter.emit('自定义的事件名称','参数')
</script>

4、接收参数的兄弟组件代码

xml 复制代码
<script setup>
     import mitt from 'mitt'
     const emitter = mitt()
     emitter.on('自定义的事件名称', '参数' )
</script>

四、$attrs

注意: 以前在在vue2里面中除了$attrs,还有$listeners; 但vue3直接把$listeners合并到 $attrs 里面了。
简要说明:$attrs主要作用是接收没在props里面定义,但父组件又传了过来的属性。看下面代码例子就好懂多了

父组件代码: 传两个属性过去,一个在子组件props中,一个不在

xml 复制代码
<template>
  <child :name="天天鸭" data="PC9527"/>
</template>

<script setup>
import child from './child.vue'
</script>

子组件代码: $attrs接收到props以外的内容,所以用useAttrs()打印出来没有name只有data

xml 复制代码
<template>
  <div>
    {{ props.name }}   // '天天鸭'
  </div>
</template>

<script setup>
import { defineProps, useAttrs } from 'vue'
const props = defineProps({
  name: {
    type: String
  }
})

const myattrs = useAttrs()
console.log(myattrs)   //  { "data": "PC9527" }
</script>

五、refs传参

简单说明:父组件通过在子组件上定义 ref='ref名称',然后const ref名称 = ref(null),就能通过ref名称操控子组件的属性和方法(子组件用defineExpose对外暴露才能被操控),具体看下面例子。

父组件代码:

xml 复制代码
<template>
  <child ref="myref"></child>
  <button @click="myClick">点击</button>
</template>

<script setup>
  import child from "./child.vue"
  import { ref } from "vue"
  const myref = ref(null)
  const myClick = () => {
      console.log(myref.value.name) // 直接获取到子组件的属性
      myref.value.chileMethod()      // 直接调用子组件的方法
  }
</script>

子组件代码:defineExpose对外暴露才能被操控

xml 复制代码
<template>
  <div></div>
</template>

<script setup>
    import { defineExpose } from "vue"

    const chileMethod = () =>{
      console.log("我是方法")
    }
    const name = ref('天天鸭')

    defineExpose({    // 对外暴露
        name,
        chileMethod
    })
</script>

六、v-model

简单讲解: v-model其实语法糖,如下两行代码作用是一样, 上面是下面的简写。

ini 复制代码
<chile v-model:title="title" />

<chile :title="title" @update:title="title = $event" />

父组件代码: 直接使用v-model传参

xml 复制代码
<template>
  <child v-model:name="name" v-model:num="num"></child>
</template>

<script setup>
    import child from "./child.vue"
    import { ref, reactive } from "vue"
    const name = ref("天天鸭")
    const num = ref("2222")
</script>

子组件代码: 通过 defineEmits获取到然后用emit("update:修改的属性", 修改的内容)进行修改父组件的内容,,注意:update:是固定写法。

xml 复制代码
<template>
  <button @click="myClick">点击</button>
</template>

<script setup>
  import { defineEmits } from "vue"
  const emit = defineEmits(["name","num"])
  
  // 子组件触发使用
  const myClick = () => {
      emit("update:name", "改个新名字")
      emit("update:num", "换个新号码")
  }
</script>

七、provide/inject

简单讲解:provide和inject叫依赖注入,是vue官方提供的API,它们可以实现多层组件传递数据,无论层级有多深,都可以通过这API实现。

假设这是太老爷组件: provide('名称', 传递的参数)向后代组件提供数据, 只要是后代都能接收

xml 复制代码
<template>
  <div></div>
</template>

<script setup>
import { ref, provide } from 'vue'
const name = ref('天天鸭')
// 向后代组件提供数据, 只要是后代都能接收
provide('name', name.value)
</script>

最深层的孙组件: 无论层级多深,用 inject(接收什么参数) 进行接收即可

xml 复制代码
<template>
  <div>{{ name }}</div>
</template>

<script setup>
import { inject } from 'vue'
// 接收顶层组件的通信
const name = inject('name')
</script>

八、路由传参

简单讲解: 路由跳转事上参数也是传参的一种,而且传参方式还不止一种呢,下面细说。

1、query传参

javascript 复制代码
// 传递方
const query = { id: 9527, name: '天天鸭' }
router.push({ path: '/user', query })

// 接收方
import { useRoute} from 'vue-router'
const route = useRoute()
console.log(route.query)

2、params传参

php 复制代码
// 发送方
router.push({
   name: 'test', 
   params: {
       name: '天天鸭'
   }
})
 
// 接收方
import { useRoute} from 'vue-router'
const route = useRoute()
console.log(route.params) // { name: '天天鸭' }

3、state传参

arduino 复制代码
// 发送方
const state= { name: '天天鸭' }
router.push({ path: '/user', state })
 
// 接收方直接使用
console.log(history?.state?.name)

九、vuex传参

写过对应的文章,可以直接细看:对比vuex和pinia用法

十、pinia

写过对应的文章,可以直接细看:对比vuex和pinia用法

十一、浏览器缓存

localStorage 和sessionStorage: 这算是用的不多,但也是必用的一种通信方式了,下面看看区别:

sessionStorage(临时存储):为每一个数据源维持一个存储区域,在浏览器打开期间存在,包括页面重新加载

localStorage(长期存储):与 sessionStorage 一样,但是浏览器关闭后,数据依然会一直存在

下面直接上使用的语法。

javascript 复制代码
// 存储数据
localStorage.setItem('key', 'value');
sessionStorage.setItem('key', 'value');

// 获取数据
const valueFromLocalStorage = localStorage.getItem('key');
const valueFromSessionStorage = sessionStorage.getItem('key');

// 删除数据
localStorage.removeItem('key');
sessionStorage.removeItem('key');

// 清空所有数据
localStorage.clear();
sessionStorage.clear();

总结:

空闲想总结一下,纯人工肝了一天终于写好了,我尽量用最简洁易懂的方式写了,如果有什么写错了或者不够明细都欢迎大家指出。这也当笔记用了,以后忘记用法回来看一眼。

相关推荐
passerby606121 分钟前
完成前端时间处理的另一块版图
前端·github·web components
掘了28 分钟前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅31 分钟前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment1 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
吹牛不交税2 小时前
admin.net-v2 框架使用笔记-netcore8.0/10.0版
vue.js·.netcore