总结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();

总结:

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

相关推荐
_斯洛伐克14 分钟前
uniapp 知识点
前端·javascript·uni-app
计算机学姐1 小时前
基于大数据技术的颈椎病预防交流与数据分析及可视化系统
大数据·vue.js·spring boot·sql·数据挖掘·数据分析·intellij-idea
计算机学姐1 小时前
基于大数据的亚健康人群数据分析及可视化系统
大数据·vue.js·hadoop·spring boot·信息可视化·数据挖掘·数据分析
木木与呆呆1 小时前
Chrome截取网页全屏
前端·chrome
向宇it2 小时前
fastadmin搜索刷新列表,怎么限制用户频繁点击?
开发语言·前端·javascript·fastadmin
Ylucius3 小时前
常见服务器大全----都是什么?又有何作用?区别联系是什么?---web,应用,数据库,文件,消息队列服务器,Tomat,Nginx,vite.....
java·前端·javascript·chrome·学习·node.js·express
alicca4 小时前
递归手撕,JSON 字符串化和解析,加权树结构的字符串解析对象,解析并返回DOM 树结构(DOMParser),解析带有层级的文本
前端·javascript
李是啥也不会5 小时前
JavaScript中的输出方式
开发语言·前端·javascript
炒毛豆5 小时前
ant design vue中带勾选表格报Tree missing follow keys: ‘undefined‘解决方法
前端·javascript·vue.js
大多_C5 小时前
python中logging的用法
前端·python