Vue装饰器中的vue-property-decorator 和 vux-class使用详解

目录
  • 1. 安装
  • 2. vue-property-decorator
  • 3. vuex-class

目前在用vue开发的项目中,都会配合使用TypeScript进行一些约束。为了提高开发效率,往往会使用装饰器来简化我们的代码。

本文主要介绍装饰器vue-property-decorator vux-class的使用。

1. 安装

npm i -S vue-property-decorator
npm i -S vuex-class

2. vue-property-decorator

  • @Component
  • @Prop
  • @PropSync
  • @Model
  • @ModelSync
  • @Watch
  • @Provide
  • @Inject
  • @ProvideReactive
  • @InjectReactive
  • @Emit
  • @Ref
  • @VModel

@Component

import { Vue, Component } from 'vue-property-decorator'

@Component({
 components:{
      componentA,
      componentB,
  }
})
export default class MyComponent extends Vue{

}

相当于:

export default{
  name: 'MyComponent',
  components:{
    componentA,
    componentB,
  }
}

@Prop

@Prop(options: (PropOptions | Constructor[] | Constructor) = {}) decorator

表示:@Prop装饰器接收一个参数,这个参数可以有三种写法:

  • PropOptions:可以使用以下选项:type,required,default,validator
  • Constructor:例如String,Number,Boolean等,指定 prop 的类型
  • Constructor[]:指定 prop 的可选类型

例如:

import { Vue, Component, Prop } from 'vue-property-decorator'

@Component
export default class MyComponent extends Vue {
  @Prop(Number) readonly propA: number | undefined
  @Prop({ default: 'default value' }) readonly propB!: string
  @Prop([String, Boolean]) readonly propC: string | boolean | undefined
}

相当于:

export default {
  name: 'MyComponent',
  props: {
    propA: {
      type: Number,
    },
    propB: {
      default: 'default value',
    },
    propC: {
      type: [String, Boolean],
    },
  },

@PropSync

@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {}) decorator
  • propName 表示父组件传递过来的属性名
  • 父组件要结合.sync来使用

例如:

// child.vue
import { Vue, Component, PropSync } from 'vue-property-decorator'

@Component
export default class MyComponent extends Vue {
  @PropSync('name', { type: String }) syncedName!: string
<!-- parent.vue -->
<template>
  <div>
    <MyComponent  :name.sync="name" />
  </div>
</template>

相当于:

export default {
  name: 'MyComponent',
  props: {
    name: {
      type: String,
    },
  },
  computed: {
    syncedName: {
      get() {
        return this.name
      },
      set(value) {
        this.$emit('update:name', value)
      },
    },
  },
}

@PropSync的工作原理与@Prop类似,除了接受propName作为装饰器的参数之外,它还在幕后创建了一个计算的getter和setter。通过这种方式,您可以像使用常规数据属性一样使用该属性,同时像在父组件中添加.sync修饰符一样简单。

@Model

@Model装饰器允许我们在一个组件上自定义v-model。

@Model(event?: string, options: (PropOptions | Constructor[] | Constructor) = {}) decorator

例如:

import { Vue, Component, Model } from 'vue-property-decorator'

@Component
export default class MyComponent extends Vue {
  @Model('change', { type: Boolean }) readonly checked!: boolean
}

相当于:

export default {
  model: {
    prop: 'checked',
    event: 'change',
  },
  props: {
    checked: {
      type: Boolean,
    },
  },
}

@ModelSync

@ModelSync(propName: string, event?: string, options: (PropOptions | Constructor[] | Constructor) = {}) decorator

例如:

import { Vue, Component, ModelSync } from 'vue-property-decorator'

@Component
export default class MyComponent extends Vue {
  @ModelSync('checked', 'change', { type: Boolean }) readonly checkedValue!: boolean
}

相当于:

export default {
  model: {
    prop: 'checked',
    event: 'change',
  },
  props: {
    checked: {
      type: Boolean,
    },
  },
  computed: {
    checkedValue: {
      get() {
        return this.checked
      },
      set(value) {
        this.$emit('change', value)
      },
    },
  },
}

@Watch

@Watch(path: string, options: WatchOptions = {}) decorator

例如:

import { Vue, Component, Watch } from 'vue-property-decorator'

@Component
export default class MyComponent extends Vue {
  @Watch('child')
  onChildChanged(val: string, oldVal: string) {}

