todolist案例源码(vue2脚手架实现)

编程入门 行业动态 更新时间:2024-10-10 19:16:44

todolist案例源码(vue2<a href=https://www.elefans.com/category/jswz/34/1756721.html style=脚手架实现)"/>

todolist案例源码(vue2脚手架实现)

实现效果

todolist

代码

1. main.js入口文件

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false;// 创建vm
new Vue({el: '#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus = this}
})

2. App.vue

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><HeaderInput @ReceiveAddTodo="ReceiveAddTodo" ></HeaderInput><TodoList :todos="todos" ></TodoList><FooterTotal :todos="todos" @selectAllTodo="selectAllTodo" @clearAlll="clearAlll"></FooterTotal></div></div>
</div>
</template>
<script>import HeaderInput from './components/HeaderInput.vue';import TodoList from './components/TodoList.vue';import FooterTotal from './components/FooterTotal.vue';import pubsub from 'pubsub-js'export default {name:"App",components:{ HeaderInput, TodoList, FooterTotal},data(){return{todos:JSON.parse(localStorage.getItem("todos"))||[],}},methods:{//添加一个todoReceiveAddTodo(todo){this.todos.unshift(todo)},//勾选一个todocheckTodo(id){this.todos.forEach((todo)=>{if(todo.id===id) todo.done=!todo.done})},//删除一个tododeleteTodo(_,id){if(confirm("确认删除吗?")){this.todos = this.todos.filter((todo)=>{return todo.id !== id})}},//全选selectAllTodo(checkValue){if(checkValue){this.todos.forEach(todo=>todo.done=true)}else{this.todos.forEach(todo=>todo.done=false)}},//清除已选clearAlll(){if(confirm("确认要清除已完成的任务吗?")){this.todos=this.todos.filter(todo=>todo.done!==true)}},editTitle(id,value){this.todos.forEach(todo=>{if(todo.id===id) todo.title=value})}},watch:{todos:{deep:true,handler(value){localStorage.setItem("todos",JSON.stringify(value))}}},mounted(){this.$bus.$on("checkTodo",this.checkTodo)// this.$bus.$on("deleteTodo",this.deleteTodo)this.pubId = pubsub.subscribe("delId",this.deleteTodo)this.$bus.$on("editTitle",this.editTitle)},beforeDestroy(){this.$bus.$off("checkTodo")// this.$bus.$off("checkTodo","deleteTodo")pubsub.unsubscrube(this.pubId)}}</script>
<style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-edit {color: #fff;background-color: skyblue;border: 1px solid rgb(117, 173, 196);}.btn-edit:hover {color: #fff;background-color: rgb(89, 147, 171);}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}</style>

3. 头部组件 HeaderInput.vue

<template><div class="todo-header"><input type="text" placeholder="请输入你的任务名称,按回车键确认" @keyup.enter="addTodo" v-model.trim="title"/></div>
</template>
<script>import {nanoid} from "nanoid"export default {name:"HeaderInput",data(){return{title:""}},methods:{addTodo(){if(this.title==="") return alert("不能为空")const todoObj = {id:nanoid(),title:this.title,done:false};this.$emit("ReceiveAddTodo",todoObj);this.title="";}},}
</script>
<style scoped>/*header*/.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;}.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);}
</style>

4. 列表组件TodoList.vue

<template><ul class="todo-main"><TodoItem v-for="todo in todos" :key="todo.id" :todo="todo" ></TodoItem></ul>
</template>
<script>import TodoItem from './TodoItem.vue'export default {name:"TodoList",components:{ TodoItem},props:["todos"]}
</script>
<style scoped>/*main*/.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;}
</style>

5. 列表item组件TodoItem.vue

<template><li><label><input type="checkbox" :checked="todo.done" @click="check(todo.id)"/><span v-show="!todo.isEdit">{{todo.title}}</span><input type="text" :value="todo.title" v-show="todo.isEdit" @blur="cancelBlur(todo,$event) "ref='edit'></label><button class="btn btn-danger" @click="delT(todo.id)">删除</button><button class="btn btn-edit" @click="editTodo(todo)" v-show="!todo.isEdit">编辑</button></li>
</template>
<script>import pubsub from 'pubsub-js'export default {name:"TodoItem",props:["todo"],methods:{check(id){this.$bus.$emit("checkTodo",id)},delT(id){// this.$bus.$emit("deleteTodo",id)pubsub.publish("delId",id)},//编辑editTodo(todo){if(Object.prototype.hasOwnProperty.call(todo,"isEdit")){todo.isEdit=true}else{this.$set(todo,"isEdit",true)}this.$nextTick(function(){this.$refs.edit.select()})},//失去焦点cancelBlur(todo,e){if(e.target.value.trim()===""){alert("输入不能为空")}else{todo.isEdit=falsethis.$bus.$emit("editTitle",todo.id,e.target.value.trim())}}}}
</script>
<style scoped>/*item*/li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;}li label {float: left;cursor: pointer;}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;}li button {float: right;display: none;margin-top: 3px;}li:before {content: initial;}li:last-child {border-bottom: none;}li:hover{background-color: #ddd;}li:hover button{display: block;}
</style>

6. 底部组件FooterTotal.vue

<template><div class="todo-footer" v-show="todos.length"><label><!-- <input type="checkbox" @change="selectAll"  :checked="isAll"/> --><input type="checkbox" v-model="isAll"/></label><span><span>已完成{{todoDone}}</span> / 全部{{todos.length}}</span><button class="btn btn-danger" @click="clearAll">清除已完成任务</button></div>
</template>
<script>export default {name:"FooterTotal",props:["todos"],computed:{todoDone(){// let quantity=0// this.todos.forEach(todo => {//     if(todo.done){//         quantity++//     }// });// return quantityreturn this.todos.reduce((pre,todo)=>pre+(todo.done==true?1:0),0)},isAll:{get(){return this.todoDone==this.todos.length&&this.todos.length>0},set(value){this.$emit("selectAllTodo",value)}}},data(){return {selectA:""}},// methods: {//         selectAll(e){//             this.selectAllTodo(e.target.checked)//         }//     }methods:{clearAll(){this.$emit("clearAlll")}}}
</script>
<style scoped>/*footer*/.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;}.todo-footer button {float: right;margin-top: 5px;}</style>

更多推荐

todolist案例源码(vue2脚手架实现)

本文发布于:2024-02-11 21:10:07,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1683504.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:脚手架   源码   案例   todolist

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!