Vue中如何使用TypeScript

622 阅读2分钟

创建一个vue2的TypeScript项目

vue create <project-name>

请看选中的绿色点,空格键进行选中取消,enter下一步

1. 在vue中书写ts的必备插件!

vue-class-component 强化 Vue 组件,使用装饰器语法使 Vue 组件更好的跟TS结合使用。 vue-property-decorator在 vue-class-component 的基础上增加了更多与 Vue 相关的装饰器,使Vue组件更好的跟TS结合使用。

npm i vue-class-component -s-d
npm i  vue-property-decorator -s-d

2.2 如何在Data双向绑定值

  • vue写法
<template>
  <div class="hello">
    <h1>{{msg}}</h1>
  </div>
</template>
<script>
export default {
   data() {
    return {
      msg: "",
    };
  },
}
</script>
  • vuets写法
<template>
  <div class="hello">
    <h1>{{msg}}</h1>
  </div>
</template>
<script src="ts">
import { Component, Vue, } from "vue-property-decorator";
@Component
export default class Home extends Vue {
  //注意点:3.public是公用的意思,可省略;没有data,return,直接放要绑定的值
  public msg!: number | string;
  // msg!: number | string;
}
</script>

如何引入子组件及组件传值

  • vue写法
<template>
  <div class="hello">
    <MenuBar :setMsg="msg"/>
  </div>
</template>
<script>
import MenuBar from "../components/MenuBar.vue";
export default {
  props: {
    // 父组件的值
    fatherMsg: {
      type: String
    }
  },
  components: {
    MenuBar
  },
  data() {
    return {
      msg: "",
    };
  },
}
</script>
  • vuets写法
<template>
  <div class="hello">
    <MenuBar :setMsg="msg" />
  </div>
</template>
<script src="ts">
import { Component, Vue, } from "vue-property-decorator";
import MenuBar from "../components/MenuBar.vue";
@Component({
  components: {
    MenuBar
  },
})
export default class Home extends Vue {
  // 父组件的传递过来的值
  @Prop() private fatherMsg!: string;
  //传递给子组件的值
  public msg!: number | string;
}
</script>

生命周期的用法

  • vue写法
<template>
  <div class="hello">
    <h1>{{msg}}</h1>
  </div>
</template>
<script>
var data = {name: "小明",age: 18};
export default {
   data() {
    return {
      msg: "",
    };
  },
  created() {
    this.msg = data.name + data.age + "岁";
  },
}
</script>
  • vuets写法
<template>
  <div class="hello">
    <h1>{{msg}}</h1>
  </div>
</template>
<script  src="ts">
import { Component, Vue, } from "vue-property-decorator";
var data = {name: "小明",age: 18};
@Component
export default class Home extends Vue {
  public msg!: number | string;
  created(): void {
    console.log("created");
    this.msg = data.name + data.age + "岁";
  }
  beforeCreate(): void {
    console.log("beforecreate");
  }
  beforeMount(): void {
    console.log("beforemounted");
  }
  mounted(): void {
    console.log("mounted");
  }
}
</script>

methods方法

  • vue写法
<template>
  <div class="hello">
    <h1>{{count}}</h1>
    <button class="btn" @click="addCount">add</button>
  </div>
</template>
<script>
var data = {name: "小明",age: 18};
export default {
   data() {
    return {
      count: 0,
    };
  },
  methods: {
    addCount() {
      return this.count++;
    }
  }
}
</script>
  • vuets写法
<template>
  <div class="hello">
    <h1>{{count}}</h1>
    <button class="btn" @click="addCount">add</button>
  </div>
</template>
<script  src="ts">
import { Component, Vue, } from "vue-property-decorator";
var data = {name: "小明",age: 18};
@Component
export default class Home extends Vue {
  public count: number = 0;
  //   方法也是直接写到外层
  addCount(): number {
    return this.count++;
  }
}
</script>

计算属性(computed)和监听属性(watch)

  • vue写法
<template>
  <div class="hello">
  <h1>计算属性:{{countChange}},结果+2:{{watchMsg}}</h1>
    <button class="btn" @click="addCcountChange">计算属性:add</button>
    <h1>监听:{{count}},结果+1:{{watchMsg}}</h1>
    <button class="btn" @click="addCount">监听add</button>
  </div>
</template>
<script>
var data = {name: "小明",age: 18};
export default {
   data() {
    return {
      count: 0,
      watchMsg: ""
    };
  },
  watch: {
    count: {
      handler(newVal, oldVal) {
        if (newVal < 10) {
          this.watchMsg = "我是数字" + newVal;
        } else {
          this.watchMsg = "我会继续增长";
        }
      },
      immediate: true
    },
    watchMsg: {
      handler(newVal, oldVal) {
        console.log(newVal);
      },
      immediate: true
    }
  },
  computed: {
    countChange: {
      get() {
        return this.count;
      },
      set(val) {
        this.count = val + 1;
      }
    }
  },
  methods: {
   addCcountChange() {
      return this.countChange;
    },
    addCount() {
      return this.count++;
    }
  }
}
</script>
  • vuets写法
<template>
  <div class="hello">
    <h1>计算属性:{{countChange}},结果+2:{{watchMsg}}</h1>
    <button class="btn" @click="addCcountChange">计算属性:add</button>
    <h1>监听:{{count}},结果+1:{{watchMsg}}</h1>
    <button class="btn" @click="addCount">监听add</button>
  </div>
