vue-typescript入门

原文链接:https://www.jianshu.com/p/8ba2cdbfabd7

这里主要讲下vue cli 3.x 的typescript集成

一、起步

1、安装

npm install -g @vue/cli
# OR
yarn global add @vue/cli

2、创建项目

安装的时候要自定义配置,选择typescript相关

3、集成开发环境

建议使用vscode编辑器,因为vscode集成了typescript,可以开箱即用

二、相关依赖介绍

Vue TypeScript支持:https://cn.vuejs.org/v2/guide/typescript.html

package.json

"dependencies": {
    "core-js": "^2.6.5",
    "vue": "^2.6.10",
    "vue-class-component": "^7.0.2",
    "vue-property-decorator": "^8.1.0",
    "vue-router": "^3.0.3",
    "vuex": "^3.0.1"
}

vue、vue-router、vuex就不讲了,大家也都了解,重点讲下

  • core-js
  • vue-class-component
  • vue-property-decorator

1、 core-js

JavaScript的模块化标准库。包括ECMAScript到2019年的polyfills:promises, symbols, collections, iterators, typed arrays许多其他功能、ECMAScript proposals、一些跨平台的WHATWG / W3C功能和建议,比如URL。您可以只加载所需的特性,或者使用它而不污染全局名称空间。

2、 vue-class-component

vue-class-component是vue作者尤大推出的一个支持使用class方式来开发vue单文件组件的库

示例:

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <p>{{ word }}</p>
  </div>
</template>

<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
@Component
export default class About extends Vue {
  word: string = "天涯共此时";
}
</script>

3、 vue-property-decorator

vue-property-decorator依赖于vue-class-component并且扩展了其他功能,如下:

  • @Prop
  • @Model
  • @Watch
  • @Emit
  • @Inject
  • @Provide
  • @Component (provided by vue-class-component)
  • Mixins(在vue-class-component中定义)

1) @Prop

HelloWorld.vue

<template>
  <div>
    {{ msg }}
  </div>
</template>

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

@Component
export default class HelloWorld extends Vue {
  @Prop() private msg!: string;
}  
</script>

!是和?相对的,是typescript的语法,表示强制解析(也就是告诉typescript编译器,我这里一定有值)。你写?的时候再调用,typescript会提示可能为undefined

Home.vue

<template>
  <div>
    <HelloWorld msg="hello vue typscript"/>
  </div>
</template>

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

@Component({
  components: {
    HelloWorld
  }
})
export default class Home extends Vue {}
</script>

2) @Model

components/Test.vue

<template>
  <div>
      <input type="checkbox" :checked="checked"/>
  </div>
</template>

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

@Component
export default class Test extends Vue {
    @Model ('change', {type: Boolean})  checked!: boolean;
}
</script>

views/Home.vue

<template>
  <div>
    <Test v-model="isChecked"/>
  </div>
</template>

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

@Component({
  components: {
    Test
  }
})
export default class Home extends Vue {
  isChecked: boolean = true;
}
</script>

3) @Watch

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <p>{{ msg }}</p>
  </div>
</template>

<script lang="ts">
import {Vue, Component, Watch} from 'vue-property-decorator';
@Component
export default class About extends Vue {
  msg: string = 'hello';

  @Watch('msg')
  onChangeValue(newV: string, oldV: string){
    console.log(newV, oldV); // world hello
  }

  mounted(): void {
    // 1.5秒后改变msg值
    setTimeout(() => {
      this.msg = 'world';
    }, 1500);
  }
}
</script>

4) @Emit示例

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <p>{{ count }}</p>
    <button type="button" @click="handleClick">点击</button>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Emit } from 'vue-property-decorator'
@Component
export default class About extends Vue {
  count: number = 0;

  @Emit()
  addToCount(n: number) {
    // return n+1; // 这里可以做数据劫持,把传的1变成n+1
    // console.log(n); 
  }

  private handleClick(): void {
    this.addToCount(1); // 相当于 this.$emit('addToCount', 1)
  }

  private mounted(): void {
    this.$on('add-to-count', (n: number) => { // 相当于 this.$on('add-to-count', (n) => { // ... })
      this.count += n;
    });
  }
}
</script>

在子父组件使用示例:

parent.vue

<template>
  <div>
    <Children @customClick="handleCustomClick"></Children>
    {{ count }}
  </div>
</template>  

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

@Component({
  components: {
    Children
  }
})
export class Parent extends Vue {
  count: number = 1;
  handleCustomClick(payload) {
     this.count += payload;
  }
}
</script>  

children.vue

<template>
  <div>
    <button type="button" @click="handleClick"></button>  
  </div>
</template>

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

@Component
export class Children extends Vue {
  @Emit('customClick')
  handleClick() {
    return 1;
  }
}
</script>  

5/6) @Inject和@Provide

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' },
    [symbol]: symbol
  },
  data () {
    return {
      foo: 'foo',
      baz: 'bar'
    }
  },
  provide () {
    return {
      foo: this.foo,
      bar: this.baz
    }
  }
})

7) @Component

其实上面的示例已经有了,这里再简写一下

<script lang="ts">
import {Vue, Component} from 'vue-property-decorator';
@Component
export default class About extends Vue {
  // ...
}
</script>

8) mixin

方式一:

components/mixin.ts

import Vue from 'vue';
import  Component  from 'vue-class-component';

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

view/About.vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>

<script lang="ts">
// 引入
import  Component, {mixins}  from 'vue-class-component';
import myMixins from '../components/mixin';

@Component
export default class About extends mixins(myMixins) {
  created() {
    console.log(this.value); // => Hello
  }
}
</script>

方式二:

components/mixin.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'
}

view/About.vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>

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

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

三、computed和methods

1、computed

<template>
  <div>
     {{ cName }}
  </div>
</template>

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

@Component
export default class HelloWorld extends Vue {
  name = 'tom';
  get cName() {
    return this.name + '123';
  }
}  
</script>

2、methods

<template>
  <div>
    <button type="button" @click="say">点击</button>
  </div>
</template>

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

@Component
export default class HelloWorld extends Vue {
  say() {
    console.log('hello'); 
  }
}  
</script>

四、如何使用vuex

安装

$ npm install --save vuex-class
# or 
$ yarn add vuex-class

示例:

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 MyComp extends Vue {
  @State('foo') stateFoo
  @State(state => state.bar) stateBar
  @Getter('foo') getterFoo
  @Action('foo') actionFoo
  @Mutation('foo') mutationFoo
  @someModule.Getter('foo') moduleGetterFoo
 
  // If the argument is omitted, use the property name
  // for each state/getter/action/mutation type
  @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']
  }
}

参考连接:



作者:webStyle_虎_
链接:https://www.jianshu.com/p/8ba2cdbfabd7
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2020-12-04 09:52  字符蹚浑水  阅读(210)  评论(0编辑  收藏  举报