使用Vue Mixin功能步骤详解

这次给大家带来使用Vue Mixin功能步骤详解,使用Vue Mixin功能的注意事项有哪些,下面就是实战案例,一起来看一下。

转到用 Typescript 写 Vue 应用以后,经过一轮工具链和依赖的洗礼,总算蹒跚地能走起来了,不过有一个很常用的功能 mixin,似乎还没有官方的解决方案。

既想享受 mixin 的灵活和方便,又想收获 ts 的类型系统带来的安全保障和开发时使用 IntelliSense 的顺滑体验。

vuejs 官方组织里有一个 ‘vue-class-component’ 以及连带推荐的 ‘vue-property-decorator’,都没有相应实现。翻了下前者的 issue,有一条挂了好些时间的待做 feature 就是 mixin 的支持。

也不是什么复杂的事,自己写一个吧。

后注:vue-class-component 6.2.0 开始提供 mixins 方法,和本文的实现思路相似。

实现

import Vue, { VueConstructor } from 'vue'export type VClass = { new(): T} & Pick/** * mixins for class style vue component */function Mixins(c: VClass): VClassfunction Mixins(c: VClass, c1: VClass): VClassfunction Mixins(c: VClass, c1: VClass, c2: VClass): VClassfunction Mixins(c: VClass, ...traits: Array<VClass>): VClass { return c.extend({  mixins: traits })}

登录后复制

声明 VClass 可作为 T 的类构造器。同时通过 Pick 拿到 Vue 的构造器上的静态方法(extend/mixin 之类),如此才能够支持下面这段中的真正实现,通过调用一个 Vue 的子类构造器上的 extend 方法生成新的子类构造器。

function Mixins(c: VClass, ...traits: Array<VClass>): VClass { return c.extend({  mixins: traits })}

登录后复制

至于 ABC 这个纯粹是类型声明的体力活了。

使用

实际使用时:

import { Component, Vue } from 'vue-property-decorator'import { Mixins } from '../../util/mixins'@Componentclass PageMixin extends Vue { title = 'Test Page' redirectTo(path: string) {  console.log('calling reidrectTo', path)  this.$router.push({ path }) }}interface IDisposable { dispose(...args: any[]): any}class DisposableMixin extends Vue { _disposables: IDisposable[] created() {  console.log('disposable mixin created');  this._disposables = [] } beforeDestroy() {  console.log('about to clear disposables')  this._disposables.map((d) => {   d.dispose()  })  delete this._disposables } registerDisposable(d: IDisposable) {  this._disposables.push(d) }}@Component({ template: ` 

{{ title }}

counted: {{ counter }}

`})export default class TimerPage extends Mixins(PageMixin, DisposableMixin) { counter = 0 mounted() { const timer = setInterval(() => { if (this.counter++ >= 3) { return this.redirectTo('/otherpage') } console.log('count to', this.counter); }, 1000) this.registerDisposable({ dispose() { clearInterval(timer) } }) }}count to 1count to 2count to 3calling reidrectTo /otherpageabout to clear disposables

登录后复制

注意到直接 extends Vue 的 DisposableMixin 并不是一个有效的 Vue 组件,也不可以直接在 mixins 选项里使用,如果要被以 Vue.extend 方式扩展的自定义组件使用,记住使用 Component 包装一层。

const ExtendedComponent = Vue.extend({ name: 'ExtendedComponent', mixins: [Component(DisposableMixin)],})

登录后复制

Abstract class

在业务系统中会使用到的 Mixin 其实多数情况下会更复杂,提供一些基础功能,但有些部分需要留给继承者自行实现,这个时候使用抽象类就很合适。

abstract class AbstractMusicPlayer extends Vue { abstract audioSrc: string playing = false togglePlay() {  this.playing = !this.playing }}class MusicPlayerA extends AbstractMusicPlayer { audioSrc = '/audio-a.mp3'}class MusicPlayerB extends AbstractMusicPlayer { staticBase = '/statics' get audioSrc() {  return `${this.staticBase}/audio-b.mp3` }}

登录后复制

但抽象类是无法被实例化的,并不满足 { new(): T } 这个要求,因此只能被继承,而不能被混入,由于同样的原因,抽象类也无法被 ‘vue-class-component’ 的 Component 函数装饰。

这时候只好将实现了的功能写入 Mixin 中,待实现的功能放到接口里,让具体类来实现。

