案例:Vue3待办事项
学习完本章的 Vue.js
组件内容之后,读者基本上可以掌握大部分 Vue
的理论知识,可以做一些较为复杂的项目,同时结合组件化和工程化,我们将会开发一个待办事项系统,界面如图 3-15 所示。

功能描述
该项目是一个响应式的单页面管理系统,结合 Vue Cli
工具来生成项目脚手架,主要有以下几个功能:
-
创建一个事项。
-
将事项标记为已完成。
-
将事项标记为未完成。
-
删除一个事项。
-
恢复一个删除的事项。
该项目主要使用 Vue.js
的基础知识和 Vue
的组件知识,比较适合初学者,主要知识包括:
-
Vue.js 单文件组件的使用。
-
Vue.js 常用指令的使用。
-
Vue.js 组件的通信方式。
-
Vue.js 的生命周期方法和事件方法的使用。
-
Vue.js 监听属性。
-
mitt 跨组件通信。
同时也包括移动端布局以及离线存储等相关知识,其中用到了 Vue Cli
工具,这部分内容读者可以先跳过,我们会在后面的章节讲解。
案例完整代码
和之前案例不同的是,本项目采用前端工程化构建,Vue Cli
生成基本的目录结构,并采用单文件组件构成整体的业务逻辑,基本目录结构如图 3-16 所示(有些目录结构不在本章使用)。

在 views
文件夹下创建 todo.vue
组件和 recycle.vue
组件,分别表示待办事项页面和回收站页面,这两个组件的初始化代码如下:
todo.vue
组件:
<template>
<div class="todo"></div>
</template>
<script>
/**
* 待办事项页面组件
*/
module.exports = {
name: 'todo', // 组件的名称尽量和文件名一致
components: {}, // 子组件的设置
data() {}, // 组件的数据
mounted() {}, // 组件的生命周期方法
methods: {} // 组件的方法
}
</script>
<style>
...
</style>
recycle.vue
组件:
<template>
<div class="recycle"></div>
</template>
<script>
/**
* 回收站页面组件
*/
module.exports = {
name: 'recycle', // 组件的名称尽量和文件名一致
components: {}, // 子组件的设置
data() {}, // 组件的数据
mounted() {}, // 组件的生命周期方法
methods: {} // 组件的方法
}
</script>
<style>
...
</style>
在 components
目录创建 navheader.vue
文件作为标题按钮组件,初始化代码如下:
navheader.vue 组件:
<template>
<div class="nav-header">
</div>
</template>
<script>
/**
* 按标题按钮组件
*/
module.exports = {
name: 'navheader',
props: {
page: { // 接收父组件传递的页面名称
type: String
}
}
}
</script>
<style>
</style>
在 components
目录创建 titem.vue
文件作为单条事项组件,初始化代码如下:
titem.vue
组件:
<template>
<div class="todo-item">
</div>
</template>
<script>
/**
* 单条事项组件
*/
module.exports = {
name: 'titem',
props: {
item: { // 接收父组件传递的事项数据
type: Object,
}
},
}
</script>
<style>
</style>
在 components
目录创建 ritem.vue
文件作为单条已删除事项组件,初始化代码如下:
ritem.vue 组件:
<template>
<div class="recycle-item">
</div>
</template>
<script>
/**
* 单挑已删除事项组件
*/
module.exports = {
name: 'ritem',
props: {
item: { // 接收父组件传递的事项数据
type: Object,
}
},
}
</script>
<style>
</style>
本项目的数据持久化也采用 LocalStorage
这种方案。创建 utils
文件夹,同时新建 dataUtils.js
文件,该文件作为对 LocalStorage
的封装,完整代码如下:
/**
* 创建存储器,基于LocalStorage的封装
* 允许存储基于JSON格式的数据
*/
export default {
/**
* 通过key获取值
* @param {String} key - key值
*/
getItem(key) {
let item = window.localStorage.getItem(key)
// 获取数据后,直接转换成JSON对象
return item ? window.JSON.parse(item) : null
},
/**
* 通过key存储数据
* @param {String} key - key值
* @param {*} value - 需要存储的数据将会转换成字符串
*/
setItem(key, value) {
window.localStorage.setItem(key, window.JSON.stringify(value))
},
/**
* 删除指定key的数据
* @param {string} key
*/
removeItem(key) {
window.localStorage.removeItem(key)
},
/**
* 清空当前系统的存储
*/
clearAllItems() {
window.localStorage.clear()
}
}
以上只是项目的基本框架和组件初始代码,具体的业务逻辑代码不再列举,读者可参考完整源码,执行 npm run serve
命令,即可启动完整源码程序。
本案例完整源码:/案例源码/Vue.js组件。
小结与练习
本章讲解了 Vue.js
更深入的组件知识,主要内容包括:组件生命周期、组件通信、组件插槽、动态组件、异步组件和组件 Mixin
。其中组件生命周期赋予了代码逻辑更多的切入点,组件通信是 Vue.js
应用众多组件沟通的桥梁,组件插槽提供了父子组件更加多样化的调用方式,动态组件、异步组件和组件 Mixin
让组件功能更加多样化。这些更深入的知识能让开发者充分利用 Vue.js
的功能实现更加复杂、用户交互更加丰富的应用。
与之前的 Vue.js
基础知识一样,建议读者自行运行一下本章提供的示例代码,以便加深对本章知识的理解。
下面来检验一下读者对本章内容的掌握程度:
-
Vue.js 中组件共有哪些生命周期钩子函数,它们的区别是什么?
-
Vue.js 中父子组件如何通信?
-
Vue.js 中非父子组件如何通信?
-
Vue.js 中的插槽有哪些类型,它们的区别和使用场景是什么?
-
请用通俗易懂的话来解释什么是 Vue.js 插槽。
-
Mixin 的使用场景是什么?