本篇咱們需要完成一個小案例,該案例的效果如下:

接著我們就來一步一步實作這個案例吧~
一、組件化編碼流程:
(1).拆分靜態組件:組件要按照功能點拆分,命名不要與html元素沖突,
(2).實作動態組件:考慮好資料的存放位置,資料是一個組件在用,還是一些組件在用:
1).一個組件在用:放在組件自身即可,
2). 一些組件在用:放在他們共同的父組件上(狀態提升),
(3).實作互動:從系結事件開始,
拆分好的頁面結構如下:


將所有的結構、樣式搭建好后我們就開始添加互動效果,
二、添加互動效果
1.初始化頁面
首先我們先生成假資料,完成頁面初始化(勾選框),在這里我們可以先把假資料放在App組件下,由App組件管理資料,
2.todoHeader組件
在todoheader中輸入資料,按回車添加一條資料,注意,此時生成的資料需要通知給App組件,在此處,我們是將子組件的資料傳遞給父組件,我們可以在父組件傳遞一個函式給子組件,讓子組件呼叫,但顯然這不是最優解,最優解是給父組件系結一個自定義事件,
相關代碼如下:
//App組件
methods: {
todoAdd(todo) {
// console.log("我收到了資料:", todo);
this.todos.unshift(todo);
},
}
// todoHeader
methods: {
// 添加一個
add() {
if (!this.title) return alert("輸入不能為空");
const todoObj = { id: nanoid(), title: this.title, done: false };
this.$emit("todoAdd", todoObj);
this.title = "";
},
},
3.todoList組件(todoItem組件)
接著我們完成的是中間的todoList板塊,List中又嵌套著todoItem組件,所以操作都是在todoItem上進行的,主要是完成添加勾選、洗掉功能,在初始化時,我們將資料放在App組件上,而真正需要資料的是todoItem組件,這里我們可以使用全域事件總線或者是訊息的訂閱與發布去實作組件間的通信,
//main.js
beforeCreate() {
Vue.prototype.$bus = this // 安裝全域事件總線
}
// App組件
methods: {
//TodoItem
todoCheck(id) {
this.todos.forEach((todo) => {
if (todo.id === id) todo.done = !todo.done;
});
},
todoDetele(_, id) {
this.todos = this.todos.filter((todo) => {
return todo.id !== id;
});
},
}
mounted() {
// 全域事件總線
this.$bus.$on("todoCheck", this.todoCheck);
// 訊息的訂閱與發布
this.pubId = pubsub.subscribe("todoDetele", this.todoDetele);
}
beforeDestroy() {
this.$bus.$off("todoCheck");
pubsub.unsubscribe(this.pubId);
},
}
//item
methods: {
handleCheck(id) {
// 通知App更改資料
this.$bus.$emit("todoCheck", id);
},
handleDelete(id) {
//通知App更改資料
if (confirm("確定洗掉嗎?")) {
// this.$bus.$emit('todoDetele',id)
pubsub.publish("todoDetele", id);
}
},
}
注意:在使用全域事件總線時,如果傳遞的引數不需要時,需要用_占位,否則Vue中嚴格檢查會報錯,
4.todoFooter組件
在這個版塊也是由子組件傳遞資料給父組件,使用自定義事件即可,和todoHeader的做法是類似的,在這個板塊中我們要實作的功能就是底部全選、任務串列、清除已完成任務,
5.將TodoList變成本地存盤
其實至此我們的todoList案例已經初具雛形,但是這個待辦事項應該是一個本地存盤,當我們下次打開這個網頁時,上次的記錄應保留,
于是我們就需要使用到webStorage來幫助我們存盤,
Window.sessionStorage--存盤的內容會隨著瀏覽器視窗關閉而消失
Window.localStorage --存盤的內容,需要手動清除才會消失,
以上兩種存盤方式,它們的API是完全相同的,主要區別就在是否是會存盤到本地,相關API如下:
☆添加:xxxxxStorage.setItem('key', 'value');
☆獲取:xxxxxStorage.getItem('person');
☆洗掉:xxxxxStorage.removeItem('key');
☆清空:xxxxxStorage.clear()在必要的時候搭配JSON.stringify和JSON.parse方法使用,
注意:xxxxxStorage.getItem(xxx) 如果xxx對應的value獲取不到,那么getItem的回傳值是null,JSON.parse(null)的結果依然是null,
在這個案例中,我們需要把初始化生成的假資料刪掉,換成我們動態添加的資料,并將這些資料存盤到本地,那么如何能通知App組件資料變化了呢,我們之前學過一個屬性,專門用來監視資料,即watch屬性,
相關代碼如下:
// App組件
data() {
return {
todos: JSON.parse(localStorage.getItem("todos")) || [],
};
},
watch: {
todos: {
deep: true,
handler(value) {
localStorage.setItem("todos", JSON.stringify(value));
},
},
},
注意:我們存盤的是一個物件,當要監聽這個物件里面的屬性和方法時,我們需要開啟深度監視,
6.添加編輯功能
一個基礎的待辦事項應該具有增刪改查的功能,所以為了讓功能更加齊全,我們為每個todo添加上編輯功能,邏輯是:當我們點擊編輯按鈕,檔案變成輸入框,可以修改文字,當輸入框失去焦點時,完成修改,在修改文字時,編輯按鈕消失,
那么我們就需要再寫一個輸入框,系結同樣的資料,用條件判斷是否顯示,書寫完樣式后就開始系結各種事件,
<template>
<li>
<label>
<input
type="checkbox"
:checked="todo.done"
@change="handleCheck(todo.id)"
/>
<span v-show="!todo.isEdit">{{ todo.title }}</span>
<input
type="input"
v-show="todo.isEdit"
:value="todo.title"
@blur="handleBlur(todo, $event)"
ref="inputTitle"
/>
</label>
<button class="btn btn-danger" @click="handleDelete(todo.id)">洗掉</button>
<button
class="btn btn-edit"
@click="handleEdit(todo)"
v-show="!todo.isEdit"
>
編輯
</button>
</li>
</template>
methods: {
handleEdit(todo) {
if (todo.isEdit) {
// if todo.hasOwnProperty("isEdit")
todo.isEdit = true;
} else {
this.$set(todo, "isEdit", true);
}
this.$nextTick(function () {
this.$refs.inputTitle.focus();
});
},
handleBlur(todo, e) {
todo.isEdit = false;
if (!e.target.value.trim()) return alert("輸入不能為空!");
this.$bus.$emit("todoUpdata", todo.id, e.target.value);
},
}
6.添加過渡/影片效果
最后為了優化用戶體驗感,添加了一個過渡效果,
過渡與影片
作用:在插入、更新或移除 DOM元素時,在合適的時候給元素添加樣式類名,
使用:
1.樣式
/* 元素進入的樣式 */
1. v-enter:進入的起點
2. v-enter-active:進入程序中
3. v-enter-to:進入的終點
/*元素離開的樣式 */
1. v-leave:離開的起點
2. v-leave-active:離開程序中
3. v-leave-to:離開的終點
2.用法
需要使用<transition>包裹要過渡的元素,并且配置name屬性,
注意:若有多個元素要過渡,使用<transition-group>,且要指定key,
具體是影片還是過渡效果看如何使用:
影片:css中的影片樣式+todo-enter-active實作影片
/* 影片 */
.todo-enter-active {
animation: atguigu 0.5s linear;
}
.todo-leave-active {
animation: atguigu 0.5s linear reverse;
}
@keyframes atguigu {
from {
transform: translateX(100%);
}
to {
transform: translateX(0px);
}
}
過渡:定義過渡的起點和終點,以及在過渡時間和效果
/* 過渡 */
.todo-enter-active,
.todo-leave-active {
transition: 0.5s linear;
}
.todo-enter {
transform: translateX(100%);
}
.todo-enter-to,
.toddo-leave {
transform: translateX(0);
}
.todo-leave-to {
transform: translateX(-100%);
}
當然,我們也可以使用一些第三方庫實作更好的影片效果,在這里我們不過多做探討,至此,一個簡單的TodoList就完成啦,本篇只是大概梳理了一下每個組件的實作邏輯,練習組件間的通信方式,
這是使用vue腳手架完成的第一個小專案,感覺之前學習的知識終于能用上了,而且腳手架中幫我們把很多東西都完成了初始化,讓我們寫代碼的效率噌噌噌往上漲!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/398704.html
標籤:其他
