vue-property-decorator用法详解


Posted in Javascript onDecember 12, 2019

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中的标签就变为这样:

<script lang="ts">
  import {Vue, Component} from 'vue-property-decorator';

  @Component({})
  export default class "组件名" extends Vue{
    ValA: string = "hello world";
    ValB: number = 1;
  }
</script>

等同于

<script lang="es6">
  import Vue from 'vue';

  export default {
    data(){
      return {
        ValA: 'hello world',
        ValB: 1
      }
    }
  }
</script>

总结: 对于data里的变量对顶,我们可以直接按ts定义类变量的写法写就可以

那么如果是计算属性呢? 这就要用到getter了.

<script lang="ts">
  import {Vue, Component} from 'vue-property-decorator';

  @Component({})
  export default class "组件名" extends Vue{
    get ValA(){
      return 1;
    }
  }
</script>

等同于

<script lang="es6">
  import Vue from 'vue';

  export default {
    computed: {
      ValA: function() {
        return 1;
      }
    }
  }
</script>

总结: 对于Vue中的计算属性,我们只需要将该计算属性名定义为一个函数,并在函数前加上get关键字即可.

原本Vue中的computed里的每个计算属性都变成了在前缀添加get的函数.

@Emit

关于Vue中的事件的监听与触发,Vue提供了两个函数$emit和$on.那么在vue-property-decorator中如何使用呢?

这就需要用到vue-property-decorator提供的@Emit属性.

<script lang="ts">
  import {Vue, Component, Emit} from 'vue-property-decorator';

  @Component({})
  export default class "组件名" extends Vue{
    mounted(){
      this.$on('emit-todo', function(n) {
        console.log(n)
      })

      this.emitTodo('world');
    }

      @Emit()
    emitTodo(n: string){
      console.log('hello');
    }
  }
</script>

运行上面的代码会打印 'hello' 'world', 为什么呢? 让我们来看看它等同于什么

<script lang="es6">
  import Vue from 'vue';

  export default {
    mounted(){
      this.$on('emit-todo', function(n) {
        console.log(n)
      })

      this.emitTodo('world');
    },
    methods: {
      emitTodo(n){
        console.log('hello');
        this.$emit('emit-todo', n);
      }
    }
  }
</script>

可以看到,在@Emit装饰器的函数会在运行之后触发等同于其函数名(驼峰式会转为横杠式写法)的事件, 并将其函数传递给$emit.
如果我们想触发特定的事件呢,比如在emitTodo下触发reset事件:

<script lang="ts">
  import {Vue, Component, Emit} from 'vue-property-decorator';

  @Component({})
  export default class "组件名" extends Vue{

    @Emit('reset')
    emitTodo(n: string){

    }
  }
</script>

我们只需要给装饰器@Emit传递一个事件名参数reset,这样函数emitTodo运行之后就会触发reset事件.

总结:在Vue中我们是使用$emit触发事件,使用vue-property-decorator时,可以借助@Emit装饰器来实现.@Emit修饰的函数所接受的参数会在运行之后触发事件的时候传递过去.

@Emit触发事件有两种写法

  • @Emit()不传参数,那么它触发的事件名就是它所修饰的函数名.
  • @Emit(name: string),里面传递一个字符串,该字符串为要触发的事件名.

@Watch

我们可以利用vue-property-decorator提供的@Watch装饰器来替换Vue中的watch属性,以此来监听值的变化.

在Vue中监听器的使用如下:

export default{
  watch: {
    'child': this.onChangeValue
      // 这种写法默认 `immediate`和`deep`为`false`
    ,
    'person': {
      handler: 'onChangeValue',
      immediate: true,
      deep: true
    }
  },
  methods: {
    onChangeValue(newVal, oldVal){
      // todo...
    }
  }
}

那么我们如何使用@Watch装饰器来改造它呢?

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

@Watch('child')
onChangeValue(newVal: string, oldVal: string){
  // todo...
}

@Watch('person', {immediate: true, deep: true})
onChangeValue(newVal: Person, oldVal: Person){
  // todo...
}

