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 相关文章推荐
JavaScript lodash常见用法系列小结
Aug 24 Javascript
jQuery属性选择器用法示例
Sep 09 Javascript
vue实现一个移动端屏蔽滑动的遮罩层实例
Jun 08 Javascript
Node.js+Express+MySql实现用户登录注册功能
Jul 10 Javascript
vue+axios 前端实现的常用拦截的代码示例
Aug 23 Javascript
Vue CLI3 如何支持less的方法示例
Aug 29 Javascript
angularjs通过过滤器返回超链接的方法
Oct 26 Javascript
jQuery实现的老虎机跑动效果示例
Dec 29 jQuery
ES6 Object方法扩展的应用实例分析
Jun 25 Javascript
微信小程序实现手势滑动卡片效果
Aug 26 Javascript
深入解读VUE中的异步渲染的实现
Jun 19 Javascript
Ajax 的初步实现(使用vscode+node.js+express框架)
Jun 18 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
PHP 验证码的实现代码
2011/07/17 PHP
深入浅出php socket编程
2015/05/13 PHP
PHP简单读取xml文件的方法示例
2017/04/20 PHP
Prototype源码浅析 String部分(三)之HTML字符串处理
2012/01/15 Javascript
js获取url参数值的两种方式
2013/09/10 Javascript
简单介绍JavaScript的变量和数据类型
2015/06/03 Javascript
牛叉的Jquery——Jquery与DOM对象的互相转换及DOM的三种操作
2015/10/29 Javascript
AngularJS入门教程之服务(Service)
2016/07/27 Javascript
JavaScript鼠标特效大全
2016/09/13 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
2016/09/17 Javascript
使用 bootstrap modal遇到的问题小结
2016/11/09 Javascript
vue2 全局变量的设置方法
2018/03/09 Javascript
在vue中使用Autoprefixed的方法
2018/07/27 Javascript
微信小程序实现的日期午别医生排班表功能示例
2019/01/09 Javascript
js中Array对象的常用遍历方法详解
2019/01/17 Javascript
解决vue-cli webpack打包开启Gzip 报错问题
2019/07/24 Javascript
用Python编写一个简单的CS架构后门的方法
2018/11/20 Python
Python 调用 Windows API COM 新法
2019/08/22 Python
python3.6、opencv安装环境搭建过程(图文教程)
2019/11/05 Python
Python数据可视化:箱线图多种库画法
2019/11/06 Python
opencv3/C++ 平面对象识别&amp;透视变换方式
2019/12/11 Python
彻底解决pip下载pytorch慢的问题方法
2021/03/01 Python
全球知名的婚恋交友网站:Match.com
2017/01/05 全球购物
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
大学生职业生涯规划范文
2013/12/31 职场文书
校园歌手大赛策划书
2014/01/17 职场文书
大学生自我鉴定评语
2014/01/27 职场文书
七年级上册语文教学计划
2015/01/22 职场文书
协议书范文
2015/01/27 职场文书
项目经理岗位职责
2015/01/31 职场文书
2015年派出所民警工作总结
2015/04/24 职场文书
反邪教警示教育活动总结
2015/05/09 职场文书
教师节班会主持词
2015/07/06 职场文书
laravel添加角色和模糊搜索功能的实现代码
2021/06/22 PHP
php双向队列实例讲解
2021/11/17 PHP
Python安装使用Scrapy框架
2022/04/12 Python