用Vue实现一个简易记账本 您所在的位置:网站首页 移动查看账单明细 用Vue实现一个简易记账本

用Vue实现一个简易记账本

2023-07-19 15:52| 来源: 网络整理| 查看: 265

初学 Vue 和 TypeScript,决定做一个简易的记账本来练手。

从自身需求出发,这个小项目实现以下几点功能:

记账:可以快速记录一笔账单的消费/收入来源(标签),选择这笔账单的时间,以及记录金额。 标签管理:可以对修改已有标签的名字,或者自定义新的标签。 查看账单:可以逐条展示所有的账单记录,也可以根据年份和月份来筛选出记录。同时添加统计图可以更直观地显示记录。 基于上述功能,共设计记账页(主页)、标签管理页、删除标签页、统计页四个页面。

本项目用 Vue Cli 搭建,用到了 Vue、Vue Router、Vuex、TypeScript、Sass 技术。

链接:点击预览 Github源代码

一些思路和总结

1. 添加底部导航,实现页面跳转

首先确定每个页面的 url ,然后添加 Vue Router。每个页面对应各自的组件,用 redirect 重定向实现进入默认页面。

const routes: Array = [ { path: '/', redirect: '/money' }, { path: '/money', component: Money }, { path: '/labels', component: Labels }, { path: '/labels/edit/:type/:id', //传递参数 type 和 id component: EditLabel }, { path:'/statistics', component: Statistics }, { path: '*', component: NotFound } ] const router = new VueRouter({ routes }) 复制代码

在导航栏组件中添加 router-link,并且添加 active-class 属性,设置链接激活时使用的 CSS 类名。以此来添加样式。

标签 记一笔 统计 复制代码

2. 引入 svg

从 iconfont 下载所需的 svg 图标。按照教程添加如下代码:

添加 HTML 代码 复制代码 添加样式 .icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } 复制代码 引入 import '@/assets/icons/xxx.svg' 复制代码

此时还是不能显示 svg, 发现是缺 svg-sprite-loader。解决办法:

安装 svg-sprite-loader yarn add svg-sprite-loader --dev (或者使用 npm) 复制代码 配置 vue.config.js const dir = path.resolve(__dirname, 'src/assets/icons') // icons 目录 config.module .rule('svg-sprite') .test(/.svg$/) .include.add(dir).end() // 包含 icons 目录 .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract:false}).end() config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}]) config.module.rule('svg').exclude.add(dir) // 其他 svg loader 排除 icons 目录 复制代码

以上的设置就可以顺利引入 svg 了。

但是在使用的过程中,会遇到 svg 的一个坑是:发现在 scss 中设置了 svg 的颜色后,依然无法生效。 首先确保样式没有写错,检查 svg 源文件后,发现有些 svg 自带 fill 属性,这个属性使得图标拥有一个默认的颜色且不可被更改。

有一个简单粗暴地方法是,把所有 svg 地 fill 属性手动移除, 就可以给 svg 添加自定义颜色了。 但是问题来了,如果项目中引入几百个图标,总不能靠手动一一删除,不太现实。所以还是要找一个更优的方案。最好可以在引入时就自动删除 svg 的 fill 属性。

经过我的一番搜索,终于发现了一个可行方案!解决方法如下:

首先下载 svgo-loader

yarn add svgo-loader --dev (或者使用npm) 复制代码

在 vue.config.js 中添加以下两行:

.use('svgo-loader').loader('svgo-loader') .tap(options => ({...options, plugins: [{removeAttrs: {attrs: 'fill'}}]})).end() 复制代码

好了,这样就借助svgo-loader 自动删除所有引入的 svg 的 fill 属性了!

3. 关于整体布局

为了适配各种大小的手机页面,根据我的设计稿,采用一种有头部和底部导航栏,且上下固定中间可滑动显示的布局。所以用 Flex 布局来实现。 思路如下:

设置 body 的高度为 100vh; 给最外层 div 添加样式 display: flex; flex-direction: column; height: 100%; 复制代码 给中间部分添加样式 flex:1; overflow: auto; 复制代码

效果如下:

动画.gif

4. 利用 localStorage 进行数据的存储

因为这只是一个本地版的 app,将数据存储到 localStorage 是一个比较好的选择。我用到的仅仅是 localStorage 存储数据和保存数据的用法。通过 window.localStorage 即可访问到。

localStorage.getItem("name"); //读取保存在localStorage对象里名为name的变量的值 localStorage.setItem("data", data); // 存储名字为name值为 data 的变量 复制代码

localStorage 的更多用法可以参考 localStorage用法小总结。

5. 每个页面的逻辑实现

记账页 作为最主要的功能,所以这个页面也是这个 app 的主页。为了更好地模块化,将这一页面又分为不同的组件,分别负责一条记录的标签、类型(支出或收入)、备注、金额输入的数据逻辑以及样式处理。

父子组件之间数据的传递方式为:

父组件可以使用 props 把数据传给子组件。 子组件可以使用 $emit 触发父组件的自定义事件。 这样,在记账页面可以生成一条完整的账单记录。 标签管理页 读取 localStorage 中所有的标签并且显示出来。其中每一个标签可以点进进入标签编辑页,所以需要设置每一个标签为 router-link 传递 type 和 id(唯一标识每一个标签) 参数。 标签编辑页 通过router-link传递来的type 和 id 可以从 localStorage 中找到对应的标签对其进行操作。这里主要是删除和修改的功能。 统计页 获取到localStorage中的记录数据,进行展示。需要解决的是对所有的记录的筛选,引入了第三方组件 datetime-picker,根据选中的年月来展示对应的记录。还引入了 echarts 柱状图,来更直观的展示数据。

6. 全局数据管理之 Vuex

考虑到多个页面都有对标签和记录数据的读取和更改操作,传参会非常繁琐且难以维护。所以采用 Vuex 对数据进行管理。这样做的好处是:

解耦:将所有数据相关的逻辑放入 store。 数据读写更方便:任何组件不管在哪里,都可以直接读写数据。 控制力更强:组件对数据的读写只能使用 store 提供的 API 进行。

我在 store 中主要实现了以下 API, 无非是对记录和标签的增删改查。供各组件进行调用。

Vue.use(Vuex); const store = new Vuex.Store({ state: {}, mutations: { fetchRecords() {}, createRecord() {}, saveRecords() {}, fetchTags() {}, createTag() {}, saveTags() {}, updateTag() {}, removeTag() {}, }, actions: {}, modules: {} }); export default store; 复制代码

7. 其他

在项目中引入 Vant 根据官网提示: # 安装 vant npm i vant -S 复制代码

按需引入组件

# 安装插件 npm i babel-plugin-import -D 复制代码 // 在 babel.config.js 中配置 module.exports = { plugins: [ ['import', { libraryName: 'vant', libraryDirectory: 'es', style: true }, 'vant'] ] }; 复制代码 // 接着你可以在代码中直接引入 Vant 组件 import { Button } from 'vant'; 复制代码

根据文档即可快速上手,对数据进行更快捷的处理和展示。更多可查看 Vant文档

实现一个 ID 生成器

在对标签存储时,需要给每一个 标签添加一个独一无二的 ID,从而可以获取到对应的标签对其管理。于是我写了这么一个小工具。

let id:number = parseInt(window.localStorage.getItem('_idMax') || '0') || 0; function createId() { id++; window.localStorage.setItem('_idMax', id.toString()); return id; } export default createId; 复制代码

每次从 localStorage 中读取到最大 id, 对其 +1 后返回,并且将新的 id 置为最大 id,使得所有的 id 不会发生重复。

总结

除了以上整理的思路,项目中还有许多细节不再赘述。刚开始写项目还有许多不足之处需要改进。通过这个小项目让我对 Vue 有了深刻的理解和运用。也希望通过更多的运用精进自己的技术。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有