总结:  @Watch使用非常简单,接受第一个参数为要监听的属性名 第二个属性为可选对象.@Watch所装饰的函数即监听到属性变化之后的操作.

@Prop

我们在使用Vue时有时会遇到子组件接收父组件传递来的参数.我们需要定义Prop属性.

比如子组件从父组件接收三个属性propA,propB,propC.

  • propA类型为Number
  • propB默认值为default value
  • propC类型为String或者Boolean
export default {
 props: {
  propA: {
   type: Number
  },
  propB: {
   default: 'default value'
  },
  propC: {
   type: [String, Boolean]
  },
 }
}

我们使用vue-property-decorator提供的@Prop可以将上面的代码改造为如下:

<script lang="ts">
  import {Vue, Component, Prop} from 'vue-property-decorator';

  @Component({})
  export default class "组件名" extends Vue{
    @Prop(Number) propA!: number;
    @Prop({default: 'default value'}) propB!: string;
    @propC([String, Boolean]) propC: string | boolean;
  }
</script>

这里 !和可选参数?是相反的, !告诉TypeScript我这里一定有值.

总结: @Prop接受一个参数可以是类型变量或者对象或者数组.@Prop接受的类型比如Number是JavaScript的类型,之后定义的属性类型则是TypeScript的类型.

Mixins

在使用Vue进行开发时我们经常要用到混合,结合TypeScript之后我们有两种mixins的方法.

一种是vue-class-component提供的.

//定义要混合的类 mixins.ts
import Vue from 'vue';
import Component from 'vue-class-component';

@Component // 一定要用Component修饰
export default class myMixins extends Vue {
  value: string = "Hello"
}
// 引入
import Component {mixins} from 'vue-class-component';
import myMixins from 'mixins.ts';

@Component
export class myComponent extends mixins(myMixins) {
             // 直接extends myMinxins 也可以正常运行
   created(){
     console.log(this.value) // => Hello
  }
}

第二种方式是在@Component中混入.

我们改造一下mixins.ts,定义vue/type/vue模块,实现Vue接口

// mixins.ts
import { Vue, Component } from 'vue-property-decorator';


declare module 'vue/types/vue' {
  interface Vue {
    value: string;
  }
}

@Component
export default class myMixins extends Vue {
  value: string = 'Hello'
}

混入

import { Vue, Component, Prop } from 'vue-property-decorator';
import myMixins from '@static/js/mixins';

@Component({
  mixins: [myMixins]
})
export default class myComponent extends Vue{
  created(){
    console.log(this.value) // => Hello
  }
}

总结: 两种方式不同的是在定义mixins时如果没有定义vue/type/vue模块, 那么在混入的时候就要继承该mixins; 如果定义vue/type/vue模块,在混入时可以在@Component中mixins直接混入.

@Model

Vue组件提供model: {prop?: string, event?: string}让我们可以定制prop和event.
默认情况下,一个组件上的v-model 会把 value用作 prop且把 input用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop来达到不同的目的。使用model选项可以回避这些情况产生的冲突。

下面是Vue官网的例子

Vue.component('my-checkbox', {
 model: {
  prop: 'checked',
  event: 'change'
 },
 props: {
  // this allows using the `value` prop for a different purpose
  value: String,
  // use `checked` as the prop which take the place of `value`
  checked: {
   type: Number,
   default: 0
  }
 },
 // ...
})
<my-checkbox v-model="foo" value="some value"></my-checkbox>

上述代码相当于:

<my-checkbox
 :checked="foo"
 @change="val => { foo = val }"
 value="some value">
</my-checkbox>

即foo双向绑定的是组件的checke, 触发双向绑定数值的事件是change

使用vue-property-decorator提供的@Model改造上面的例子.

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

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

总结, @Model()接收两个参数, 第一个是event值, 第二个是prop的类型说明, 与@Prop类似, 这里的类型要用JS的. 后面在接着是prop和在TS下的类型说明.

