当前位置: 首页 > java >正文

Vue 组件二次封装透传slots、refs、attrs、listeners

最近写了一个开源项目,有些地方需要二次封装,需要透传一些数据,需要注意的是ref,我这里使用俩种方式间接传递ref,具体如下:

使用:

import VideoPlayer from './index.js'Vue.use(VideoPlayer)

index.js因为是Vue 2.7 老项目,所以这里用Vue.extend构造函数构造组件这里和 Vue3 不太一样,Vue3 要用 defineComponent创建组件支持hook式和选项式,废弃了Vue.extend(),这里属性继承用$attrs, 事件用 $listeners(Vue3 不需要,在attrs里面),插槽这里固定指定了一个ocr作用域插槽,refs后面说

import Player from "video-player"
import OcrResult from "@/components/ocrResult"
import Vue from "vue"let P = Vue.extend({data() { return { isEnableOcr: true, // 是否启用ocrisEnableWaterMarker: true, // 是否启动水印waterMarkerContent: '水印' // 水印内容} }template: `<Player ref="player"v-bind="$attrs"v-on="$listeners":isEnableOcr="isEnableOcr":isEnableWaterMarker="isEnableWaterMarker":waterMarkerContent="waterMarkerContent"><template v-if="isEnableOcr" #ocr="{ show_ocr, curPlayTime, cancel }"><ocrResultv-model="show_ocr":curPlayTime="curPlayTime * 1000"@cancel="cancel"/></template></Player >`,
})export default {install(Vue) {Vue.component('VideoPlayer', VideoPlayer)}
}

这里如果涉及到多个slot插槽,利用#[name]动态插槽,scope返回作用域插槽数据:

 <template v-for="(_, name) in $slots" #[name]="scope"><slot :name="name" v-bind="scope"></slot></template>

这里涉及到 refs,因为 refs``Vue没有做处理,不想 reactforwardRef,我的处理方式,提前已知组件暴露出什么数据,遍历获取,反之全部遍历获取:

// 透传ref属性,这里劫持下,不然会报错
let attributes = ['_register_emits', 'current', 'duration']attributes.forEach(key => {Object.defineProperty(this, key, {get() {return Reflect.get(this.$refs.player, key, this)},set(v) {throw new Error('Not Allow!')}})
})// for (let key in this.$refs.player) {
//   this[key] = this.$refs.player[key]
// }

还有一种方式,利用render函数渲染 vnode,这样做少去了编译过程,Vue拿到节点compireAST,进而打标记最后生成render函数,render函数渲染时当前利用Vue.extend()生成的组件实例会自动绑定this,而template不会这么做

render(h) {let scopedSlots = {}if (this.isEnableOcr) {scopedSlots.ocr = ({ show_ocr, curPlayTime, cancel }) => {return h(ocrResult, {props: {value: show_ocr,curPlayTime: curPlayTime * 1000},on: {input: (val) => { show_ocr = val; },cancel}});};}return h(Player, {attrs: this.$attrs,on: this.$listeners, // 添加 $listenersprops: {isEnableOcr: this.isEnableOcr,isEnableWaterMarker: this.isEnableWaterMarker,waterMarkerContent: this.waterMarkerContent},scopedSlots})}
http://www.xdnf.cn/news/17893.html

相关文章:

  • 把 AI 装进“冰箱贴”——基于超低功耗语音合成的小屏电子价签
  • StringBoot-SSE和WebFlux方式消息实时推送-默认单向-可增加交互接口
  • C语言中的输入输出函数:构建程序交互的基石
  • 开源数据发现平台:Amundsen Frontend Service 应用程序配置
  • 基于CodeBuddy的2D游戏开发实践:炫酷大便超人核心机制解析
  • NOI Online培训1至26期例题解析(16-20期)
  • week1-[一维数组]传送
  • MySQLl中OFFSET 的使用方法
  • PIDGenRc函数中lpstrRpc的由来和InitializePidVariables函数的关系
  • JMeter性能测试详细版(适合0基础小白学习--非常详细)
  • 基于SpringBoot的救援物资管理系统 受灾应急物资管理系统 物资管理小程序
  • 浏览器环境下AES-GCM JavaScript 加解密程序
  • Elasticsearch ABAC 配置:实现动态、细粒度的访问控制
  • 【C#】跨平台创建你的WinForms窗体应用(WindowsUbuntu)
  • 新手入门 Makefile:FPGA 项目实战教程(一)
  • Java面试场景题大全精简版
  • vue3使用leaflet地图
  • 力扣(LeetCode) ——225 用队列实现栈(C语言)
  • 算法基础 第3章 数据结构
  • C++类与对象核心知识点全解析(中)【六大默认成员函数详解】
  • P1281 [CERC1998] 书的复制
  • TCP 连接管理:深入分析四次握手与三次挥手
  • 2025年大模型安全岗的面试汇总(题目+回答)
  • 扩展用例-失败的嵌套
  • 大语言模型基础
  • 监控插件SkyWalking(二)集成方法
  • 7、C 语言数组进阶知识点总结
  • Mac 新电脑安装cocoapods报错ruby版本过低
  • 仪器制造业推广平台推荐有哪家
  • 计算机视觉(opencv)实战二——图像边界扩展cv2.copyMakeBorder()