vue3组件常用必学的通信方式(父传子、子传父、父直接获取子、pinia)

787 阅读2分钟

一、父传子

方法一:props传值

  1. 先创建一个子组件引入到父级页面
  2. 定义一个数据加冒号定义一个名称如下:(传入一个数据)
<template>
    <div>
        <MyHeader 
        :title="title"
        ></MyHeader>
    </div>
</template>
<script setup lang='ts'>
    import MyHeader from "../../components/MyHeader.vue";
    import {ref} from 'vue';
    const title = ref('父组件')
</script>
  1. 子组件接收数据
<template>
    <div>
        <h2>{{ title }}</h2>
    </div>
</template>
<script setup lang='ts'>
    // 创建props 
    import {defineProps} from 'vue';
    // 解析获取数据             对应定义的名称
    const {title} = defineProps(['title'])
</script>

效果:

image.png

方法二:快速传值 provide/inject

  • provide/inject 是 Vue 中提供的一对 API。无论层级多深,API 都可以实现父组件到子孙组件的数据传递。
  •    // 父组件中
      <script setup lang='ts'>
          // 引入方法
          import {provide, ref} from 'vue';
          // 定义数据
          const list = ref('父组件')
          // 传递数据
          provide('list', list.value)
      </script>
    

子组件接收

  •    // 子组件中中
      <script setup lang='ts'>
          // 引入方法
          import {inject, ref} from 'vue';
          
          // 接收数据
          const list = inject('list')
      </script>
      <template>
          <div>
              // 显示传递数据
              <h3>{{ list }}</h3>
          </div>
      </template>
    
  • 总结:就两步方便快捷 image.png
  • 效果 image.png

二、子传父

方法一:defineEmits传值

  1. 子页面定义一条数据;
  2. 绑定父组件接收数据的事件;
  3. 将数据放在onMounded挂载阶段钩子函数,具体如下:
<script setup lang='ts'>
    // 子传父 
    import {ref, onMounted, defineEmits} from 'vue';
    // 定义数据
    const msg = ref('我是儿子')
    // 接收父组件绑定的事件
    const emit = defineEmits(['getson'])
    // 放入挂载阶段,传递数据
    onMounted(()=> {
        emit('getson', msg.value)
    })
</script>
  1. 父页面接收数据
<script setup lang='ts'>
    import MyHeader from "../../components/MyHeader.vue";
    import {ref} from 'vue';
    
    // 定义空数据用于接收子数据
    const sondata = ref('没有子数据')

    // 获取子数据函数
    const getson = (zidata: string) => {
        sondata.value = zidata
    }
</script>

<template>
    <div>
        <!-- 展示子数组 -->
        {{ sondata }}
    </div>
</template>

效果:

image.png

方法二:子组件暴露传递数据 defineExpose

  1. 在子组件定义数据解构defineExpose暴露出去
<script setup lang='ts'>
    // 子传父 
    import {ref, defineExpose} from 'vue';
    // 定义数据
    const message = ref('子组件暴露传递数据')
    // 暴露数据
    defineExpose({
        message
    })
</script>
  1. 父组件定义一个数据ref绑定到子组件上
  2. 通过数据名直接点(抛出数据名称)获取数据,如下:
<template>
    <div>
        <MyHeader 
        ref="checkSon"
        ></MyHeader>

        <!-- 展示子数组 -->
        <button @click="btn">点击</button>
        {{ son }}
    </div>
</template>
<script setup lang='ts'>
    import MyHeader from "../../components/MyHeader.vue";
    import {ref} from 'vue';
    
    const checkSon = ref()
    let son = ref()
    
    const btn = () => {
        console.log(checkSon.value.message);
        son.value = checkSon.value.message
    }
</script>

效果:

image.png

三、pinia仓库用法

Pinia 是 Vue 3 的状态管理库,类似于 Vuex,但更轻量级和灵活。通过使用 Pinia,可以在多个组件之间共享和管理状态。

  1. 首先,安装pinia
npm install pinia
  1. 然后,在应用中创建并初始化 Pinia:
import { createPinia } from 'pinia';  
  
const pinia = createPinia();  
  
const app = createApp(App);  
app.use(pinia);  
app.mount('#app');
  1. 建立stores仓库文件夹可复制官网[:](Pinia | The intuitive store for Vue.js (vuejs.org))
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('main', {
  state: () => ({
    count: 0,
  }),
  actions: {
    increment() {
      this.count++
    },
    randomizeCounter() {
      this.count = Math.round(100 * Math.random())
    },
  },
})
  1. 页面调用,Action 可以像函数或者通常意义上的方法一样被调用:
<template>
    <div>
        <button @click="store.randomizeCounter()">Randomize</button>
        // 调用仓库数据显示
        {{ store.count }}
    </div>
</template>
    
<script setup lang='ts'>
    import {useCounterStore} from '../../stores/counter'
    const store = useCounterStore()
    // 将 action 作为 store 的方法进行调用
    store.randomizeCounter()
</script>

效果:

1.gif