暂时常用的就这几个,还有@Provice和@Inject等用到了再写.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
在IE下:float属性会影响offsetTop的取值
Dec 22 Javascript
JavaScript自执行闭包的小例子
Jun 29 Javascript
通过一段代码简单说js中的this的使用
Jul 23 Javascript
JavaScript中定义函数的三种方法
Mar 12 Javascript
JS实现灵巧的下拉导航效果代码
Aug 25 Javascript
xmlplus组件设计系列之树(Tree)(9)
May 02 Javascript
利用Jasmine对Angular进行单元测试的方法详解
Jun 12 Javascript
node文字生成图片的示例代码
Oct 26 Javascript
Vue拖拽组件开发实例详解
May 11 Javascript
JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】
Feb 22 Javascript
vue-cli配置全局sass、less变量的方法
Jun 06 Javascript
测量JavaScript函数的性能各种方式对比
Apr 27 Javascript
JS实现动态倒计时功能(天数、时、分、秒)
Dec 12 #Javascript
JavaScript Reflect Metadata实现详解
Dec 12 #Javascript
JS动态显示倒计时效果
Dec 12 #Javascript
如何用vue-cli3脚手架搭建一个基于ts的基础脚手架的方法
Dec 12 #Javascript
js实现倒计时秒杀效果
Mar 25 #Javascript
vue el-table实现自定义表头
Dec 11 #Javascript
Vue如何获取数据列表展示
Dec 11 #Javascript
You might like
日本十大惊悚动漫
2020/03/04 日漫
Symfony2使用Doctrine进行数据库查询方法实例总结
2016/03/18 PHP
Yii框架数据库查询、增加、删除操作示例
2019/10/14 PHP
IE bug table元素的innerHTML
2010/01/11 Javascript
js模仿jquery的写法示例代码
2013/06/16 Javascript
JS关闭窗口与JS关闭页面的几种方法小结
2013/12/17 Javascript
javascript原型链继承用法实例分析
2015/01/28 Javascript
jquery 设置style:display的方法
2015/01/29 Javascript
JS实现双击内容变为可编辑状态
2017/03/03 Javascript
原生js更改css样式的两种方式
2017/03/15 Javascript
使用vue制作FullPage页面滚动效果
2017/08/21 Javascript
基于vue.js的分页插件详解
2017/11/27 Javascript
vue 下列表侧滑操作实例代码详解
2018/07/24 Javascript
js中let能否完全替代IIFE
2019/06/15 Javascript
PHP读取远程txt文档到数组并实现遍历
2020/08/25 Javascript
Python数据结构之翻转链表
2017/02/25 Python
python中安装模块包版本冲突问题的解决
2017/05/02 Python
Windows系统下多版本pip的共存问题详解
2017/10/10 Python
Python 给某个文件名添加时间戳的方法
2018/10/16 Python
解决pycharm py文件运行后停止按钮变成了灰色的问题
2018/11/29 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
2019/03/30 Python
详解python 模拟豆瓣登录(豆瓣6.0)
2019/04/18 Python
django框架cookie和session用法实例详解
2019/12/10 Python
在Sublime Editor中配置Python环境的详细教程
2020/05/03 Python
解决selenium+Headless Chrome实现不弹出浏览器自动化登录的问题
2021/01/09 Python
菲律宾酒店预订网站:Hotels.com菲律宾
2017/07/12 全球购物
会计岗位职责范本
2014/03/07 职场文书
二年级班级文化建设方案
2014/05/10 职场文书
企业员工集体活动方案
2014/08/17 职场文书
成都人事代理协议书
2014/10/25 职场文书
2014年银行工作总结范文
2014/11/12 职场文书
教师辞职信范文
2015/02/28 职场文书
廉洁自律承诺书范文
2015/04/28 职场文书
转变工作作风心得体会
2016/01/23 职场文书
Redis遍历所有key的两个命令(KEYS 和 SCAN)
2021/04/12 Redis
为Java项目添加Redis缓存的方法
2021/05/18 Redis