  @Watch('person', { immediate: true, deep: true })
  onPersonChanged1(val: Person, oldVal: Person) {}

  @Watch('person')
  onPersonChanged2(val: Person, oldVal: Person) {}
}

相当于:

export default {
  watch: {
    child: [
      {
        handler: 'onChildChanged',
        immediate: false,
        deep: false,
      },
    ],
    person: [
      {
        handler: 'onPersonChanged1',
        immediate: true,
        deep: true,
      },
      {
        handler: 'onPersonChanged2',
        immediate: false,
        deep: false,
      },
    ],
  },
  methods: {
    onChildChanged(val, oldVal) {},
    onPersonChanged1(val, oldVal) {},
    onPersonChanged2(val, oldVal) {},
  },
}

@Provide | @Inject

@Provide(key?: string | symbol) decorator
@Inject(options?: { from?: InjectKey, default?: any } | InjectKey) decorator

例如:

import { Component, Inject, Provide, Vue } from 'vue-property-decorator'

const symbol = Symbol('baz')

@Component
export class MyComponent extends Vue {
  @Inject() readonly foo!: string
  @Inject('bar') readonly bar!: string
  @Inject({ from: 'optional', default: 'default' }) readonly optional!: string
  @Inject(symbol) readonly baz!: string

  @Provide() foo = 'foo'
  @Provide('bar') baz = 'bar'
}

相当于:

const symbol = Symbol('baz')

export const MyComponent = Vue.extend({
  inject: {
    foo: 'foo',
    bar: 'bar',
    optional: { from: 'optional', default: 'default' },
    baz: symbol,
  },
  data() {
    return {
      foo: 'foo',
      baz: 'bar',
    }
  },
  provide() {
    return {
      foo: this.foo,
      bar: this.baz,
    }
  },
})

@ProvideReactive | @InjectReactive

它们是@provider@Inject的响应式版本。如果父组件修改了提供的值,那么子组件可以捕捉到这种修改。

@ProvideReactive(key?: string | symbol)  decorato
@InjectReactive(options?: { from?: InjectKey, default?: any } | InjectKey) decorator

例如:

const key = Symbol()
@Component
class ParentComponent extends Vue {
  @ProvideReactive() one = 'value'
  @ProvideReactive(key) two = 'value'
}

@Component
class ChildComponent extends Vue {
  @InjectReactive() one!: string
  @InjectReactive(key) two!: string
}

@Emit

@Emit(event?: string) decorator

例如:

import { Vue, Component, Emit } from 'vue-property-decorator'

@Component
export default class MyComponent extends Vue {
  count = 0

  @Emit()
  addToCount(n: number) {
    this.count += n
  }

  @Emit('reset')
  resetCount() {
    this.count = 0
  }

  @Emit()
  returnValue() {
    return 10
  }

  @Emit()
  onInputChange(e) {
    return e.target.value
  }

  @Emit()
  promise() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(20)
      }, 0)
    })
  }
}

相当于:

export default {
  data() {
    return {
      count: 0,
    }
  },
  methods: {
    addToCount(n) {
      this.count += n
      this.$emit('add-to-count', n)
    },
    resetCount() {
      this.count = 0
      this.$emit('reset')
    },
    returnValue() {
      this.$emit('return-value', 10)
    },
    onInputChange(e) {
      this.$emit('on-input-change', e.target.value, e)
    },
    promise() {
      const promise = new Promise((resolve) => {
        setTimeout(() => {
          resolve(20)
        }, 0)
      })

      promise.then((value) => {
        this.$emit('promise', value)
      })
    },
  },
}

@Ref

Ref(refKey?: string) decorator

例如:

import { Vue, Component, Ref } from 'vue-property-decorator'