interface IMusicSourceProvider { audioSrc: string}/** * @implements IPlayerImplementation */class PlayerMixin extends Vue { /** @abstract */ audioSrc: string logSrc() {  console.log(this.audioSrc) }}interface IPlayerImplementation extends IMusicSourceProvider {}class RealPlayer extends Mixins(PlayerMixin) implements IPlayerImplementation { audioSrc = '/audio-c.mp3'}

登录后复制

这种欺骗编译器的方式其实还是比较拙劣的,如果一个具体类继承了 PlayerMixin,却没有显示声明实现 IPlayerImplementation ,编译器无法告诉你这个错误。我们只能在代码里小心翼翼写上注释,期待使用者不要忘了这件事。

相信看了本文案例你已经掌握了方法,更多精彩请关注【创想鸟】其它相关文章!

推荐阅读:

分享页面后跳转回首页

在Vue中watch方法使用详解

以上就是使用Vue Mixin功能步骤详解的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2766533.html

(0)
上一篇 2025年3月8日 11:15:29
下一篇 2025年2月25日 04:07:30

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Vue-cropper对图片进行裁剪步骤详解

    这次给大家带来Vue-cropper对图片进行裁剪步骤详解,Vue-cropper对图片进行裁剪的注意事项有哪些,下面就是实战案例,一起来看一下。 一:裁剪的思路: 1-1,裁剪区域:需要进行裁剪首先需要形成裁剪区域,裁剪区域的大小和我们的…

    2025年3月8日 编程技术
    200
  • js闭包使用详解

    这次给大家带来js闭包使用详解,js闭包使用的注意事项有哪些,下面就是实战案例,一起来看一下。 closure is the combination of a function and the lexical environment wit…

    编程技术 2025年3月8日
    200
  • vue常用组件使用详解

    这次给大家带来vue常用组件使用详解,vue常用组件使用的注意事项有哪些,下面就是实战案例,一起来看一下。 项目技术: webpack + vue + element + axois (vue-resource) + less-loader…

    编程技术 2025年3月8日
    200
  • vuex使用详解

    这次给大家带来vuex使用详解,vuex使用的注意事项有哪些,下面就是实战案例,一起来看一下。 1、 npm install vuex 2、 在src 下 新建文件夹 store (为什么是这个单词,vuex 是用来状态管理的,用储存一些组…

    2025年3月8日 编程技术
    200
  • js捆绑TypeScript声明使用详解

    这次给大家带来js捆绑TypeScript声明使用详解,js捆绑TypeScript声明的注意事项有哪些,下面就是实战案例,一起来看一下。 前话 TypeScript是注意事项类型的超集,这是TypeScript的文档介绍的一句话,那么他们…

    2025年3月8日
    200
  • d.ts文件使用详解

    这次给大家带来d.ts文件使用详解,使用d.ts文件的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 本文主要讲怎么写一个typescript的描述文件(以d.ts结尾的文件名,比如xxx.d.ts)。 最近开始从js转ts了。但是…

    2025年3月8日 编程技术
    200
  • vue render开发实例详解

    这次给大家带来vue render开发实例详解,vue render开发的注意事项有哪些,下面就是实战案例,一起来看一下。 简介 在使用Vue进行开发的时候,大多数情况下都是使用template进行开发,使用template简单、方便、快捷…

    编程技术 2025年3月8日
    200
  • Koa项目搭建步骤详解

    这次给大家带来Koa项目搭建步骤详解,Koa项目搭建的注意事项有哪些,下面就是实战案例,一起来看一下。 本文介绍了Koa项目搭建过程详细记录,分享给大家,具体如下: Java中的Spring MVC加MyBatis基本上已成为Java We…

    2025年3月8日
    200
  • 编写d.ts文件步骤详解

    这次给大家带来编写d.ts文件步骤详解,编写d.ts文件的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 本文主要讲怎么写一个typescript的描述文件(以d.ts结尾的文件名,比如xxx.d.ts)。 最近开始从js转ts了。…

    2025年3月8日 编程技术
    200
  • 实现圆弧形拖动进度条步骤详解

    这次给大家带来实现圆弧形拖动进度条步骤详解,实现圆弧形拖动进度条的注意事项有哪些,下面就是实战案例,一起来看一下。 先上效果图 因为需求需要实现这个效果图 非原生实现, 难点1:绘制 使用svg 难点2:点击事件的处理 难点3:封装 由于绘…

    2025年3月8日
    200

发表回复

登录后才能评论