vue3 组件间传值

162 阅读2分钟

一、通过props和emit传值和接收值

父组件

<div>
  <child :myName="childName" @myNewName="onMyNewName"></child>
</div>
<script setup lang="ts">
    import {ref} from 'vue'
    let childName=ref("Emily");
      const onMyNewName=()=>{
      childName.ref="new Emily"
    }
</script>

子组件

<div>
  <span>{{myName}}</span>
  <button @click="changeName">改变名称</button>
</div>
<script>
import {defineProps,defineEmits} from 'vue'
const emit=defineEmits(['clickChild'])
const pros=defineProps({
myName:{
  type:string
  }
})
const changeName=()=>{
emit('myNewName','new name')
}
</script>

二、provide/inject

传静态数据,值不会被子组件修改

父组件

<div></div>
<script setup lang="ts">
import {provide} from 'vue'
provide('provideStatic','staticData'); //传string

</script>

子组件

<div>{{provideStatic}}</div>
<script setup lang="ts">
import {inject} from 'vue'
const provideStatic=inject('provideStatic');
</script>

传动态数据,值可以被子组件修改(不安全) 父组件

<div></div>
<script setup lang="ts">
import {provide,ref} from 'vue'
const provideStatic=ref('staticData')
provide('provideStatic',provideStatic); //传string

</script>

子组件

<div>{{provideStatic}}</div>
<script setup lang="ts">
import {inject} from 'vue'
const provideStatic=inject('provideStatic');

</script>

使用readonly,使子组件无法直接修改父组件数据,但是可以由父组件provide一个方法以供子组件修改

父组件

<script>
import { provide, ref, readonly } from 'vue'
const readonlyData = ref({ name: '张三' }) 
provide('readonlyData', readonly(readonlyData)) //使用readonly,提供响应性的数据,该值可以不可以直接被子组件修改。但是可以再提供一个方法专门用于修改数据
const changeReadonlyData = (val: string) => { readonlyData.value.name = val } provide('changeReadonlyData', changeReadonlyData)

</script>

子组件

<template>   
    <div>子组件{{ readonlyData.name }}</div>   
    <button @click="changeReadonlyData('李四')">点击修改</button> 
</template>

<script lang="ts">
import { defineComponent, inject } from 'vue'
const readonlyData = inject('readonlyData')
const changeReadonlyData = inject('changeReadonlyData')

三、透传 Attributes

“透传 attribute”指的是传递给一个组件,却没有被该组件声明为props或emits的 attribute 或者 v-on 事件监听器。最常见的例子就是 classstyle 和 id

组件

<button>按钮</button>

传入class 渲染为 click me

组件让的class和type值会被渲染到根节点 inheritAttrs: false禁止自动继承arribute; 如果想透传到子组件特定的元素上可以给指定的元素设置v-bind="$attrs";

父组件(添加type="button")

<MyButton type="button" />
<script setup lang="ts">
import {defineOptions } from 'vue'
defineOptions({
  inheritAttrs: false
})
</script>

子组件

<div class="btn-wrapper"> 
 <button class="btn" v-bind="$attrs">click me</button>
</div>

最终渲染为

<div class="btn-wrapper"> 
 <button class="btn" type="button">click me</button>
</div>

四、vuex状态管理

store/index.js

import { createStore } from 'vuex'

export default createStore({
  state: {
  count: 100, num: 10
  },
  mutations: {
  increment (state) { state.count++ }
  sum (state, num) { state.count += num }
  },
  actions: {
  sum_actions (context, num) { setTimeout(() => {
  context.commit('sum', num)// 通过context去触发mutions中的sum 
  }, 1000) }
  },
  modules: {
  }
})


page页


<script setup>
import { useStore } from 'vuex'
// 引入useStore 方法
const store = useStore();
store.commit('increment')
store.dispatch('sum_actions', num)
console.log(store)
</script>