vue專案開發-3
專案實戰
篩選
- 有三種篩選:
- 全部:顯示全部 todo
- 進行中:顯示未完成的 todo
- 已完成:顯示已完成的 todo
- 使用者是想要進行中的 todo 還是已完成的todo?
- 可以發現使用者會點選相應的按鈕來表明他的意圖
- 如果在使用者點選按鈕時把他的意圖傳遞給 Vue 物件
- 給 data 增加一個屬性 intention,來記錄使用者的意圖
- 定義三種意圖:
- all:想檢視全部 todo
- ongoing:想檢視未完成的 todo
- completed:想檢視已完成的 todo
- 需要根據使用者的意圖從 todos 中篩選 todo
- 從 Vue 已繫結的資料中計算新的結果是計算屬性的典型應用場景,所以加一個 filteredTodos 計算屬性
- 會發現未完成的 todo 分別在 filteredTodos 和 leftTodosCount 兩個計算屬性中被計算了兩次
- n 根據使用者意圖返回的結果:filteredTodos
- 使用者點選按鈕的意圖需要傳給 Vue 物件
- 設定讓使用者的意圖在點選按鈕時傳給 Vue
- 給各個篩選按鈕繫結一個 click 事件
- 之前在迴圈顯示 todo 列表時使用的是 this.todos 的資料
- 把迴圈的內容改為 filteredTodos
- 迴圈過濾結果
<ul>
<li v-for='todo in filteredTodos' :key='todo.id'>
- 繫結事件
<span>篩選:
<input type="button" class="selected" value="全部"
@click="intention='all'">
<input type="button" value="進行中"
@click="intention='ongoing'">
<input type="button" value="已完成"
@click="intention='completed'">
- vue物件增加data屬性和計算屬性
data: function () {
...
intention: 'all'
...
computed: {
...
leftTodos(){
return this.todos.filter(todo => !todo.completed)
},
leftTodoCount(){
return this.leftTodos.length
},
filteredTodos(){
if(this.intention == 'ongoing'){
return this.leftTodos
}else if (this.intention == 'completed'){
return this.todos.filter(todo => todo.completed)
}else { //返回所有的
return this.todos
}
}
功能10:樣式繫結
- 使用v-bind:class繫結
<span>篩選:
<input type="button" class="selected" value="全部"
@click="intention='all'"
v-bind:class="{selected: intention==='all'}">
<input type="button" value="進行中"
@click="intention='ongoing'"
v-bind:class="{selected: intention==='ongoing'}">
<input type="button" value="已完成"
@click="intention='completed'"
v-bind:class="{selected: intention==='completed'}">
批量清除
- 只要把篩選出來的 todo 從 todos 列表刪除就可以了
- 先為按鈕繫結事件
- 然後實現相應的繫結方法
- 繫結事件
<input type="button" value="清除已完成"
@click="clearCompleted">
<input type="button" value="清除全部"
@click="clearAll">
- 實現方法methods
clearCompleted(){
this.todos = this.todos.filter(todo => !todo.completed)
},
clearAll(){
this.todos = []
}
功能11:動態顯示按鈕
- 繫結v-if條件刷選
<span>篩選:
...
<input v-if="leftTodoCount" type="button" value="進行中"
@click="intention='ongoing'"
v-bind:class="{selected: intention==='ongoing'}">
<input v-if="completedTodoCount" type="button" value="已完成"
@click="intention='completed'"
v-bind:class="{selected: intention==='completed'}">
<input v-if="completedTodoCount" type="button" value="清除已完成"
@click="clearCompleted">
- 增加和修改計算屬性
computed: {
...
completedTodos(){
return this.todos.filter(todo => todo.completed)
},
completedTodoCount(){
return this.completedTodos.length
},
功能12:使用者體驗
- 增加span的v-if
<div>
<span v-if="leftTodoCount">剩餘 {{ leftTodoCount }} 項未完成 ---</span>
<span v-else-if="completedTodoCount">全部完成,你真是太優秀了</span>
<span v-else>新增我的第一個TODO</span>
- 增加清除確認
clearCompleted(){
if(!confirm('確定清除已完成的待辦事項?')){
return
}
this.todos = this.todos.filter(todo => !todo.completed)
},
clearAll(){
if(!confirm('確定清除全部的待辦事項?')){
return
}
this.todos = []
}
功能13:回收站
- 新增一個回收站data物件:recycleBin
data: function () {
return {
...
recycleBin:[], //回收站
- 新增刪除標記:removed
addTodo: function () {
...
this.todos.push({id: id++, title: this.newTodoTitle,
completed:false, removed:false});
...
},
- 修改removedTodo,clearCompleted,clearAll,將刪除資料移動到回收站
removeTodo(todo){
let pos = this.todos.indexOf(todo);
let removedTodo = this.todos.splice(pos, 1)[0];
removedTodo.removed = true;
this.recycleBin.unshift(removedTodo)
},
clearCompleted(){
if(!confirm('確定清除已完成的待辦事項?')){
return
}
this.completedTodos.map(todo => todo.removed = true)
this.recycleBin.unshift(...this.completedTodos)
this.todos = this.leftTodos
},
clearAll(){
if(!confirm('確定清除全部的待辦事項?')){
return
}
this.todos.map(todo => todo.removed = true)
this.recycleBin.unshift(...this.todos)
this.todos = []
}
- DOM增加回收站按鈕,繫結事件
<input v-if="recycleBin.length" type="button" value="回收站"
@click="intention='removed'">
...
filteredTodos(){
...
}else if (this.intention == 'removed'){
return this.recycleBin
...
}
從回收站還原
- 還原按鈕
<li v-for='todo in filteredTodos' :key='todo.id'>
...
<input v-if="todo.removed" type="button" value="還原"
@click="restoreTodo(todo)"/>
<input v-else="todo.removed" type="button" value="刪除"
@click="removeTodo(todo)"/>
- 新增方法
restoreTodo: function(todo){
todo.removed = false
this.todos.unshift(todo) //恢復
pos = this.recycleBin.indexOf(todo)
this.recycleBin.splice(pos, 1)
},
本地儲存
-
Vue 提供了一種更通用的方式來觀察和響應 Vue 例項上的資料變動:偵聽屬性
-
現在只要一重新整理瀏覽器,所有todo 都沒了,因為的資料儲存在記憶體中,頁面重新整理資料就會清除
-
可以使用瀏覽器的 LocalStorage 來實現資料的持續性儲存
- 這樣一來只要使用者不刪除瀏覽器快取,todo 會一直在
- 當然瀏覽器清除快取後資料也沒有了
- 為了更加持久化儲存,可以使用資料庫,這裡只是用 LocalStorage
-
首先來定義一個物件,用於 LocalStorage 儲存和獲取 todo 的相關操作
- STORAGE_KEY 用來區分儲存到 LocalStorage 的內容,因為 LocalStorage 中可能儲存其它應用的資料,使用這個 key 用於區分
- todoStorage 是一個 JavaScript 的物件,它的屬性是兩個方法
- save 方法:把 todos 轉為 JSON 格式,然後將序列化的資料存入對應 key 為 STORAGE_KEY 的本地儲存中
- fetch 方法:從對應 STORAGE_KEY 的本地儲存將之前存入的 todo 資料取出並反序列化
-
為 todoStorage 物件繫結一個 uid 屬性,作用是後續新增 todo 時,用於確定新新增todo 的 id
- 注意這裡程式碼中的 localStorage 就代表了本地儲存物件,在支援 HTLM5 的瀏覽器中會存在這個物件,直接引用即可
-
每當使用者開啟頁面時,因為去 LocalStorage fetch 一下儲存的資料
-
當新增 todo 時,由於可能已經存在從本地取出的 todo 資料,新的 todo id 不能是從 0 開始了,而應該從已有 todoStorage.uid 開始
- 一旦新增了新的 todo,應該及時將新的 todo 存到本地,防止使用者不小心關閉頁面而導致資料丟失
- 可以使用 Vue 的 watch 來監聽使用者新增 todo 的事件,即監視 this.todos 的變化,一旦改變,立即修改本地儲存的 todos 的資料
-
定義localstorage儲存和獲取todo
<script>
let id = 0; // 用於 id 生成
var STORAGE_KEY = "dylan-vue2-todo"
var todoStorage = {
fetch(){ //讀
var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
todos.forEach(function(todo, index){
todo.id = index
});
todoStorage.uid = todos.length
return todos
},
save(todos){ //寫
localStorage.setItem(STORAGE_KEY,JSON.stringify(todos))
}
};
- 修改data
data: function () {
return {
todos: todoStorage.fetch(),
...
- 修改addTodo
addTodo: function () {
...
this.todos.push({id: todoStorage.uid++, title: this.newTodoTitle,
...
- 增加監聽
watch:{
todos:{
handler: function(todos){
todoStorage.save(todos)
},
deep: true
}
},
相關文章
- Vue3.x專案開發常用知識點Vue
- vue開發:前端專案模板Vue前端
- Vue3 專案Vue
- [VUE]vue3新建專案Vue
- vue3+typescript管理系統專案開發記錄1VueTypeScript
- 加快Vue專案的開發速度Vue
- 在 Laradock 中開發 Vue 專案Vue
- Vue從零開發SPA專案Vue
- web前端教程:Vue專案開發流程Web前端Vue
- Vue3教程:一個基於 Vue 3 + Vant 3 的商城專案開源啦!Vue
- Vue3的專案搭建Vue
- springboot+vue前後端分離專案-vue專案搭建3Spring BootVue後端
- 測試src的方式開發vue專案Vue
- Vue 框架-12-Vue 專案的詳細開發流程Vue框架
- vue專案開發過程常見問題Vue
- 如何用 Laravel Mix 單獨開發 Vue 專案?LaravelVue
- vue3+ts+elementPlus專案搭建Vue
- yarn + vue3 + vite 建立專案YarnVueVite
- Vue3專案配置 eslint + prettierVueEsLint
- 推薦 10 個好用的 Vue3 的開源專案,開發效率又能提升了?Vue
- python3 專案開發-中級篇Python
- Vue3 來了,Vue3 開源商城專案重構計劃正式啟動!Vue
- Vue(1):用Vue-cli構建Vue3專案Vue
- Cordova+vue 混合app開發(一)建立Cordova專案VueAPP
- 深入Vue後臺管理開發(1)專案安裝Vue
- Vue開源專案使用探索Vue
- 【Vue】vue專案目錄介紹 es6的匯入匯出語法 vue專案開發規範 Vue專案編寫步驟Vue
- 【vue3-ts】-小兔鮮兒專案2022新版-系列開篇Vue
- cli3 使用 vue init 建立專案Vue
- vue3專案中安裝lessVue
- Vue-cli3+Typescript+Element搭建專案VueTypeScript
- ThreeJs 3D 全景專案開發總結JS3D
- Unity3D Demo專案開發記錄Unity3D
- Python爬蟲開發與專案實踐(3)Python爬蟲
- vue3開發文件Vue
- Vue3.x全家桶+vite+TS-搭建Vue3.x專案VueVite
- 從react轉職到vue開發的專案準備ReactVue
- 飛冰 2.0 正式釋出並支援 Vue 專案開發Vue