vue基礎(五),對todos的操作
阿新 • • 發佈:2020-08-17
對於totos的操作
入口main.js檔案
// 引入vue
import Vue from 'vue'
// 引入App
import App from './App'
// 配置vue物件
new Vue({
el:"#root",
// 註冊元件,渲染元件
render : h=> h(App)
})
App元件
<template> <div class="todo-container"> <div class="todo-wrap"> <Header :todos="todos" :updateO="updateO"></Header> <Main :todos="todos" :changeStatus= "changeStatus" :dltO="dltO" ></Main> <Footer :todos="todos" :delQc="delQc"></Footer> </div> </div> </template> <script> // 引入元件 import Header from'@/components/Header' import Main from '@/components/Main' import Footer from '@/components/Footer' export default { name:'App', data() { return { todos:[ {id:1,content:'抽菸', isOver:false}, {id:2,content:'喝酒', isOver:true}, {id:3,content:'燙頭', isOver:false}, ] }; }, methods:{//接收header的資料 updateO(obj){ //新增的物件的id是最後一個id加1 let id = this.todos[this.todos.length-1].id+1 obj.id =id //陣列往頂部新增一個物件 this.todos.unshift(obj) console.log(this.todos) }, //item元件點選單選框,改變狀態 changeStatus(index){ //取反 this.todos[index].isOver = !this.todos[index].isOver }, //item元件點選刪除按鈕 dltO(index){ this.todos.splice(index,1) }, //對於footer元件中過濾的新陣列賦值給原陣列 delQc(newTodos){ this.todos =newTodos } }, // 註冊元件 components:{ Header, Main, Footer, } }; </script> <style scoped lang="less"> /*app*/ .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
Header元件
<template> <div class="todo-header"> <input type="text" placeholder="請輸入你的任務名稱,按回車鍵確認" v-model="content" @keyup.enter="update" /> </div> </template> <script> export default { //輸入框一個按鍵事件,新增li name:'Header', data() { return { content:'', }; }, // 接收父元件的資料 props:{ todos:Array, updateO:Function }, methods:{ //輸入框輸入資料,組成一個新物件,給父元件傳遞過去 update(){ let {content} =this if(content.trim()){ //新物件 let obj ={ content, isOver:false } //傳遞資料給父元件 this.updateO(obj) this.content='' } } } }; </script> <style scoped lang="less"> /*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>
Main元件
<template> <ul class="todo-main"> <Item v-for="(todo, index) in todos" :key="todo.id" :todo="todo" :index="index" :changeStatus= "changeStatus" :dltO="dltO" ></Item> </ul> </template> <script> import Item from './Item' export default { name:'Main', data() { return {}; }, props:{ todos:Array, changeStatus:Function, dltO:Function, }, //註冊元件 components:{ Item } }; </script> <style scoped lang="less"> /*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>
Item元件
<template> <li @mouseenter="isShow=true" @mouseleave="isShow=false" :class="{myClass:isShow}"> <label> <input type="checkbox" :checked="todo.isOver" @click="changeZt" /> <span>{{todo.content}}</span> </label> <button class="btn btn-danger" v-show="isShow" @click="deleteO" >刪除</button> </li> </template> <script> export default { //1.點選li中的單選按鈕,需要父元件的資料更改狀態,需要傳遞一個index引數,定位是那個li //2.點選刪除按鈕,需要父元件運算元組的邏輯,需要傳遞一個index引數,定位是那個li //3.移入,移出事件,li變化顏色,而且刪除按鈕也會跟著改變 name:"Item", props:{ todo:Object, index:Number, changeStatus:Function, dltO:Function, }, data() { return { //定義一個狀態 isShow:false }; }, methods:{ changeZt(){ //點選單選框,更改狀態 this.changeStatus(this.index) }, //點選刪除按鈕 deleteO(){ //給組價傳遞index this.dltO(this.index) } } }; </script> <style scoped lang="less"> /*item*/ .myClass{ background-color: hotpink; } 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; } </style>
Footer元件
<template> <div class="todo-footer"> <label> <input type="checkbox" v-model="ischeck" /> <!-- isCheckAll的資料是和checked屬性值進行關聯的 --> <!-- v-model 如果input當中是有value的,那麼v-model影響的就是value的值 對於文字輸入框密碼輸入框來說一定是有value的 對於單選輸入框和多選輸入框,如果沒有寫value,那麼影響的的是checked的值 --> </label> <span> <span>已完成{{qcNum}}</span> / 全部{{qbNum}} </span> <button class="btn btn-danger" @click="deleteQc">清除已完成任務</button> </div> </template> <script> export default { //1.父元件傳遞todos元件,計算已完成和全部數量 // 2.對於全選按鈕,需要判斷兩種情況,一種是獲取,一種是修改 // 對於獲取邏輯,需要判斷已完成數量和全部數量是否全等, //對於修改邏輯,則需要對遍歷todos的每個物件,狀態進行修改 //3.對於清除已完成的任務,需要判斷已經狀態為true的物件清除 name:'Footer', props:{ todos:Array, delQc:Function, }, data() { return {}; }, methods:{ deleteQc(){ //將新陣列傳遞父元件,讓父元件對原陣列跟新 let newTodos= this.todos.filter(item =>!item.isOver) this.delQc(newTodos) } }, // 計算屬性,元件中沒有的屬性 computed:{ //計算完成的數量 qcNum(){ return this.todos.filter(item =>item.isOver).length }, //計算全部的數量 qbNum(){ return this.todos.length }, ischeck:{ //獲取方法 get(){ return this.qcNum ===this.qbNum && this.qbNum>0 }, //修改方法 set(value){ //遍歷todos,將每一項的isOver都隨著vlaue改變 this.todos.forEach(item =>item.isOver = value) } } } }; </script> <style scoped lang="less"> /*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>