import AnotherComponent from '@/path/to/another-component.vue'

@Component
export default class MyComponent extends Vue {
  @Ref() readonly anotherComponent!: AnotherComponent
  @Ref('aButton') readonly button!: HTMLButtonElement
}

相当于:

export default {
  computed() {
    anotherComponent: {
      cache: false,
      get() {
        return this.$refs.anotherComponent as AnotherComponent
      }
    },
    button: {
      cache: false,
      get() {
        return this.$refs.aButton as HTMLButtonElement
      }
    }
  }
}

@VModel

@VModel(propsArgs?: PropOptions) decorator

例如:

import { Vue, Component, VModel } from 'vue-property-decorator'

@Component
export default class MyComponent extends Vue {
  @VModel({ type: String }) name!: string
}

相当于:

export default {
  props: {
    value: {
      type: String,
    },
  },
  computed: {
    name: {
      get() {
        return this.value
      },
      set(value) {
        this.$emit('input', value)
      },
    },
  },
}

3. vuex-class

@State@Getter@Action@Mutationnamespace

import Vue from 'vue'
import Component from 'vue-class-component'
import {
  State,
  Getter,
  Action,
  Mutation,
  namespace
} from 'vuex-class'

const someModule = namespace('path/to/module')

@Component
export class MyComponent extends Vue {
  @State('foo') stateFoo
  @State(state => state.bar) stateBar
  @Getter('foo') getterFoo
  @Action('foo') actionFoo
  @Mutation('foo') mutationFoo
  @someModule.Getter('foo') moduleGetterFoo

  // 如果省略参数, 直接使用每一个 state/getter/action/mutation 类型的属性名称
  @State foo
  @Getter bar
  @Action baz
  @Mutation qux

  created () {
    this.stateFoo // -> store.state.foo
    this.stateBar // -> store.state.bar
    this.getterFoo // -> store.getters.foo
    this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
    this.mutationFoo({ value: true }) // -> store.commit('foo', { value: true })
    this.moduleGetterFoo // -> store.getters['path/to/module/foo']
  }
}

