案例:Vue3待办事项

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

image 2024 02 22 16 14 27 167
Figure 1. 图3-15 Vue 3 待办事项

功能描述

该项目是一个响应式的单页面管理系统,结合 Vue Cli 工具来生成项目脚手架,主要有以下几个功能:

  • 创建一个事项。

  • 将事项标记为已完成。

  • 将事项标记为未完成。

  • 删除一个事项。

  • 恢复一个删除的事项。

该项目主要使用 Vue.js 的基础知识和 Vue 的组件知识,比较适合初学者,主要知识包括:

  • Vue.js 单文件组件的使用。

  • Vue.js 常用指令的使用。

  • Vue.js 组件的通信方式。

  • Vue.js 的生命周期方法和事件方法的使用。

  • Vue.js 监听属性。

  • mitt 跨组件通信。

同时也包括移动端布局以及离线存储等相关知识,其中用到了 Vue Cli 工具,这部分内容读者可以先跳过,我们会在后面的章节讲解。

案例完整代码

和之前案例不同的是,本项目采用前端工程化构建,Vue Cli 生成基本的目录结构,并采用单文件组件构成整体的业务逻辑,基本目录结构如图 3-16 所示(有些目录结构不在本章使用)。

image 2024 02 22 16 17 21 365
Figure 2. 图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 的使用场景是什么?