vue+Typescript ——插件vue-class-component、vue-property-decorator的使用总结

安装

npm install vue-class-component vue-property-decorator --save-dev

其次,咱来说说它们的区别与联系:

vue-property-decorator社区出品;vue-class-component官方出品

vue-class-component 是 vue 的官方库,作用是用类的方式编写组件,提供了Vue、Component等;

vue-property-decorator深度依赖了vue-class-component,拓展出了更多操作符:@Prop、@Emit、@Inject、@Model、@Provide、@Watch;

简单的示例:

ComponentA.vue

<template>
  <div>
    <p>{{ nameString }}</p> 
    <p>{{ child }}</p> 
    <button @click="comClick">button</button>
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
  props: {
    child: String
  },
  watch:{
    
  },
  components: {
    
  }
})
export default class ComponentA extends Vue {
  // initial data
  nameString = `ComponentA`    
  
  // lifecycle hook
  mounted () {
  this.greet()
  }

  // computed
  get computedMsg () {
  return 'computed ' + this.nameString
  }

  // method
  greet () {
  console.log('greeting: ' + this.nameString)
  }

}
</script>

App.vue

<template>
  <div id="app">

    <component-a ref="a" :child="nameString" @com-click="fromChildEvent" />

  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'
import ComponentA from './ComponentA'

@Component({
  components: {
    'component-a': ComponentA
  }
})
export default class App extends Vue {}
</script>

开始我并不理解这种全新的写法,心想:props watch components 写哪儿呢?

后来知道了,写在 @Component() 修饰器方法里。

开发时正常引入vue-property-decorator就行

引入后写vue代码就是如此,

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

@Component
export default class App extends Vue {
  name:string = 'Jack'

  // computed
  get MyName():string {
    return `My name is ${this.name}`
  }

  // methods
  sayHello():void {
    alert(`Hello ${this.name}`)
  }

  mounted() {
    this.sayHello();
  }
}

相当于

xport default {
  data () {
    return {
      name: 'Jack'
    }
  },

  mounted () {
    this.sayHello()
  },

  computed: {
    MyName() {
      return `My name is ${this.name}`
    }
  },

  methods: {
    sayHello() {
      alert(`Hello ${this.name}`)
    },
  }
}

我遇到问题一堆,以下做个积累总结:

1、写法问题:引入组件和接收父组件传过来的参数

@Component({
  components: {
    XXXX
  },
  props: {
    mapFlag: Number
  }
})

2、获取refs,在其后面加上as HTMLDivElement(不知道是不是这插件引起的直接写就是)

let layoutList:any = this.$refs.layout as HTMLDivElement
或
let fieldCalculate:any = (this as any).$refs.fieldCalculate

3、ts文件 公用方法导出

const xxx = (value: any, type: string) => {
  ...
}
export { xxx, xxx, xxx, xxx }

4、引入装饰器,使用方式@Watch

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

5、引用插件。在shims-vue.d.ts 文件中声明,再在组件中引用

declare module 'vuedraggable' {
  const vuedraggable: any;
  export default vuedraggable;
}

6、@Watch使用

// 监听formula 其变化则显示验证公式按钮
    @Watch('formula', { deep: true, immediate: true }) formulaWatch (newVal:string, oldVal:string) {
      if (newVal !== oldVal) {
       this.grammarSuccess = true
       this.errMsgFlag = false
       this.checkFormulaSuccess = false
      }
    }

7、计算属性方法写法(跟@watch一样,当成方法写就行;加一个关键字get)

get aTagDatasFcomput () { // computed计算属性, 过滤出visible为true的对象来渲染,因为当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中
      return this.aTagDatasF.filter(item => item.visible)
}

8、@Prop的用法

@Prop({
      type: Boolean, // 父组件传递给子组件的数据类型
      required: false, // 是否必填
      default: false // 默认值, 如果传入的是 Object,则要 default: ()=>({}) 参数为函数
  }) collapsed !: boolean
@Prop()private datas!: any

感叹号是非null和非undefined的类型断言,所以上面的写法就是对datas这个属性进行非空断言

9、ts设置html的fontSize

获取时:(不加会报错Object is possibly 'null'.  )

let docEl = document.documentElement as HTMLDivElement // 加上 as HTMLDivElement
发布了44 篇原创文章 · 获赞 15 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Sunshine0508/article/details/93180755