使用vue重构ToDoList—最简单的待办事项列表

使用vue重构ToDoList—最简单的待办事项列表

大家好,我是一个刚入门前端的一个小白,希望各位大佬们能够对小的多多指导,我先做一下自我介绍吧。我叫王小辉,我大学的专业是播音主持,为什么选择学习前端呢,这就跟我大学最后一年跟几个小伙伴一起创业开始说起,其实也不能完全说成创业,其实就是大学期间认识的几个小伙伴想一起做一些喜欢的事情,那是18年年初,当时小程序市场起步,市场上大大小小的小程序公司如雨后春笋冒出来,当时我们觉得这个小程序是一个市场,并且可以通过大学生创业这个方式获取到一些资源。我的另两个小伙伴分别是商学院和艺术设计学院的,我们当时没有一个人懂得技术,所以我们就了解到了,一些大的互联网公司做的小程序可以代理,可以开代理商后台的,我们当时拿着三千以大学生创业的身份跟广州的一家小程序公司谈,最后谈了下来,基本一个模版都在300-1000左右的拿货价,接下来我们就开始了漫长的推广过程,刚好当时赶到暑假,临时招募学校里的几位同学加入我们,公司的运营总共持续了5个月左右,总共谈下2位代理,8个客户,共计收到打款十多万。感觉自己扯的有点远了,继续说回为什么想要学习编程,就是因为在我们业务的过程中遇到了很多的难题,模版的功能是固定的,客户的需求无法满足,给当时的我们造成很多的困扰,所以当时就萌生了这个想法,当时也尝试着学习一些基础的页面的东西,尝试去满足客户需求,但是对于一个什么都不动的文科生,实在是太难了。但是前端时间因为疫情所以决心转变一下,当时也是考虑很久,对前端也比较感兴趣。其他废话就不说了,最近学到vue,做了一个作业,在这里分享出来,希望大佬指点一下,哪里需要改进,请不吝赐教。

先来分享一下已经打包上线的demo

ToDoList-代办事项列表
地址:http://todolist.wyhvip.top/#/

为了练习数据流,我总共分成了三个组件
其实最后两个组件逻辑相似,其实是可以和在一起的,这样可以节省很多代码段
下面这个Home是主组件

<template>
  <div class="home">
    <header>
      <div class="banxin">
        <label for="textval">ToDoList</label>
        <input
          type="text"
          placeholder="添加ToDo"
          id="textval"
          v-model.trim="userval"
          @keyup.enter="submit"
        />
      </div>
    </header>
    <section class="banxin">
      <div class="title">
        <h2>正在进行</h2>
        <span>{{goingArr.length}}</span>
      </div>
      <ul-comp
        :goingarr="goingArr"
        @goingtogdown="fathergoingtogdown"
        @delgoingarr="fatherdelgoingarr"
        @goingtoginphdiv="fathergoingtoginphdiv"
        @xggoingarrs="fatherxggoingarrs"
      ></ul-comp>
    </section>
    <section class="banxin">
      <div class="title">
        <h2>已经完成</h2>
        <span>{{doneArr.length}}</span>
      </div>
      <ol-comp
        :donearr="doneArr"
        @donetogup="fatherdonetogup"
        @deldonearr="fatherdeldonearr"
        @donetoginphdiv="fatherdonetoginphdiv"
        @xgdonegarrs="fatherxgdonegarrs"
      ></ol-comp>
    </section>
    <footer>
      Copyright &copy; 2020 todolist.wyhvip.top
      <a @click="createlocalstorage">clear</a>
    </footer>
  </div>
</template>

<script>
// @ is an alias to /src
import UlComp from "../components/UlComp.vue";
import OlComp from "../components/OlComp.vue";

