使用vue-cli3+
建立一个基于ts
的模板:
javascript
上一步中已经建立完了基于ts
的vue
模板,可是开发方式仍是如同以前的template
同样,只是将script
中的js
部分改为了ts
来书写。接下来就将模板(template)方式改为tsx的方式,这里须要借助一个库 -- vue-tsx-support
vue
首先安装vue-tsx-support
: java
npm install vue-tsx-support --save
# or
yarn add vue-tsx-support
复制代码
安装结束后,咱们须要对咱们的文件作点小改动,首先咱们在主入口文件main.ts
中引入:
git
// main.ts
import "vue-tsx-support/enable-check";复制代码
而后删掉src/shims-tsx.d.ts
文件,避免和vue-tsx-support/enable-check
声明重复冲突。github
最后在咱们的vue.config.js
文件里的configureWebpack
属性下增长一项resolve
:
vuex
// vue.config.js
module.exports = {
// ...
configureWebpack: {
resolve: {
extensions: [".js", ".vue", ".json", ".ts", ".tsx"] // 加入ts 和 tsx
}
}
}复制代码
这样就能够了,接下来就能够开始开发了。 咱们在/components
下新建一个文件button.tsx
。而后开始书写咱们tsx
风格的vue
代码:
vue-cli
// components/button/button.tsx
import { Component, Prop } from "vue-property-decorator";
import * as tsc from "vue-tsx-support";
interface ButtonClick {
(value: string): void
}
interface ButtonProps {
text: string;
btnClick?: ButtonClick
}
@Component
export default class ZButton extends tsc.Component<ButtonProps> {
@Prop() text!: string;
public btnClick(value: string): void {
console.log("value is: ", value);
}
protected render() {
return (
<div>
<button onClick={() => this.btnClick("click")}>{this.text}</button>
</div>
)
}
}复制代码
这样咱们就完成了一个简单的tsx组件了。 接下来咱们去改写原来的Home.vue
变成Home.tsx
:
typescript
// views/Home.tsx
import { Component, Vue } from "vue-property-decorator";
import { Component as tsc } from "vue-tsx-support";
import ZButton from "@/components/button/button.tsx";
@Component
export default class HomeContainer extends tsc<Vue> {
protected render() {
return <Zbutton text="点我!"></Zbutton>;
}
}复制代码
而后运行,能看到如下效果:
npm
就这样完成了一个简单的tsx风格的vue项目了。
json
新建mixins/index.ts
,在index.ts
中写一个vue mixin
:
// mixins/index.ts
import { Vue, Component } from "vue-property-decorator";
// 这里必定要作个声明 否则在组件里使用的时候会报不存在的错误
// 要对应mixin中的属性和方法
declare module "vue/types/vue" {
interface Vue {
mixinText: string;
showMixinText(): void;
}
}
@Component
export default class MixinTest extends Vue {
public mixinText: string = "我是一个mixin";
public showMixinText() {
console.log(this.mixinText);
}
}复制代码
而后在component/button/button.tsx
中使用:
// component/button/button.tsx
import { Component, Prop } from "vue-property-decorator";
import * as tsc from "vue-tsx-support";
import MixinTest from "@/mixins";
interface ButtonClick {
(value: string): void;
}
interface ButtonProps {
text: string;
btnClick?: ButtonClick;
}
// 在Component装饰器上注入mixin
@Component({
mixins: [MixinTest]
})
export default class ZButton extends tsc.Component<ButtonProps> {
@Prop() text!: string;
public btnClick(value: string): void {
console.log("value is: ", value);
}
// 点击事件中调用mixin的方法
protected render() {
return (
<div>
<button onClick={() => this.showMixinText()}>{this.text}</button>
</div>
);
}
}复制代码
vuex
的ts
改造主要有两种方案,一种是基于vuex-class的方式,一种是基于vue-module-decorators的方式。 这里我使用的是vuex-class
。
安装vuex-class
:
npm install vue-class --save
#or
yarn add vuex-class复制代码
新建一个system的module,针对system的store创建各自文件
编写一个简单的例子,在vuex中存储user信息:
// store/modules/system/state.ts
interface SystemState {
user: Object
}
const state: SystemState = {
user: {}
}
export default state;复制代码
// store/modules/system/mutation-type.ts
interface SystemMutationType {
SET_USER_INFO: String;
}
const Mutation_Type: SystemMutationType = {
SET_USER_INFO: "SET_USER_INFO"
}
export default Mutation_Type;复制代码
// store/modules/system/mutation.ts
import type from "./mutation-type";
const mutation: any = {
[type.SET_USER_INFO as string](state: SystemState, user: Object) {
state.user = user;
}
}
export default mutation;复制代码
import type from "./mutation-type";
import { Commit } from "vuex";
export const cacheUser = (context: { commit: Commit }, user: Object) => {
context.commit(type.SET_USER_INFO as string, user);
}复制代码
而后创建一个system的入口文件index.ts
将这些外抛出去:
// store/modules/system/index.ts
import state from "./state";
import mutations from "./mutation";
import * as actions from "./action";
import * as getters from "./getter";
export default {
namespaced: true,
state,
getters,
mutations,
actions
};复制代码
最后在store的入口文件处引用该module:
// store/index.ts
import Vue from "vue";
import Vuex from "vuex";
import system from "./modules/system";
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
system
}
});复制代码
接着咱们去组件button.tsx
中使用:
// components/button/button.tsx
import { Component, Prop } from "vue-property-decorator";
import * as tsc from "vue-tsx-support";
// 引入store命名空间 方便使用某个模块
import { namespace } from "vuex-class";
// 经过namespace(module name)的方式使用某个模块的store
const systemStore = namespace("system");
@Component
export default class ZButton extends tsc.Component<ButtonProps> {
@Prop() text!: string;
// store使用state和action 其余getter和mutation类型
@systemStore.State("user") user!: Object;
@systemStore.Action("cacheUser") cacheUser: any;
public btnClick(value: string): void {
console.log("value is: ", value);
// 点击调用store的action方式存储user信息
// 而state中的user信息会同步 可经过vue-tools查看
this.cacheUser({ name: "张三", phone: "13333333333" });
}
// 点击事件中调用mixin的方法
protected render() {
return (
<div>
<button onClick={() => this.btnClick()}>{this.text}</button>
</div>
);
}
}复制代码
Tips: 基于typescript的vuex,还在想更优的一种方式。
Ps: 头一次写文章,不免有点紧张,若是问题,欢迎讨论。感谢~
最终的template在这里