在前面的文章中介词了使用 Vue + TypeScript 实现了一个简单的 ToDo Demo。
其实在这个 Demo 中已经算是用到了自定义 Component
了。如:
@Component
class App extends Vue{ }
这一般是用来作为应用的根组件。
下面要会更具体的介绍一下 Vue 的组件系统及单文件组件。
安装
vue-loader
,$npm install -D vue-loader
webpack.config.js
中module.rules
中添加以下规则声明:
{ test: /\.vue$/, loader: 'vue-loader' }
安装
vue-property-decorator
,$npm i -S vue-property-decorator
并将tsconfig
的emitDecoratorMetadata
选项设置为true
安装
vue-template-compiler
,$npm i -D vue-template-compiler
创建
vue-shims.d.ts
声明文件,以便 TS 识别.vue
后缀的单文件模块。内容如下:
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
- 将
Todo
类单独放到models.ts
文件中,如下:
export default class Todo{
content: string
created: Date
done = false
constructor(content:string){
this.content = content
this.created = new Date()
}
}
- 创建单文件模块
TodoItem.vue
,内容如下:
<template>
<li>
<span v-show="todo.done" class="done-marker" @click="markTodo">✓</span>
<span v-show="!todo.done" class="todo-marker" @click="markDone">☐</span>
<span class="content">{{todo.content}}</span>
</li>
</template>
<script lang="ts">
import Vue from "vue"
import Component from "vue-class-component"
import { Prop } from "vue-property-decorator"
import Todo from "./Todo"
@Component
export default class TodoItem extends Vue {
@Prop() todo:Todo
markDone():void{
this.todo.done = true
}
markTodo():void{
this.todo.done = false
}
}
</script>
注意需要在 script
标签中添加 lang="ts"
属性。
- 将
app.ts
修改如下:
import Vue from "vue"
import Component from "vue-class-component"
import TodoItem from "./TodoItem.vue"
import Todo from "./Todo"
@Component
class App extends Vue{
newTodoText = ''
todos :Array<Todo> = [new Todo("学习 Vue")]
hideCompletedTodos = false
visitCount = 0
error:any = null
create():void{
const content = this.newTodoText.trim()
if(content.length < 1){
this.error = "待办事项不能为空"
return
}
const todo = new Todo(content)
this.todos.push(todo)
this.newTodoText = ""
}
clearError():void{
this.error = null
}
}
const app = new App({ el: '#app',
components: {
'todo-item': TodoItem
}
})
- 将
index.html
中的ul
标签的绑定, 做如下修改:
<ul>
<todo-item v-for="todo in todos" :todo="todo" :key="todo.content"> </todo-item>
</ul>
完整代码见: https://github.com/banxi1988/VueToDoDemo.git
标签 step7