</template>
<script  src="ts">
// 注意1.导入Watch
import { Component, Vue,Watch } from "vue-property-decorator";
var data = {name: "小明",age: 18};
@Component
export default class Home extends Vue {
  public count: number = 0;
  public watchMsg: string = "开始";
    //   计算属性
  get countChange(): number {
    return this.count;
  }
  set countChange(val) {
    this.count = val + 1;
  }
  // 注意2. 监听多个就导入多个Watch,命名自定义 clgMsg(newVal: string)
  @Watch("count")
  Count(newVal: number) {
    if (newVal < 10) {
      this.watchMsg = "我是数字" + newVal;
    } else {
      this.watchMsg = "我会继续增长";
    }
  }
  @Watch("watchMsg")
  clgMsg(newVal: string) {
    console.log(newVal);
  }
   //   方法
  addCcountChange(): number {
    return this.countChange++;
  }
  addCount(): number {
    return this.count++;
  }
}
</script>

Mixins混入如何使用

Mixins混入是公共方法同一调用;

Mixins文件的写法

  • js写法
export const TestMixins = {
    data(){
      return{
        form:{}
      }
    },
    methods:{
      handleSubmit(name): {
        return new Promise((resolve) => {
            resolve()
        })
      }
      handleReset(name){
        console.log(name)
        return name
      }
    }
}
  • TS写法
//必须引入
import { Component, Vue, } from "vue-property-decorator";
// 导出模块
declare module 'vue/types/vue' {
    interface Vue {
        form: Object
        handleSubmit(name: any): Promise<any>
        handleReset(name: any): void
    }
}
@Component
export default class TestMixins extends Vue {
    form: Object = {}
    handleSubmit(name: any): Promise<any> {
        return new Promise((resolve) => {
            resolve()
        })
    }
    handleReset(name: any): void {
        console.log(name)
        return name
    }
}

调用Mixins的vue文件写法

  • vue写法
<template>
  <div class="hello">
     <h1>{{handleReset("测试js-mixins")}}</h1>
  </div>
</template>
<script>
import TestMixins from "../assets/mixin";
export default {
   mixins: [TestMixins],
   data() {
    return {
      count: 0,
    };
   },
}
</script>
  • ts写法
<template>
  <div class="hello">
      <h1>{{handleReset("测试TS-mixins222")}}</h1>
  </div>
</template>
<script  src="ts">
import TestMixins from "../assets/mixin";
import { Component, Vue, Mixins} from "vue-property-decorator";
// 写在@Component内
@Component({
  mixins: [TestMixins]
})
export default class Home extends Vue {
  public count: number = 0;
}
</script>

vuex

js、ts写法除了类型判断其他区别不大;

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    isShowEdit: false,
    onlySticky: null,
  },
  mutations: {
    SHOW_EDIT(state: any, editMemo: any) {
      console.log(editMemo)
      state.onlySticky = editMemo;
      state.isShowEdit = true;
    }
  },
  actions: {
  },
  modules: {
  }
})

vuex调用单页面的写法

  • vue写法
<template>
  <div class="hello">
    <button @click="showEdit('vuex')">测试vuex</button>
  </div>
</template>
<script>
import { mapActions, mapState, mapGetters, mapMutations } from "vuex";
export default {
   data() {
    return {
      stickyList:[],
    };
   },
   created() {
    this.stickyList = this.$store.state.onlySticky;
  },
    methods: {
    ...mapMutations(["SHOW_EDIT"]),
    showEdit(item) {
      this.$store.commit("SHOW_EDIT", item);
    },
  }
}
</script>
  • vuets写法
<template>
  <div class="hello">
     <button @click="showEdit('vuex')">测试vuex</button>
  </div>
</template>
<script  src="ts">
import { Component, Vue,} from "vue-property-decorator";
import ItemData from "../model/ItemData"; //导入类
// 写在@Component内
@Component
export default class Home extends Vue {
  stickyList: [ItemData] = this.$store.state.onlySticky;
 // vuex,如果this.$store一直报错,则在单页面引入 import Vuex from 'vuex'
  showEdit(item) {
    this.$store.commit("SHOW_EDIT", item);
  }
}
</script>

axios请求数据

main.ts

import axios from 'axios'
Vue.prototype.$axios = axios;

ts语法除了类型其他区别不大,这里直接使用的是挂载axios和引入axios的方式

  • js写法
<template>
  <div class="hello">
    axios请求
  </div>
</template>
<script>
export default {
   data() {
    return {
    };
   },
   created() {
    // 请求地址  https://www.foobar.com/my-app/user/add
    const url1 = "https://www.foobar.com/my-app/user/add";
    this.$axios.get(url1, { params: { type: "js" } }).then(res => {
      console.log(res);
    });
    // 使用vue代理
    const url2 = "/my-app/user/add";
    this.$axios.get(url2, { params: { type: "Ts" } }).then(res => {
      console.log(res);
    });
  },
}
</script>
  • ts写法
<template>
  <div class="hello">
    axios请求
  </div>
</template>
<script  src="ts">
import { Component, Vue,} from "vue-property-decorator";
import axios from "axios";
// 写在@Component内
@Component
export default class Home extends Vue {
   created(): void {
    const url1 = "https://www.foobar.com/my-app/user/add";
    axios.get(url1, { params: { type: "js" } }).then((res: any) => {
      console.log(res);
    });
    // 使用vue代理
    const url2 = "/my-app/user/add";
    axios.get(url2, { params: { type: "Ts" } }).then((res: any) => {
      console.log(res);
    });
  }
}
</script>