一个小项目带你了解vue框架——TodoList(简单实用易上手)

news2025/1/18 6:51:22

写在前面

你是否还在为繁杂的事情感到头昏脑涨?你是否还在将便利贴贴满整个桌面?本文就为你解决这个烦恼,使用vue框架做一个TodoList,将事情整理的井井有条不再是一个遥不可及梦!让我们行动起来吧!

基于vue的小项目——todoList

  • 写在前面
  • 设置头部基础布局和内容主体区域
  • 设置左边待完成模块:
  • 设置右边已完成模块:
  • 交互的逻辑(数据的添加和循环展示)代码展示:
  • 利用过滤器进行日期显示:
  • watch监听List的变换,目的是保存数据状态:
  • 设置删除效果
  • 写在最后

设置头部基础布局和内容主体区域

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>todo</title>
    <style>
        body{
            margin: 0;
        }
        .top{
            width: 100%;
            height: 80px;
            background-color: #555;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        input[type="text"]{
            width: 400px;
            height: 50px;
            border: none;
            padding: 0 30px;
        }
        input:focus{
            outline: none;
        }
        button{
            width: 100px;
            height: 50px;
            background-color: darkcyan;
            color: #fff;
            border: none;
            padding: 0;
            cursor: pointer;
        }
        .bottom{
            width: 1221px;
         	height: auto;
            min-height: 500px;
            background-color: aqua;
            margin: 30px auto;
            overflow: hidden;
        }
        .left{
            width: 600px;
            height: auto;
            float: left;
            min-height: 1px;
        }
        .divider{
            width: 1px;
            height: 500px;
            background-color: #555;
            float: left;
            margin: 0 10px;
        }
        .right{
            width: 600px;
            height: auto;
            float: left;
            min-height: 1px;
        }
    </style>
</head>
<body>
  <div id="app">
    <div class="top">
        <input type="text">//使用vue之后,将此行代码改为<input type="text" placeholder="请输入代待办事项" v-model="value">
        <button>添加</button>//使用vue之后,将此行代码改为<button @click="handleClick">添加</button>
    </div>
    <div class="bottom">
        <div class="left"></div>
        <div class="divider"></div>
        <div class="right"></div>
    </div>
   </div>
</body>
</html>

内容主体区域背景加了颜色,框架效果展示:
在这里插入图片描述

设置左边待完成模块:

     <div class="left">
            <h3>待完成(0)</h3>
            <div class="item">
                <div class="control">
                    <input type="checkbox">
                    <span>2022/05/03 15:15</span>
                </div>
                    <div class="content">
                        学习vue知识 制作todolist应用
                    </div>
            </div>
        </div>


        .item{
            width: 100%;
        }
        .control{
            width: 100%;
            line-height: 30px;
            font-size: 18px;
            font-weight: bold;
        }
        .content{
            width: 90%;
            line-height: 30px;
            font-size: 16px;
            border-top: 1px solid #999;
            border-bottom: 1px solid #999;
            margin: 10px auto;
            padding: 15px 0;
        }

将背景颜色去掉,效果展示:
在这里插入图片描述

设置右边已完成模块:


  <div class="right">
            <h3>已完成(0)</h3>
            <div class="item">
                <div class="control">
                    <input type="checkbox">
                    <span>2022/05/03 15:15</span>
                    <img src="delete.png" alt="" class="del">
                </div>
                <div class="content">
                    学习vue知识 制作todolist应用
                </div>
            </div>
        </div>

 .del{
            width: 20px;
            height: 20px;
            float: right;
            cursor: pointer;
            margin-top: 5px;
        }

delete.png

效果展示:
在这里插入图片描述

交互的逻辑(数据的添加和循环展示)代码展示:

<body>
    <div id="app">
        <div class="top">
            <input type="text" placeholder="请输入代待办事项" v-model="value">
            <button @click="handleClick">添加</button>
        </div>
        <div class="bottom">
            <div class="left">
                <h3>待完成({{undoList.length}})</h3>
                <div class="item" v-for="item in undoList":key="item.datetime">
                    <div class="control">
                        <input type="checkbox">
                        <span>{{item.datetime}}</span>
                    </div>
                    <div class="content">
                        {{item.content}}
                    </div>
                </div>
            </div>
            <div class="divider"></div>
            <div class="right">
                <h3>已完成({{doneList.length}})</h3>
                <div class="item" v-for="item in doneList":key="item.datetime">
                    <div class="control">
                        <input type="checkbox">
                        <span>{{item.datetime}}</span>
                        <img src="delete.png" alt="" class="del">
                    </div>
                    <div class="content">
                        {{item.content}}
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el:"#app",
            data:{
                list:[],
                value:""
            },
            computed:{
                undoList(){
                    return this.list.filter(v=>!v.done)
                },
                doneList(){
                    return this.list.filter(v=>v.done);
                }
            },
            methods:{
                handleClick(){
                    if(this.value===""){
                        alert("请填写事项的内容");
                        return;
                    }
                    let obj={};
                    obj.content=this.value;
                    obj.datetime=Date.now();//时间戳1970/01/01 0h 0min 0s到现在的毫秒数
                    obj.done=false;//完成状态
                    this.list.push(obj);//在数组末尾添加
                    this.value="";
                }
            },
        })
    </script>
</body>

效果展示:
在这里插入图片描述

利用过滤器进行日期显示:

<span>{{item.datetime|formatDate}}</span>
<span>{{item.datetime|formatDate}}</span>
 filters:{
                formatDate(value){
                    let date=new Date(value);
                    let year=date.getFullYear();
                    let month=date.getMonth();
                    let day=date.getDate();
                    let hour=date.getHours();
                    let min=date.getMinutes();
                    let sec=date.getSeconds();
                    return `${year}/${month}/${day} ${hour}:${min}:${sec}`;
                }
            },

效果展示:
在这里插入图片描述现在想要将待完成状态的事件标记成已完成状态,就要在待完成事件中添加点击事件,这也是利用了vue的一大优势,就是处理响应式数据。

<input type="checkbox" @click="item.done=true">

想要将已完成状态的事件改成待完成状态,也是一样的道理。在已完成事件中添加点击事件

 <input type="checkbox" @click="item.done=false">

效果展示:
在这里插入图片描述待办事件多了以后,会超出容器,此时要根据容器动态设置divider分割线的效果:
先定义一个height变量

data:{
                list:[],
                value:"",
                height:500//先设置分割线长度为500
            },

divider分割线内联一个样式:

 <div class="divider" :style="{height:height+'px'}"></div>

因为在vue中数据的更新和页面内容的更新并不是同步的,要想在网页进行下一次更新渲染之后才进行新的高度的设置,加上这段代码才能实现内容的高度始终和线的高度保持一致:

 this.$nextTick(()=>{
                        this.height=this.$refs.bottom.offsetHeight
                    })

效果展示:
在这里插入图片描述

批注:为了实现这一效果,我花了半小时时间,到最后才发现少写了一个字母,害得我找了半天,大家在写代码的时候,一方面要注意代码之间的逻辑,另一方面是不要马虎,要细心呀~

watch监听List的变换,目的是保存数据状态:

 watch: {
                list: {
                    handler() {
                        localStorage.list = JSON.stringify(this.list);//在localStorage里不能直接存储对象,要把this.list转换成字符串设置到本地存储当中
                    },
                    deep: true//深度监听
                }
            },
            mounted() {//生命周期函数,这是保存数据状态的方式
                if (localStorage.list) {//当重新加载数据时,要把localStorage.list里的数据转换回来
                    this.list = JSON.parse(localStorage.list);
                }
            },

设置删除效果

