• vue3组件通信


    组件通信总结起来有这几种:

    1. 父子组件通信 props/emit
    2. 平行组件通信 vuex pinia provide/inject attrs/listeners
    3. 跨组件通信 vuex provide/inject pinia

    在项目 components 文件夹下分别创建 User, List, Info .vue单文件

    依赖注入

    provide()提供一个值,可以被后代组件注入

    provide() 接受两个参数:第一个参数是要注入的 key,可以是一个字符串或者一个 symbol,第二个参数是要注入的值

    当使用 TypeScript 时,key 可以是一个被类型断言为 InjectionKey 的 symbol。InjectionKey 是一个 Vue 提供的工具类型,继承自 Symbol,可以用来同步 provide() 和 inject() 之间值的类型。

    与注册生命周期钩子的 API 类似,provide() 必须在组件的 setup() 阶段同步调用。

    在 App.vue文件中注入要传给其他组件的值:

    App.vue
    <script setup lang="ts">
    import { ref, provide } from 'vue'
    import List from './components/List.vue'
    import User from './components/User.vue'
    
    const count = ref<number>(1)
    const msg = ref<string>('hello world')
    
    const updateData = (): void => {
      console.log('我是来自爷爷组件的方法')
    }
    const dataObj = ref<any>({
      name: 'zhangsan',
      age: 20,
      gender: 'male',
      updateData,
    })
    
    const clickHandle = (): any => {
      console.log(count.value)
      count.value++
      /**在js中需要通过 .value来访问变量,
      *因为 count是 proxy代理的名称 */
    }
    
    provide('msg', msg)
    provide('dataObj', dataObj)
    
    const getDataFromSon = (params: string): any => {
      console.log('来自子组件的数据', params)
    }
    </script>
    
    <template>
      <!--在模板中直接使用变量-->
      <h1>这是一个 vue3 项目 {{ count }}</h1>
    
      <button @click="count++">{{ count }}</button>
    
      <button @click="clickHandle">增加</button>
       <!--List组件 App传递数据给 List -->
      <List @getDataFromSon="getDataFromSon" :dataToSon="msg" />
    
      <User />
    </template>
    
    <style scoped></style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    inject()

    注入一个由祖先组件或整个应用 (通过 app.provide()) 提供的值

    第一个参数是注入的 key。Vue 会遍历父组件链,通过匹配 key 来确定所提供的值。如果父组件链上多个组件对同一个 key 提供了值,那么离得更近的组件将会“覆盖”链上更远的组件所提供的值。如果没有能通过 key 匹配到值,inject() 将返回 undefined,除非提供了一个默认值。

    第二个参数是可选的,即在没有匹配到 key 时使用的默认值

    与注册生命周期钩子的 API 类似,inject() 必须在组件的 setup() 阶段同步调用

    Info.vue
    <script setup lang="ts">
    import { ref, inject } from 'vue'
    import HelloWorld from './HelloWorld.vue'
    const txt = ref<string>('hello vue3')
    const message = inject<string>('msg')
    const dataObj = inject<any>('dataObj')
    </script>
    <template>
      <h1>{{ txt }} {{ message }}</h1>
    
      <h2>{{ dataObj.name }}</h2>
    
      <button @click="dataObj.updateData">调用爷爷组件的方法</button>
    
      <Hello-World />
    </template>
    <style scoped></style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    List.vue 父子组件通信
    <script setup lang="ts">
    import { ref, reactive, onMounted, watch, computed } from 'vue'
    import Info from './Info.vue'
    
    interface Book {
      title: string
      year?: number
    }
    const book: Book = reactive({ title: 'Vue 3 指引' })
    const txt = ref<string>('')
    const list = ref<string[]>([])
    
    // 通过 defineEmits来发布定义在父组件中的事件
    const emits = defineEmits(['getDataFromSon'])
    // 通过 defineProps来接受父组件传递过来的值
    const props = defineProps<{ dataToSon: string }>()
    
    const saveText = (): any => {
      if (txt) list.value.push(txt.value)
      emits('getDataFromSon', txt.value)
      console.log('来自父组件的数据:', props.dataToSon)
      txt.value = ''
    }
    computed(() => {})
    watch(
      () => txt.value,
      (txt, preText) => {
        console.log(txt, preText)
      }
    )
    onMounted(() => {
      console.log('Dom 已经挂在完毕')
    })
    </script>
    
    <template>
      <input
        type="text"
        v-model="txt"
        @keyup.enter="saveText"
        placeholder="请输入内容"
      />
      <div class="list">
        <ul>
          <li v-for="item in list" :key="item">
            {{ item }}
          </li>
        </ul>
      </div>
      <Info />
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
  • 相关阅读:
    基于flask的网站如何使用https加密通信-问题记录
    Git简介
    基于SpringBoot+Mybatis+layui的学生成绩管理系统
    电脑重装系统后安全中心有个黄色感叹号如何处理
    华贝甄选干细胞科技,揭秘生命修复的奥秘
    Leetcode 1417. Reformat The String
    STM32F4使用ucosii时操作浮点数卡死的问题
    TensorFlow2从磁盘读取图片数据集的示例(tf.data.Dataset.list_files)
    java-net-php-python-ssmA公司运维管理系统计算机毕业设计程序
    YOLOv5代码解读[03] utils/loss.py文件解析
  • 原文地址:https://blog.csdn.net/qyl_0316/article/details/127804000