export default {
  name: "Home",
  components: {
    UlComp,
    OlComp
  },
  data() {
    return {
      userval: "",
      num: 0,
      goingArr: [],
      doneArr: []
    };
  },
  created() {
    this.num = JSON.parse(localStorage.getItem("num")) || 0;
    this.goingArr = JSON.parse(localStorage.getItem("goingArr")) || [];
    this.doneArr = JSON.parse(localStorage.getItem("doneArr")) || [];
  },
  methods: {
    fathergoingtogdown(i) {
      this.goingArr[i].ifShowIpu = false;
      this.goingArr[i].ifCheck = true;
      this.doneArr.unshift(this.goingArr[i]);
      this.goingArr.splice(i, 1);
      this.setlocalstorage();
    },
    fatherdonetogup(i) {
      this.doneArr[i].ifShowIpu = false;
      this.doneArr[i].ifCheck = false;
      this.goingArr.push(this.doneArr[i]);
      this.doneArr.splice(i, 1);
      this.setlocalstorage();
    },
    fatherdelgoingarr(i) {
      this.goingArr.splice(i, 1);
      this.setlocalstorage();
    },
    fatherdeldonearr(i) {
      this.doneArr.splice(i, 1);
      this.setlocalstorage();
    },
    fathergoingtoginphdiv(i) {
      this.goingArr[i].ifShowIpu = true;
      this.setlocalstorage();
    },
    fatherdonetoginphdiv(i) {
      this.doneArr[i].ifShowIpu = true;
      this.setlocalstorage();
    },
    submit() {
      if (this.userval == "") {
        return;
      } else {
        this.num++;
        let obj = {
          id:
            this.num < 10
              ? "00" + this.num
              : this.num < 100
              ? "0" + this.num
              : "" + this.num,
          ifCheck: false,
          ifShowIpu: false,
          content: this.userval
        };
        this.goingArr.unshift(obj);
        this.userval = "";
        this.setlocalstorage();
      }
    },
    setlocalstorage() {
      localStorage.setItem("num", this.num);
      localStorage.setItem("goingArr", JSON.stringify(this.goingArr));
      localStorage.setItem("doneArr", JSON.stringify(this.doneArr));
    },
    fatherxggoingarrs(i) {
      this.goingArr[i].ifShowIpu = false;
      this.setlocalstorage();
    },
    fatherxgdonegarrs(i) {
      this.doneArr[i].ifShowIpu = false;
      this.setlocalstorage();
    },
    createlocalstorage() {
      localStorage.clear();
      this.goingArr = [];
      this.doneArr = [];
    }
  }
};
</script>
<style>
* {
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;
}
body {
  background-color: #cdcdcd;
  font-size: 16px;
}
.banxin {
  width: 600px;
  margin: 0 auto;
}
header {
  min-width: 600px;
  height: 50px;
  background: rgba(47, 47, 47, 0.98);
}
label {
  float: left;
  width: 100px;
  line-height: 50px;
  color: #ddd;
  font-size: 24px;
  cursor: pointer;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
header input {
  float: right;
  width: 60%;
  height: 24px;
  margin-top: 12px;
  text-indent: 10px;
  border-radius: 5px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24),
    0 1px 6px rgba(0, 0, 0, 0.45) inset;
  border: none;
  outline: none;
}
.title {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.title h2 {
  font-size: 24px;
  color: #000;
  margin: 20px 0;
}
.title span {
  display: inline-block;
  padding: 0 5px;
  height: 20px;
  border-radius: 20px;
  background: #e6e6fa;
  line-height: 22px;
  text-align: center;
  color: #666;
  font-size: 14px;
}
.list li {
  height: 32px;
  line-height: 32px;
  background: #fff;
  margin-bottom: 10px;
  border-radius: 3px;
  border-left: 5px solid #629a9c;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07);
  display: flex;
  justify-content: space-around;
  align-items: center;
  cursor: grabbing;
}
.list li .fxk {
  width: 22px;
  height: 22px;
  cursor: pointer;
  margin: 3px 3px 3px 4px;
  margin-left: 10px;
}
.list li .txt {
  width: 421px;
  height: 24px;
  padding: 1px 2px;
  border-radius: 5px;
  text-indent: 1em;
  font-size: 16px;
  color: #000;
  /* outline: none; */
  outline-color: #999;
  cursor: progress;
}
.list li div {
  width: 421px;
  height: 32px;
  padding: 1px 2px;
  text-indent: 1em;
  font-size: 16px;
  color: #000;
}
.list li label {
  width: 100px;
  height: 32px;
}
.list li a {
  float: right;
  text-decoration: none;
  width: 14px;
  height: 12px;
  border-radius: 14px;
  border: 6px double #fff;
  background: #ccc;
  line-height: 14px;
  text-align: center;
  color: #fff;
  font-weight: bold;
  font-size: 14px;
  cursor: pointer;
  margin-right: 5px;
}
.ollist li {
  border-left: 5px solid #999;
  opacity: 0.5;
  cursor: progress;
}
footer {
  font-size: 14px;
  color: #666;
  text-align: center;
  display: block;
  margin-top: 20px;
  margin-bottom: 30px;
}
footer a {
  text-decoration: none;
  font-size: 14px;
  color: #999;
  cursor: pointer;
}
</style>

下面就是正在进行的组件和已完成的组件

正在进行组件

<template>
  <ul class="list">
    <li v-for="(item,i) in goingarr" :key="item.id">
      <input :checked="item.ifCheck" type="checkbox" class="fxk" @click="togdwon(i)" />
      <input
        v-focus
        v-if="item.ifShowIpu"
        type="text"
        class="txt"
        :id="item.id"
        v-model="item.content"
        @keyup.13="xggoingarr(i)"
        @blur="blurIpu(i)"
      />
      <div v-else @click="toginphdiv(i)">{{item.content}}</div>
      <label :for="item.id" @click="toginphdiv(i)"></label>
      <a @click="dellist(i)">-</a>
    </li>
  </ul>
</template>

<script>
export default {
  props: ["goingarr"],
  methods: {
    togdwon(i) {
      this.$emit("goingtogdown", i);
    },
    dellist(i) {
      this.$emit("delgoingarr", i);
    },
    toginphdiv(i) {
      this.$emit("goingtoginphdiv", i);
    },
    xggoingarr(i) {
      this.$emit("xggoingarrs", i);
    },
    blurIpu(i) {
      this.$emit("xggoingarrs", i);
    }
  },
  directives: {
    focus: {
      inserted(el) {
        el.focus();
      }
    }
  }
};
</script>

<style>
</style>

已经完成的组件

<template>
  <ol class="list ollist">
    <li v-for="(item,i) in donearr" :key="item.id">
      <input :checked="item.ifCheck" type="checkbox" class="fxk" @click="togup(i)" />
      <input
        v-focus
        v-if="item.ifShowIpu"
        type="text"
        class="txt"
        :id="item.id"
        v-model="item.content"
        @keyup.13="xgdonegarr(i)"
        @blur="blurIpu(i)"
      />
      <div v-else @click="toginphdiv(i)">{{item.content}}</div>
      <label :for="item.id" @click="toginphdiv(i)"></label>
      <a @click="dellist(i)">-</a>
    </li>
  </ol>
</template>

<script>
export default {
  props: ["donearr"],
  methods: {
    togup(i) {
      this.$emit("donetogup", i);
    },
    dellist(i) {
      this.$emit("deldonearr", i);
    },
    toginphdiv(i) {
      this.$emit("donetoginphdiv", i);
    },
    xgdonegarr(i) {
      this.$emit("xgdonegarrs", i);
    },
    blurIpu(i) {
      this.$emit("xggoingarrs", i);
    }
  },
  directives: {
    focus: {
      inserted(el) {
        el.focus();
      }
    }
  }
};
</script>

<style>
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值