到此这篇关于Vue装饰器中的vue-property-decorator 和 vux-class使用详解的文章就介绍到这了,更多相关vue-property-decorator 和 vux-class内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue项目之ES6装饰器在项目实战中的应用

    目录 前言 装饰模式(Decorator) ES6 装饰器 装饰器应用 Validate CatchError Confirmation 总结 参考 前言 在面向对象(OOP)的设计模式中,装饰器的应用非常多,比如在 Java 和 Python 中,都有非常多的应用.ES6 也新增了装饰器的功能,本文会介绍 ES6 的装饰器的概念.作用以及在 Vue + ElementUI 的项目实战中的应用. 装饰模式(Decorator) 装饰模式(Decorator Pattern)允许向一个现有的对象添

  • 关于vue-property-decorator的基础使用实践

    目录 基本使用 基础模板 data数据定义 生命周期钩子 method方法 计算属性 其他选项 装饰器函数 @Component @Prop @PropSync @Emit @Ref @Watch @Model 其他 vue-property-decorator帮助我们让vue支持TypeScript的写法,这个库是基于 vue-class-component库封装实现的. 注:以下环境为 vue2.x + typescript 基本使用 基础模板 和原来的vue单文件组件写法对比,templa

  • VUE中使用TypeScript装饰器实现表单验证的全过程

    目录 前言 装饰器 class-validator 封装Validator 具体使用 小结 前言 最近接触了关于很多TypeScript装饰器的知识,以及class-validator这个用装饰器来做表单验证的包,就萌生了想在vue中使用装饰器来做表单验证的想法.class-validator允许我们在类上通过使用装饰器来完成表单的验证,并且可在浏览器端和node端同时使用.那么接下来先简单介绍一下装饰器和class-validator的用法. 装饰器 装饰器的语法十分简单,只需要在想使用的装饰

  • 详解vue-property-decorator使用手册

    一,安装 npm i -s vue-property-decorator 二,用法 1,@Component(options:ComponentOptions = {}) @Component 装饰器可以接收一个对象作为参数,可以在对象中声明 components ,filters,directives 等未提供装饰器的选项 虽然也可以在 @Component 装饰器中声明 computed,watch 等,但并不推荐这么做,因为在访问 this 时,编译器会给出错误提示 import { Vu

  • Vue中使用装饰器的方法详解

    目录 前言 什么是装饰器? 装饰器的使用 js中使用装饰器 不使用装饰器 vue 中使用装饰器 一些常用的装饰器 1. 函数节流与防抖 2. loading 3. 确认框 总结 前言 相信各位在开发中一定遇到过二次弹框确认相关的需求.不管你使用的是UI框架的二次弹框组件,还是自己封装的弹框组件.都避免不了在多次使用时出现大量重复代码的问题.这些代码的积累导致项目的可读性差.项目的代码质量也变得很差.那么我们如何解决二次弹框代码重复的问题呢?使用装饰器 什么是装饰器? Decorator是ES7的

  • vue-property-decorator用法详解

    vue-property-decorator 这个组件完全依赖于vue-class-component.它具备以下几个属性: @Component (完全继承于vue-class-component) @Emit @Inject @Provice @Prop @Watch @Model Mixins (在vue-class-component中定义); 使用 当我们在vue单文件中使用TypeScript时,引入vue-property-decorator之后,script中的标签就变为这样:

  • vue中typescript装饰器的使用方法超实用教程

    VueConf ,尤大说, Vue 支持 Ts 了,网上关于 Vue + Ts 的资料有点少, 楼主踩了一个星期坑,终于摸明白了 修饰器 的玩法,下面我们就来玩下 Vue 的 decorator 吧 1,data 值的声明 在这里 public 声明的是公有属性, private 声明的是私有属性,私有属性要带 下划线 蓝色框里的内容是声明组件,在每个组件创建时都要带上, Components 中的写法如下 上面是 普通写法 ,下面是 懒加载写法 2.@Prop 父组件传值给子组件 父组件使用

  • Vue框架TypeScript装饰器使用指南小结

    前言 装饰器是一种特殊类型的声明,它能够被附加到 类声明,方法, 访问符,属性或参数 上. 装饰器使用 @expression这种形式, expression求值 后必须为一个函数,它会在 运行时被调用 ,被装饰的声明信息做为参数传入. 本篇先从项目的宏观角度来总结一下Decorator如何组织. 目录 主要的Decorator依赖 vue-class-component vuex-class vue-property-decorator core-decorators 自定义Decorator

  • Vue装饰器中的vue-property-decorator 和 vux-class使用详解

    目录 1. 安装 2. vue-property-decorator 3. vuex-class 目前在用vue开发的项目中,都会配合使用TypeScript进行一些约束.为了提高开发效率,往往会使用装饰器来简化我们的代码. 本文主要介绍装饰器vue-property-decorator 和 vux-class的使用. 1. 安装 npm i -S vue-property-decorator npm i -S vuex-class 2. vue-property-decorator @Comp

  • Python装饰器中@property使用详解

    目录 最初的声明方式 使用装饰器的声明方式 使用装饰器的调用过程 总结 最初的声明方式 在没有@property修饰的情况下,需要分别声明get.set.delete函数,然后初始化property类,将这些方法加载进property中 class C持有property的实例化对象x 对外表现出来C().x时,实际上是调用C()中的x(property类)中设置的fset,fget,fdel,分别对应getx,setx,delx C真正持有的x,是self._x被隐藏起来了 class C(o

  • python如何修改装饰器中参数

    本文实例为大家分享了python修改装饰器中参数的具体代码,供大家参考,具体内容如下 案例: 为分析程序内哪些函数执行时间开销较大,我们需定义一个带timeout参数的装饰器 需求: 统计被装饰函数的运行时间 时间大于timeout时,将此次函数调用记录到log日志中 运行时可以修改timeout的值 如何解决这个问题? 定义一个装饰器,计算函数执行时间,并与timeout比较,当大于timeout时候,通过logging模块打印出日志信息 在包裹函数中添加一个函数,通过这个函数来修改timeo

  • 在vue中安装使用vux的教程详解

    最近因为的工作的原因在弄vue,从后端弄到前端之前一直用js,现在第一次接触vue感觉还挺有意思的,就是自己太菜了,这个脑子呀....不太够用.....页面设计用了一个叫vux的东西,vux可以提供一些组件,用起来还是比较方便的,因为自己比较菜吧,所以有很多东西还是不太深入了解...比如对vux自带样式的修改..希望有大牛看到的话也可以多多指点... 今天就记录一下vux的安装使用吧...... 首先自己要先新建一个vue项目,cmd进入到项目目录下,进行安装 1.在项目目录下安装vux(也可以

  • 基于vue中对鼠标划过事件的处理方式详解

    鼠标事件进行监听 需求中,在一个table(组件)表中,对于其中一列(该列为图片列),当鼠标划过该列的某个单元格子(图片)时,需要展示出该单元格子对应的遮罩层 翻阅了一些博客,发现好多都提到了mouse事件,如mouseover.mouseout.mouseenter.mouseleave,在之后我自己也通过这种方法进行了尝试. <template> <el-table :data="tableData" stripe style="width: 100%&

  • Vue中使用vux配置代码详解

    一.根据vux文档直接安装,无需手动配置 npm install vue-cli -g // 如果还没安装 vue init airyland/vux2 my-project // 创建名为 my-project 的模板 cd my-project // 进入项目 npm install --registry=https://registry.npm.taobao.org // 开始安装 npm run dev // 运行项目 二.想在已创建的Vue工程里引入vux组件 <1>. 在项目里安装

  • 在vue中封装方法以及多处引用该方法详解

    步骤: 1.先建立一个文件,放你想封装的方法:然后导出: 部分代码: 注: 导出这个地方需要特别注意:如果是一个对象的话:export 对象:如果是一个函数的话:export { 函数 } 2.引入文件: 补充知识:vue uni-app 公共组件封装,防止每个页面重复导入 1.公共插件 实现目标,将公共组件或者网络请求直接在this中调用,不需要再页面引用 #例如网络请求 var _this = this; this.api.userInfo({ token: '' } #通用工具 _this

  • Vue中Router路由两种模式hash与history详解

    hash 模式 (默认) 工作原理: 监听网页的hash值变化 -> onhashchange事件, 获取location.hash 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载. 会给用户好像跳转了网页一样的感觉, 但是实际上没有跳转 主要用在单页面应用(SPA) // 模拟原理 // 监听页面hash值变化 window.onhashchange = function(){ // 获取当前url的哈希值 const _hash = locat

  • Vue 中指令v-bind动态绑定及与v-for结合使用详解

    目录 前言: 一. v-bind动态绑定class 1. v-bind动态绑定class(对象语法) 2. v-bind动态绑定class(数组用法) 3.v-bind动态绑定style(对象语法) 4.v-bind动态绑定style(数组语法) 二.v-bind和v-for的结合使用 前言: 在昨天的文章中已经基本介绍了,v-bind的基本使用,可以参考学习,本文是更加具体的解释v-bind的使用,和v-for结合的使用. 一. v-bind动态绑定class 1. v-bind动态绑定cla

  • vue 父组件通过$refs获取子组件的值和方法详解

    前言 在vue项目中组件之间的通讯是很常见的问题,同时也是很重要的问题,我们大致可以将其分为三种情况: 父传子:在父组件中绑定值,在子组件中用props接收 子传父:在父组件中监听一个事件,在子组件中利用$emit触发这个事件并带上数据作为第二个参数,这时父组件中监听事件的回调函数就会被调用,回调函数的参数就是子组件带上来的数据,这样就可以在父组件中使用子组件的数据了, 兄弟之间的传递:我们可以使用事件总线(eventBus)来轻松的解决,其实就是发布订阅者模式 今天我们要看的是父组件如何直接调

随机推荐