• 08 【Props 组件事件】


    15.Props

    15.1 Props 声明#

    Props 是一种特别的 attributes,你可以在组件上声明注册。要传递给子组件内容,我们必须在组件的 props 列表上声明它。

    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    defineProps 是一个仅

    • 1
    • 2
    • 3

    这声明了一个组件可能触发的所有事件,还可以对事件的参数进行验证。同时,这还可以让 Vue 避免将它们作为原生事件监听器隐式地应用于子组件的根元素。

    defineProps 类似,defineEmits 仅可用于

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    defineEmits()不能在子函数中使用。如上所示,它必须直接放置在

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如果你正在搭配 TypeScript 使用

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    现在 v-model 也可以在这个组件上正常工作了:

    
    
    • 1

    在演练场中尝试一下

    v-model 的参数#

    默认情况下,v-model 在组件上都是使用 modelValue 作为 prop,并以 update:modelValue 作为对应的事件。我们可以通过给 v-model 指定一个参数来更改这些名字:

    
    
    • 1

    在这个例子中,子组件应声明一个 title prop,并通过触发 update:title 事件更新父组件值:

    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在演练场中尝试一下

    16.6 关于组件使用原生事件

    这是我目前想到的,如果有错误,请指出

    Vue3移除v-on.native修饰符,那如何在组件上触发原生事件呢?

    其实可以利用属性继承,详细可以看17.1 Attributes 继承

    注意要写根标签,因为这个事件只会继承在根标签因为Vue3不强制写根标签,所以会出现多个标签,这时这个事件找不到根标签会发出警告,解决的方法在Attributes 继承里面说了

    父组件App.vue

    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    子组件Son.vue

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    image-20220809130712485

    16.7 vue3中事件总线

    16.7.1 插件

    1.在vue3中,创建方法改成了createApp({}),prototype属性也被取消了,因此无法使用之前Vue.prototype.$bus = new Vue()的方式使用事务总线。

    2.且在vue3中移除了 o n , on, on,off方法,因此官方推荐:事件总线模式可以被替换为使用外部的、实现了事件触发器接口的库,例如 mitt 或 tiny-emitter。

    3.首先安装mitt:npm install --save mitt

    4.在代码中使用:

    import mitt from "mitt"
    import {createApp} from "vue"
     
    const app = createApp(App)//正常配置
    //挂载事务总线
    app.config.globalProperties.$bus = mitt()
     
    //在组件A中使用事务总线触发某个动作
    import {getCurrentInstance } from 'vue';
    const instance = getCurrentInstance();
    function send() {
      instance.proxy.$bus.emit('receive', '你是一个瓜皮');
    }
     
    //在组件B中监听动作的发生
    import { getCurrentInstance } from 'vue';
    let data = ref('');
    
    const instance = getCurrentInstance();
    instance.proxy.$bus.on('receive', str => {
      console.log('来数据了');
      data.value = str;
    });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    对于ts文件的写法

    import { createApp } from 'vue'
    import App from './App.vue'
    import mitt from 'mitt'
     
    const Mitt = mitt()
     
    //TypeScript注册
    // 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
    declare module "vue" {
        export interface ComponentCustomProperties {
            $bus: typeof Mitt
        }
    }
     
    const app = createApp(App)
     
    //Vue3挂载全局API
    app.config.globalProperties.$Bus = Mit
     
    app.mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    16.7.2 手写

    Bus.ts

    import * as Console from 'console'
    
    
    type BusClass = {
      emit: (name: string) => void,
      on: (name: string, callback: Function) => void
    }
    
    type CallbackName = string | number | symbol
    
    type List = {
      [key: CallbackName]: Array<Function>
    }
    
    class Bus implements BusClass {
      list: List
    
      constructor() {
        this.list = {}
      }
    
      emit(name: string, ...args: Array<any>) {
        let callbacks: Array<Function> | undefined = this.list[name]
        if (callbacks === undefined) {
          console.warn(`event "${name}" is not bound`)
          return
        }
        callbacks.forEach(callback => {
          console.log('emit', this)
          callback.apply(this, args)  // this 为 Bus.ts 导出的实例, on方法如果使用ArrowFunction, 则无法使用this
        })
      }
    
      on(name: string, callback: Function) {
        let callbacks: Array<Function> = this.list[name] || []
        callbacks.push(callback)
        this.list[name] = callbacks
      }
    }
    
    export default new Bus < BusParams >()
    
    • 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

    挂载到全局Vue config
    或者单独的页面引入 import Bus from ‘bus.ts’
    Bus.emit 触发,Bus.on监听

    image-20220810185533253

    main.ts

    import { createApp } from 'vue'
    import App from './App.vue'
    import Bus from "./utils/Bus"
    const app = createApp(App);
    app.config.globalProperties.$bus = Bus;
    app.mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用方法和插件一模一样

  • 相关阅读:
    EM@坐标@函数@图象的对称和翻折变换
    长整型(Long Integer)在Python中是一种用于表示大整数的数据类型
    数组排序,实现中间数字最大,向两边越来越小的排序
    MySQL数据库之多表查询
    C语言王国——深入自定义类型(联合体、枚举)
    AWS认证SAA-C03每日一题
    CSDN专栏设置
    杨辉三角(Java实现)
    spark向hadoop写入文件后,查路径为目录,无法查值
    java毕业设计——基于java+JSP+Oracle的记账管理系统设计与实现——记账管理系统
  • 原文地址:https://blog.csdn.net/DSelegent/article/details/126237707