We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
我们已经基本完成了 UI 层面的编写,接下来我们需要对逻辑层进行实现。
我们选择全局状态管理工具 vuex,但是在 TypeScript 中 vuex 往往要与 vuex-class 进行配合,它同样提供了多个装饰器供我们使用。
首先安装 vuex-class:
npm i -S vuex-class
本节对应源代码在v1.2
我们可以 src/store/state.ts 中先定义 State 的类型和初始值。
src/store/state.ts
export enum Mode { edit, // 处于编辑状态 finish // 处于编辑完成状态 } export interface ITodoItem { id: string; // todo任务的id name: string; // todo 任务名称 isDone: boolean; // 任务是否完成 iconName: string; // 任务的图标 color: string; // 任务底色 mode: Mode; // 编辑状态 } export interface State { todoList: Array<ITodoItem>; } export const state: State = { todoList: [] };
export enum Mode { edit, // 处于编辑状态 finish // 处于编辑完成状态 } export interface ITodoItem { id: string; // todo任务的id name: string; // todo 任务名称 isDone: boolean; // 任务是否完成 iconName: string; // 任务的图标 color: string; // 任务底色 mode: Mode; // 编辑状态 } export interface State { todoList: Array<ITodoItem>; }
export interface ITodoItem { id: string; // todo任务的id name: string; // todo 任务名称 isDone: boolean; // 任务是否完成 iconName: string; // 任务的图标 color: string; // 任务底色 mode: Mode; // 编辑状态 }
export interface State { todoList: Array<ITodoItem>; }
export const state: State = { todoList: [] };
然后我们在 src/store/mutations.ts 中编写创建 todo 的逻辑,其实很简单,我们接受一个 todo 对象,把它添加到 todoList 数组中即可。
src/store/mutations.ts
export const mutations: MutationTree<State> = { // 创建 todo createTodoItem(state: State, todoItem: ITodoItem) { state.todoList.push(todoItem); }, };
那么如何在组件中使用 mutations 呢?
mutations
import { Component, Prop, Vue } from "vue-property-decorator"; import { Icon } from "vant"; import { Mutation, State } from "vuex-class"; import { ITodoItem, Mode } from "../store/state"; import { _ } from "../utils"; @Component({ components: { [Icon.name]: Icon } }) export default class Header extends Vue { @State private todoItem!: ITodoItem[]; @Mutation private createTodoItem!: (todo: ITodoItem) => void; private createTodoItemHandle() { const newItem: ITodoItem = { id: _.uuid(), name: "新任务", isDone: false, mode: Mode.edit, iconName: "yingtao", color: "#FFCC22" }; this.createTodoItem(newItem); } }
我们看到 @mutation 就是 vuex-class 提供的装饰器,它可以帮助我们把相关的 mutations 作为类成员来使用。
我们可以先看一下动图的演示:
我们点击了 + 按钮之后创建了新的 todo 任务,然后进入了自定义 todo 任务的编辑页面,我们可以选择背景颜色和图标,也可以自定义任务名称。
这些逻辑我们统一在 mutations 中实现:
export const mutations: MutationTree<State> = { ... // 选择图标背景 selectColor(state: State, payload: { id: string; color: string }) { const list = state.todoList; const todo = _.find(list, payload.id); <span class="hljs-keyword">if</span> (todo) { todo.color = payload.color; } }, // 选择图标 selectIcon(state: State, payload: { id: string; icon: string }) { const list = state.todoList; const todo = _.find(list, payload.id); if (todo) { todo.iconName = payload.icon; } }, // 编辑任务名称 changeName(state: State, payload: { id: string; value: string }) { const list = state.todoList; const todo = _.find(list, payload.id); if (todo) { todo.name = payload.value; } } };
<span class="hljs-keyword">if</span> (todo) { todo.color = payload.color; }
}, // 选择图标 selectIcon(state: State, payload: { id: string; icon: string }) { const list = state.todoList; const todo = _.find(list, payload.id); if (todo) { todo.iconName = payload.icon; } },
// 编辑任务名称 changeName(state: State, payload: { id: string; value: string }) { const list = state.todoList; const todo = _.find(list, payload.id); if (todo) { todo.name = payload.value; } } };
后面我们借助 vuex-class 把它们作为类的成员使用,我们看 src/views/Create.vue 的部分:
src/views/Create.vue
export default class Create extends Vue { private iconSetting: string[] = config.iconSetting; private colorSetting: string[] = config.colorSetting; private id!: string; private index!: number; private currentItem!: ITodoItem; @Mutation private selectColor!: (payload: { id: string; color: string }) => void; @Mutation private selectIcon!: (payload: { id: string; icon: string }) => void; @Mutation private changeName!: (payload: { id: string; value: string }) => void; @Getter private getCurrentTodoList!: ITodoItem[]; // 获取当前将要创建的todo的id private mounted() { console.log(this.getCurrentTodoList); const list = this.getCurrentTodoList; this.index = list.length - 1; const currentItem = list[this.index]; this.id = currentItem.id; } // 计算当前icon名称 private get iconComputed() { const currentItem = _.find(this.getCurrentTodoList, this.id); const { iconName } = currentItem!; return iconName; } // 计算当前背景颜色 private get colorComputed() { const currentItem = _.find(this.getCurrentTodoList, this.id); const { color } = currentItem!; return color; } private changeColorHandle(color: string) { this.selectColor({ id: this.id, color }); } private handleIconHandle(name: string) { this.selectIcon({ id: this.id, icon: name }); } private get nameComputed() { const todo = _.find(this.getCurrentTodoList, this.id); return todo!.name; } private set nameComputed(name) { this.changeName({ id: this.id, value: name }); } }
你可能会好奇 @Getter 是干什么的,这个其实就是将 Vuex 中的 Getter 添加到类成员的装饰器,我们在这里把 todoList 这个数组作引入进来,方便操作。
我们创建完任务之后回到首页,会发现多出了一个 todo 任务,这个时候我们需要两个逻辑:
我们在 mutations 中编辑相关逻辑:
deleteTodoItem(state: State, id: string) { const list: ITodoItem[] = state.todoList; state.todoList = list.filter(item => item.id !== id); } // 将此任务设置为完成 doneTodoItem(state: State, id: string) { const list: ITodoItem[] = state.todoList; const todo = _.find(list, id); if (todo) { todo.isDone = true; } }
然后我们在 src/views/Home.vue 部分应用:
src/views/Home.vue
export default class Home extends Vue { @Mutation private deleteTodoItem!: (id: string) => void; @Mutation private doneTodoItem!: (id: string) => void; @Getter private getCurrentTodoList!: ITodoItem[]; private get TodoListComputed() { const list = this.getCurrentTodoList.filter( item => item.mode !== Mode.edit ); <span class="hljs-keyword">return</span> list; } private delHandle(id: string) { this.deleteTodoItem(id); } private doneHandle(id: string) { this.doneTodoItem(id); } }
export default class Home extends Vue { @Mutation private deleteTodoItem!: (id: string) => void; @Mutation private doneTodoItem!: (id: string) => void; @Getter private getCurrentTodoList!: ITodoItem[]; private get TodoListComputed() { const list = this.getCurrentTodoList.filter( item => item.mode !== Mode.edit ); <span class="hljs-keyword">return</span> list; } private delHandle(id: string) { this.deleteTodoItem(id); }
private get TodoListComputed() { const list = this.getCurrentTodoList.filter( item => item.mode !== Mode.edit );
<span class="hljs-keyword">return</span> list;
}
private delHandle(id: string) { this.deleteTodoItem(id); }
private doneHandle(id: string) { this.doneTodoItem(id); } }
逻辑编写部分没有什么有太大难度的东西,强烈建议你把源代码拷贝下来,结合本节内容和注释进行学习,因为其中涉及了一些细节我们碍于篇幅没办法都涉及到。
这就是我们借助 TypeScript + Vue 完成的一个简单的 TODO 应用,其实如果你搞清楚了这个小应用,整个使用就不会有太大问题了。
但是值得注意的是,目前 vue2.6x 虽然对 TypeScript 的支持已经有了一定进步,但是整体的代码提示还是不到位,语法噪音依然非常大,vue 3.0 要到 2020年一季度发布,这个版本的 Vue 只是个过渡,在下个用 TypeScript 重写后的 Vue 3.0 发布后我们会继续进行实战。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Vue 实战:TypeScript 下的 Vuex
我们已经基本完成了 UI 层面的编写,接下来我们需要对逻辑层进行实现。
我们选择全局状态管理工具 vuex,但是在 TypeScript 中 vuex 往往要与 vuex-class 进行配合,它同样提供了多个装饰器供我们使用。
首先安装 vuex-class:
本节对应源代码在v1.2
创建 todo 任务逻辑
我们可以
src/store/state.ts
中先定义 State 的类型和初始值。然后我们在
src/store/mutations.ts
中编写创建 todo 的逻辑,其实很简单,我们接受一个 todo 对象,把它添加到 todoList 数组中即可。那么如何在组件中使用
mutations
呢?我们看到 @mutation 就是 vuex-class 提供的装饰器,它可以帮助我们把相关的 mutations 作为类成员来使用。
自定义 todo 内容
我们可以先看一下动图的演示:
我们点击了 + 按钮之后创建了新的 todo 任务,然后进入了自定义 todo 任务的编辑页面,我们可以选择背景颜色和图标,也可以自定义任务名称。
这些逻辑我们统一在 mutations 中实现:
后面我们借助 vuex-class 把它们作为类的成员使用,我们看
src/views/Create.vue
的部分:你可能会好奇 @Getter 是干什么的,这个其实就是将 Vuex 中的 Getter 添加到类成员的装饰器,我们在这里把 todoList 这个数组作引入进来,方便操作。
删除、完成 todo 任务
我们创建完任务之后回到首页,会发现多出了一个 todo 任务,这个时候我们需要两个逻辑:
我们在 mutations 中编辑相关逻辑:
然后我们在
src/views/Home.vue
部分应用:小结
逻辑编写部分没有什么有太大难度的东西,强烈建议你把源代码拷贝下来,结合本节内容和注释进行学习,因为其中涉及了一些细节我们碍于篇幅没办法都涉及到。
这就是我们借助 TypeScript + Vue 完成的一个简单的 TODO 应用,其实如果你搞清楚了这个小应用,整个使用就不会有太大问题了。
但是值得注意的是,目前 vue2.6x 虽然对 TypeScript 的支持已经有了一定进步,但是整体的代码提示还是不到位,语法噪音依然非常大,vue 3.0 要到 2020年一季度发布,这个版本的 Vue 只是个过渡,在下个用 TypeScript 重写后的 Vue 3.0 发布后我们会继续进行实战。
The text was updated successfully, but these errors were encountered: