vue3的传参方式总结

文章目录


  1. props:父传子
  2. defineEmits:子传父
  3. mitt:兄弟组件传参
  4. $attrs:爷孙
  5. refs
  6. v-model(双向)
  7. provide/inject(多层)
  8. 路由传参
  9. vuex传参(全局)
  10. pinia传参(全局)
  11. 浏览器缓存
  12. window
  13. app.config.globalProperties

一、父传子

方式:

父组件通过冒号:绑定变量,

子组件通过const props=defineProps({})进行接收

父组件

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

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

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

子组件

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

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

二、子传父

方式:

子组件用const emits=defineEmits(['所触发的方法名称'])注册在父组件中的事件,然后通过emits('触发的事件',参数)触发父组件事件并且带上参数

子组件

vue 复制代码
<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>

父组件

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

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

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

三、兄弟组件传参

vue2中使用EventBus事件总线跨组件实现兄弟组件通信的,但vue3目前主要使用mitt.js插件来进行兄弟组件通信

  1. npm包下载
bash 复制代码
 npm install --save mitt
  1. 在main.js文件进行全局挂载,$bus是自定义属性名
javascript 复制代码
import mitt from 'mitt'
const app=createApp(App)
app.config.globalProperties.$bus=new mitt()
  1. 传出去参数的兄弟组件
vue 复制代码
<script setup>
  import mitt from 'mitt'
  const emitter=mitt()
  emitter.emit('自定义事件名称','参数')
</script>
  1. 接收参数的兄弟组件
vue 复制代码
<script setup>
  import mitt from 'mitt'
  const emitter=mitt()
  emitter.on('自定义事件名称','参数')
</script>

四、$attrs

作用:接收没在props里面定义,但是父组件又传过来的属性

父组件

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

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

子组件

vue 复制代码
<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>

五、ref

父组件通过在子组件上定义ref='ref名称',然后const ref名称 =ref(null),就能通过ref名称操纵子组件的属性和方法(子组件用defineExpose对外暴露才能被操控)

父组件

vue 复制代码
<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>

子组件

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

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

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

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

六、v-model

vue 复制代码
<child v-model:title="title">
//简写
<child :title="title">

父组件:

vue 复制代码
<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:是固定写法。

vue 复制代码
<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('名称', 传递的参数)向后代组件提供数据, 只要是后代都能接收

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

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

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

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

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

八、路由传参

1、query传参

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

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

2、params传参

注意:4.1.4 (2022-08-22) 删除了param这种方式

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

3、state传参

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

十一、浏览器缓存

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

十二、通过window对象全局挂载全局对象或者属性

简单说明:直接用语法 window.name = '天天鸭' 定义然后全局通用即可。存放在内存刷新会清空

注意 :在 Vue 3 应用程序中,虽然可以直接将属性挂载到 window 对象上实现全局访问,但这并不是推荐的做法,因为直接修改全局对象可能会导致命名冲突、难以进行模块化管理以及不利于应用的封装与维护

用法:直接定义,可以是属性也可以是对象

javascript 复制代码
window.duname = '天天鸭'
window.duObj = { test: '看看对象' }

引用:

javascript 复制代码
console.log( window.duname);   // 天天鸭 
console.log( window.duObj);   // {test: '看看对象'}

十三、app.config.globalProperties

简单讲解:app.config.globalProperties 是Vue官方的一个 api,这是对 Vue 2 中 Vue.prototype 使用方式的一种替代,Vue.prototype 法在 Vue3 已经不存在了。与任何全局的东西一样,应该谨慎使用。

用法示例:在main.js文件挂载一个全局的 msg 属性

plain 复制代码
import { createApp } from 'vue'

const app = createApp(App)

app.config.globalProperties.msg = 'hello'

在其它页面使用getCurrentInstance()获取

plain 复制代码
import { getCurrentInstance } from "vue";

const { proxy } = getCurrentInstance() // 使用proxy,类似于vue2的this

console.log(proxy.msg);    // hello

总结

这周项目主要写交互,但是因为文件结构太不好,又重构了一遍,分了好多子组件,好多地方都要改,用到的传参只是也不少,就去大概了解了以上几种vue3传参方式,内容还挺多的

下周还是继续进行交互,但是希望自己可以多手敲一些代码,不能太依赖豆包了

相关推荐
梵得儿SHI1 小时前
Vue 核心语法深度解析:生命周期与响应式之计算属性(computed)与侦听器(watch/watchEffect)
前端·javascript·vue.js·计算属性·侦听器·缓存机制·数据派生
anuoua1 小时前
歼20居然是个框架-基于 Signals 信号的前端框架设计
前端·javascript·前端框架
秋天的一阵风1 小时前
翻掘金看到停更的前辈们,突然想聊两句 🤔
前端·vue.js·程序员
我爱学习_zwj1 小时前
Node.js模块管理:CommonJS vs ESModules
开发语言·前端·javascript
咬人喵喵1 小时前
网页开发的“三剑客”:HTML、CSS 和 JavaScript
javascript·css·html
心本无晴.1 小时前
深入剖析Vue3中Axios的实战应用与最佳实践
前端·javascript·vue.js
冬男zdn1 小时前
优雅的React表单状态管理
前端·javascript·react.js
国服第二切图仔1 小时前
基于Electron for 鸿蒙PC的高性能表格组件封装
javascript·electron·harmonyos·鸿蒙pc
IT·小灰灰1 小时前
Doubao-Seedream-4.5:当AI学会“版式设计思维“——设计师的七种新武器
javascript·网络·人工智能·python·深度学习·生成对抗网络·云计算