一、开始前准备
实现一个想要的功能前,可以先理清它的功能,最好画一张思维导图,再按着导图实现的话会轻松很多,好记性不如烂笔头
如我们今天要实现的一个todo list的功能 那我的规划是这样的首先先实现网页版本->再实现用electron包装起来加入sqlite数据库操作的功能。
实现一个TodoList前 我们首先观察windows 自带的Microsoft To Do的功能 画出导图
这样就可以很清晰的看到我们要实现的功能 那功能的大概罗列出来以后我们就要开始想界面如何实现 可以对界面打一个草稿做一个原型 这个一个demo项目的话 我们就直接根据Microsoft To Do布局做参考。
二、技术选型
demo来说的话 我个人习惯敏捷开发出原型 比起先打磨样式的情况 我更喜欢先把功能实现
首先进行技术选型:vue+vuex+vueitfy(同时兼容移动端)
三、原型编写
既然是要实现一个Todo List 那我们就先把注意力放在核心功能上 开始编写
首先通过vue ui 或者 vue-cli 创建一个空项目
shell
# 若vue命令报错的话 请先安装脚手架 npm install -g @vue/cli
# 根据上面的选型 我们闯建项目的时候 只需要保留Babel与vuex
vue create todo-list
# 等编译完毕后 进入文件夹
cd todo-list
# 安装我们需要的vuetify 为什么其他UI也兼容移动端要选择它呢?它有内置的css规范 可以少写很多css
cnpm install vuetify@v2-stable -S
cnpm install sass@~1.32 [email protected] deepmerge -D #不建议直接安装官方的命令 sass-loader太高会报错
# 进入vueitfy 官网 https://v2.vuetifyjs.com/zh-Hans/getting-started/installation/#nuxt-5b8988c5
# 找到webpack安装 要看完上面网址webpack安装
安装完后步骤
-
引入vuetify
-
删除HellowWorld.vue
-
删除App.vue不需要的东西
-
引入样式文件
-
public/index.html下加入 但是加载很慢
ini<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
-
-
在components创建TaskList.vue的组件 并引入到App.vue里
-
下载需要的库vue-uuid、momentjs原型开发
原型开发
html
<!--App.vue -->
<template>
<div
id="app"
class="v-application"
>
<v-card
width="100%"
flat
>
<v-system-bar
color="#303F9F"
dark
>
<v-spacer></v-spacer>
<v-icon>mdi-window-minimize</v-icon>
<v-icon>mdi-window-maximize</v-icon>
<v-icon>mdi-close</v-icon>
</v-system-bar>
<v-toolbar
color="#3F51B5"
dark
>
<v-app-bar-nav-icon></v-app-bar-nav-icon>
<v-toolbar-title>我的一天</v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-container>
<task-list />
</v-container>
</v-card>
</div>
</template>
<script>
import TaskList from "./components/TaskList.vue";
export default {
name: "App",
components: {
TaskList,
},
};
</script>
<style lang="scss">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
height: 100vh;
overflow: auto;
}
</style>
html
<!-- components/TaskList.vue -->
<template>
<div class="py-4">
<v-text-field
v-model="todo"
counter="25"
placeholder="请输入待办事项"
label="待办事项"
outlined
dense
persistent-placeholder
@keydown.enter="addTodo"
></v-text-field>
<v-list dense>
<div
v-for="list in lists"
:key="list.name"
>
<template v-if="list.data.length">
<v-subheader>{{list.name}}</v-subheader>
<v-list-item
v-for="(item, i) in list.data"
:key="i"
class="task-item mb-4"
:class="{complete:item.complete}"
>
<v-list-item-avatar>
<v-checkbox
v-model="item.complete"
@change="forceUpdate"
v-if="refresh"
/>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>{{item.title}}</v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-icon
v-if="!item.complete"
@click="deleteItem(item.id)"
>mdi-close</v-icon>
</v-list-item-action>
</v-list-item>
</template>
</div>
</v-list>
</div>
</template>
<script>
import { uuid } from "vue-uuid";
export default {
data() {
return {
// 当前完整列表
current_list: [],
// 待办事项输入值
todo: "",
// 这里处理渲染的时候v-checkbox值变动样式不刷新的问题
refresh: true,
};
},
computed: {
// 为了能用v-for 渲染写的列表目录
lists() {
return [
{
name: "待办列表",
data: this.current_list.filter((list_item) => !list_item.complete),
},
{
name: "已完成",
data: this.current_list.filter((list_item) => list_item.complete),
},
];
},
},
methods: {
// 新增todolist
addTodo() {
if (!this.todo) return;
this.current_list.push({
// 增加id是因为使用了computed 它的index是不准的
id: uuid.v4(),
title: this.todo,
complete: false,
create_time: new Date(),
});
this.todo = "";
},
// 强制刷新
forceUpdate() {
this.refresh = false;
this.$nextTick(() => {
this.refresh = true;
});
},
// 删除事项
deleteItem(id) {
this.current_list.splice(
this.current_list.findIndex((item) => item.id == id),
1
);
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .v-label {
left: -13px !important;
}
.task-item {
background-color: #eee;
border-radius: 10px;
}
.task-item.complete {
.v-list-item__title {
text-decoration: line-through;
color: #ccc;
}
}
</style>
这样就完成了一个最基础的todolist的原型功能 后续我们开始对布局进行调整 把思维导图上的大模块上的功能加上去 我们就可以继续对原型功能开发