之前在已完成模块中设置的垃圾桶图片,现在给添加上点击事件:

 <img src="delete.png" alt="" class="del" @click="handleDelete(item)">
   handleDelete(item){
                    if(confirm("确定删除吗?")){
                    this.list=this.list.filter(v=>v.datetime!=item.datetime);
                }

点击垃圾桶就能进行删除操作
效果展示:
在这里插入图片描述

写在最后

希望我的分享能够帮助到更多的人,如果觉得我的分享有帮助的话,请大家一键三连支持一下哦~
原创不易,期待你的关注与支持~
点赞❤+收藏❤+评论❤
之后我会继续更新前端学习小知识,关注我不迷路~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/409203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决前端项目问题,uniapp运行微信开发工具小程序,出现× initialize报错,以及浏览器无法运行

项目场景&#xff1a; uniapp进行小程序以及多端web页面都不知道如何配置讲项目运行起来。 就会报出无法运行错误。 [微信小程序开发者工具] - initialize [微信小程序开发者工具] [微信小程序开发者工具] IDE may already started at port , trying to connect如图 问题描…

微信小程序前端解密获取手机号

微信小程序在获取用户手机号时安全正确的做法是把获取的iv等信息传递给后端&#xff0c;让后端解密&#xff0c;再提供接口返回给前端。 但是遇到一下比较一般的后端或者懒的后端的话&#xff0c;前端也可以考自己完成手机号解密。 1.使用授权手机号组件按钮 <view class&…

【Vue】Cannot set reactive property on undefined,null,or primitive value:undefined

一、背景描述技术栈&#xff1a;vue element报错内容&#xff1a;Cannot set reactive property on undefined, null, or primitive value:undefined如下图所示&#xff1a;二、报错原因根据报错内容翻译一下&#xff0c;就是不能对 undefined,null 或者原始值为 undefined 的…

uniapp中怎么使用easycom 自定义组件

一、全局注册 uni-app 支持配置全局组件&#xff0c;需在 main.js 里进行全局注册&#xff0c;注册后就可在所有页面里使用该组件。 Vue.component 的第一个参数必须是静态的字符串。nvue 页面暂不支持全局组件。 二、局部注册 局部注册之前&#xff0c;在需要引用该组件的…

详解Promise使用

Promise引入PromiseExecutorresolve不同值的区别then方法catch方法finally方法resolve类方法reject类方法all类方法allSettled方法race方法引入Promise 我们调用一个函数&#xff0c;这个函数中发送网络请求(我们可以用定时器来模拟)&#xff1b; 如果发送网络请求成功了&…

前端面试题 | 什么是回流和重绘?它们的区别是什么?

在了解回流和重绘之前我们可以先简单了解一下浏览器的渲染过程~ 1. 解析获取到的HTML&#xff0c;生成DOM树&#xff0c;解析CSS&#xff0c;生成CSSOM树 2. 将DOM树和CSSOM树进行结合&#xff0c;生成渲染树&#xff08;render tree&#xff09; 3.根据生成的渲染树&#xff0…

Vue开发环境安装

目录 Vue概述&#xff1a; Vue特点&#xff1a; Vue官网: 一、node.js安装和配置 1. 下载安装node.js Step1&#xff1a;下载安装包 Step2&#xff1a;安装程序 Step3&#xff1a;查看 问题解决&#xff1a; 解决npm warn config global --global, --local are depr…

Session详解

&#x1f451; 博主简介&#xff1a;    &#x1f947; Java领域新星创作者    &#x1f947; 阿里云开发者社区专家博主、星级博主、技术博主 &#x1f91d; 交流社区&#xff1a;BoBooY&#xff08;优质编程学习笔记社区&#xff09; 前言&#xff1a;上节我们详细讲解了…

华为云从入门到实战 | 云服务概述与华为云搭建Web应用

云计算在快速发展过程中逐渐形成了不同的服务模式(Service Model)。根据云计算最终服务的交付形态主要分为3种类型,软件即服务、平台即服务与基础架构即服务。从根源上来说,云计算的服务模式来源于面向服务的架构SOA(Service-Oriented Architecture)。所谓SOA,就是一种架构设…

npm install或npm i后没有依赖包node_modules?

今天git clone一个项目发现npm i后发现自己的文件下面没有node_modules包&#xff0c;但是有如图提示&#xff1a;但是文件夹下没有任何新增文件 added 1 package in 674ms 随后查看了C:\Users\俊\AppData\Roaming\npm\node_modules 图一&#xff1a; 里面存在今天执行npm i…

微信小程序实训|基于云数据库的语文听写工具

本实训项目结合云开发的云数据库和 “微信同声传译”插件&#xff0c;制作一个可真实运营的小学生语文听写工具&#xff0c;页面效果如图1所示。 ▍图1 “听写小助手”页面 基于云开发的微信小程序具有众多优势&#xff0c;云开发模式真正解放了开发者&#xff0c;使得开发效率…

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)

