惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
InfoQ
C
CERT Recently Published Vulnerability Notes
The Last Watchdog
The Last Watchdog
P
Proofpoint News Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
T
Tenable Blog
博客园 - 三生石上(FineUI控件)
P
Privacy & Cybersecurity Law Blog
Simon Willison's Weblog
Simon Willison's Weblog
Jina AI
Jina AI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tor Project blog
博客园_首页
F
Fortinet All Blogs
博客园 - Franky
Latest news
Latest news
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hugging Face - Blog
Hugging Face - Blog
D
Docker
Project Zero
Project Zero
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MongoDB | Blog
MongoDB | Blog
F
Full Disclosure
D
DataBreaches.Net
Google DeepMind News
Google DeepMind News
Cisco Talos Blog
Cisco Talos Blog
Y
Y Combinator Blog
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
H
Help Net Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Blog — PlanetScale
Blog — PlanetScale
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Schneier on Security
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
PCI Perspectives
PCI Perspectives
Cloudbric
Cloudbric
V
Visual Studio Blog
Recorded Future
Recorded Future
人人都是产品经理
人人都是产品经理

博客园 - 金色海洋(jyk)

【vue3】详解单向数据流,大家千万不用为了某某而某某了。 Vue3.3 的新功能的体验(下):泛型组件(Generic Component) 与 defineSlots Vue3.3 的新功能的一些体验 【摸鱼神器】UI库秒变低代码工具——表单篇(二)子控件 【摸鱼神器】UI库秒变低代码工具——表单篇(一)设计 用Typescript 的方式封装Vue3的表单绑定,支持防抖等功能。 【摸鱼神器】UI库秒变LowCode工具——列表篇(二)维护json的小工具 【摸鱼神器】UI库秒变LowCode工具——列表篇(一)设计与实现 【摸鱼神器】一次搞定 vue3的 路由 + 菜单 + tabs 被迫开始学习Typescript —— vue3的 props 与 interface 被迫开始学习Typescript —— class 被迫开始学习Typescript —— interface 结合 Vuex 和 Pinia 做一个适合自己的状态管理 nf-state 一篇文章说清 webpack、vite、vue-cli、create-vue 的区别 从 jQuery 到 Vue3 的快捷通道 简单了解一下pinia的结构 nf-Press —— 在线文档也可以加载组件和编写代码 vite2 打包的时候vendor-xxx.js文件过大的解决方法 基于 vite2 + Vue3 写一个在线帮助文档工具
Vue3实现组件级基类的几种方法
金色海洋(jyk) · 2023-04-28 · via 博客园 - 金色海洋(jyk)

2023-04-28 08:20  金色海洋(jyk)  阅读(678)  评论()    收藏  举报

Vue3的组件有三种代码组织方式

  1. 纯Option API (不含setup)
  2. option API + setup
  3. 纯 setup (即composition API)

对于这三种形式,设置基类的方法也略有不同。

使用 mixins、extends

vue3提供了 mixins和extends,但是尝试之后发现这两种方法只支持纯OptionAPI,设置的data会被识别,但是设置的setup里return 的 reactive,完全无效,setup也没有被执行。
所以这种方式只能使用于第一种方式。

使用 hooks (function、class)

既然官方没有提供,那么我们自己来想想办法。我们先观察一下组件的代码(第二种情况):

<template>
  <!--模板-->
  举例
</template>

<script lang="ts">
  import { defineComponent } from 'vue'

  export default defineComponent({
    name: 'ui-core-',
    components: {
      // 注册共用组件
    },
    props: {
      // 定义共用属性
    },
    setup(props, context) {
      // 各种共用操作
      _logger()
      _setTitle()
      // 共用成员
      const foo = reactive ({})
      return {
        foo
      }
    }
  })
</script>

defineComponent 方法接收一个对象,对象需要有特定的几个属性,比如name、components、props、setup等。
那么也就是说,我们可以做一个函数返回这样的对象即可。
比如我们先建立一个js(或则ts)文件:

export function base (name, callback) {
  return {
    name: 'ui-' + name,
    components: {
      // 注册共用组件
    },
    props: {
      // 定义共用属性
    },
    setup(props, context) {
      // 各种共用操作
      _logger()
      _setTitle()
      // 共用成员
      const foo = reactive ({})

      // 执行其他操作
      const re = callback(props, context)
      return {
        foo,
        ...re
      }
    }
  }
}

有点像模板模式。

传入name和一个回调函数,props, context作为参数进行传递。内部成员也可以作为参数传递。
这样一个简单的基类就做成了,如果你觉得function不好看,那么可以换成class。

export default class BaseComponent {
  name: string
  components: any
  props: any
  setup: any

  constructor (name: string, callback: (props: any, context: any) => any) {
    this.name = name
    this.components = {}
    this.props = {}
    this.setup = (props: any, context: any) => {
      // 各种共用操作
      _logger()
      _setTitle()

      // 执行其他操作
      const re = callback(props, context)

      return {
        ...re
      }
    }
    
  }
}

有了class之后,还可以设置子类,不过感觉有点繁琐。总之,反正可以实现就对了。

script setup怎么办

上述这种方法应该也是可以支持纯composition API的,但是有点小问题,defineProps 和 defineEmits 并不是普通 js 函数,而是一种“宏”。
引用官网的解释:

defineProps 和 defineEmits 都是只能在 <script setup> 中使用的编译器宏。他们不需要导入,且会随着 <script setup> 的处理过程一同被编译掉。
也就是说 defineXXX系列 只有在 <script setup> 标签内部才会被识别,如果在单独的js文件里面,不会被识别。

这就导致 defineProps 和 defineEmits 无法做成基类的形式。
如果需要的基类不涉及 defineProps 和 defineEmits 的话,那么还是可以在单独的js文件里面定义一个function或者class的,(即做一个综合的hooks)。

如果涉及 defineProps 和 defineEmits,那么,我也没想出来办法。(只能第二种方式)