如何从零实现一个todo list(1)

一、开始前准备

实现一个想要的功能前,可以先理清它的功能,最好画一张思维导图,再按着导图实现的话会轻松很多,好记性不如烂笔头

如我们今天要实现的一个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安装

安装完后步骤

  1. 引入vuetify

  2. 删除HellowWorld.vue

  3. 删除App.vue不需要的东西

  4. 引入样式文件

    1. 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">
  5. 在components创建TaskList.vue的组件 并引入到App.vue里

  6. 下载需要的库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的原型功能 后续我们开始对布局进行调整 把思维导图上的大模块上的功能加上去 我们就可以继续对原型功能开发

相关推荐
斯~内克2 小时前
Electron 菜单系统深度解析:从基础到高级实践
前端·javascript·electron
数据知道2 小时前
【YAML】一文掌握 YAML 的详细用法(YAML 备忘速查)
前端·yaml
dr李四维2 小时前
vue生命周期、钩子以及跨域问题简介
前端·javascript·vue.js·websocket·跨域问题·vue生命周期·钩子函数
旭久2 小时前
react+antd中做一个外部按钮新增 表格内部本地新增一条数据并且支持编辑删除(无难度上手)
前端·javascript·react.js
windyrain2 小时前
ant design pro 模版简化工具
前端·react.js·ant design
浪遏2 小时前
我的远程实习(六) | 一个demo讲清Auth.js国外平台登录鉴权👈|nextjs
前端·面试·next.js
GISer_Jing3 小时前
React-Markdown详解
前端·react.js·前端框架
太阳花ˉ3 小时前
React(九)React Hooks
前端·react.js
拉不动的猪4 小时前
vue与react的简单问答
前端·javascript·面试