目录 一、todolist项目准备 vue3.0环境搭建&#x1f344; 二、todolist基本结构 1. 定义组件&#x1f437; 2.实现todolist需要用到的四个组件 &#x1f436; 3.ref定义单个数据 &#x1f42d; 4.reactive定义对象类型的数据&#x1f439; 5. 实现todolist每个组件需要…

前端实战【ES6】你会ES6,但是你真的会用吗?

目录&#x1f31f;前言&#x1f31f;关于取值&#x1f31f;关于合并数据&#x1f31f;关于拼接字符串&#x1f31f;关于if中判断条件&#x1f31f;关于列表搜索&#x1f31f;关于扁平化数组&#x1f31f;关于获取对象属性值&#x1f31f;关于添加对象属性&#x1f31f;关于输入…

vue父子组件传值:父传子、子传父

最近项目中又需要用到父子组件&#xff0c;用了很多次之后对父子组件终于有种从善如流的感觉。会了之后再看自己写的父子组件传值的文章&#xff0c;感觉还是存在很多问题的&#xff0c;问题就不改了&#xff0c;在这篇文章做个总结和纠正吧。 父子组件就是在一个vue文件中引入…

瑞吉外卖项目:编辑员工信息与公共字段自动填充

目录 一. 编辑员工信息 1.1 需求分析 1.2 代码编写 执行流程 后端代码 二. 项目公共字段填充 2.1 问题分析 2.2 代码实现 2.3 功能完善 一. 编辑员工信息 1.1 需求分析 在员工管理列表点击编辑按钮&#xff0c;跳转至编辑页面后&#xff0c;回显员工数据进行修改。 …

前端开发利器--PxCook(像素大厨)

前端开发利器 - - PxCook&#xff08;像素大厨&#xff09;1、PxCook简述2、PxCook安装3、PxCook基本操作3.1 通过软件打开设计图3.2 常用快捷键3.3 常用工具3.4 从psd文件中直接获取数据1、PxCook简述 前端开发软件&#xff1a; PS&#xff08;Photoshop&#xff09;收费、占…

【SVG】路径<Path>标签详解,一次搞懂所有命令参数

在上一篇文章 什么是SVG&#xff1f;——SVG快速入门 中我对SVG做了基础的介绍&#xff0c;这篇文章将集中讲解<path>标签 本站链接&#xff1a;什么是SVG&#xff1f;——SVG快速入门_gxyzlxf的博客-CSDN博客 稀土掘金链接&#xff1a;什么是SVG&#xff1f;——SVG快…

npm修改默认源(默认镜像)

1 npm修改默认源(默认镜像) 首先如果之前安装过node.js的需要先卸载&#xff0c;删除npm原始默认安装目录&#xff08;在cmd命令面板执行 npm config ls 查看npm默认路径&#xff09; 在cmd命令面板中输入npm config ls 查看npm默认路径 删除操作如下所示&#xff1a; 重新安…

js实现base64,url,blob之间的相互转换

一般来说前端展示图片会通过三种方式&#xff1a; url、base64、blob 1.url: 一般来说&#xff0c;图片的显示还是建议使用url的方式比较好。 let url "http://xxxxxx" 2.base64&#xff1a; 如果图片较大&#xff0c;图片的色彩层次比较丰富&#xff0c;则不适合…

【原创】基于JavaWeb的医院预约挂号系统(医院挂号管理系统毕业设计)

项目介绍&#xff1a;后端采用JspServlet。前端使用的是Layui的一个网站模板。开发一个在线的医院预约挂号系统。从角色的划分&#xff0c;包括用户、医生、管理员。功能模块上包括了公告发布、医院信息查看、医院医生信息查看、预约医生、病例记录、挂号审核、图表统计等模块。…