目錄
一.準(zhǔn)備工作
二.編寫各個(gè)組件的頁面結(jié)構(gòu)
三.實(shí)現(xiàn)初始任務(wù)列表的渲染
四.新增任務(wù)
五.刪除任務(wù)
六.展示未完成條數(shù)
七.切換狀態(tài)-篩選數(shù)據(jù)
八.待辦事項(xiàng)(全)代碼
一.準(zhǔn)備工作
在開發(fā)“ToDoList”案例之前,需要先完成一些準(zhǔn)備工作,包括創(chuàng)建項(xiàng)目、引入 BootStrap 樣式文件和搭建基本項(xiàng)目結(jié)構(gòu),下面分別進(jìn)行實(shí)現(xiàn)。
(1)創(chuàng)建項(xiàng)目 創(chuàng)建項(xiàng)目包含新建項(xiàng)目、安裝依賴項(xiàng)和運(yùn)行項(xiàng)目,具體步驟如下。
① 創(chuàng)建項(xiàng)目。使用HbuliderX軟件創(chuàng)建todolist項(xiàng)目 在src的目錄下創(chuàng)建style.css 文件中的樣式,具體代碼如下。
style.css樣式如下:
:root {
font-size: 16px;
}
body {
margin: 0;
}
② 新建并封裝組件。在D:\vue\chapter03\todolist\src\components 目錄下新建文件 ToDoHeader.vue、ToDoMain.vue 和 ToDoFooter.vue,分別表示 ToDoHeader、ToDoMain 和ToDoFooter 組件。
③?各個(gè)組件中的<style>節(jié)點(diǎn)的樣式代碼。
二.編寫各個(gè)組件的頁面結(jié)構(gòu)
準(zhǔn)備工作完成之后,接下來編寫各個(gè)組件的頁面結(jié)構(gòu),實(shí)現(xiàn)“ToDoList”案例靜態(tài)頁 面的渲染,具體步驟如下。
①在App組件中以局部注冊的方式引入ToDoHeader、ToDoMain、ToDoFooter組 件
?②在ToDoHeader組件中編寫輸入?yún)^(qū)域的頁面結(jié)構(gòu)
③ 在ToDoMain組件中編寫列表區(qū)域的頁面結(jié)構(gòu)
④ 在ToDoFooter組件中編寫切換狀態(tài)區(qū)域的頁面結(jié)構(gòu)
三.實(shí)現(xiàn)初始任務(wù)列表的渲染
App 組件為根組件,數(shù)據(jù)在App組件中,現(xiàn)在需要將App根組件中的初始數(shù)據(jù)傳遞 到列表區(qū)域,ToDoMain組件中。即通過props(自定義屬性)從父組件(App組件)向 子組件(ToDoMain組件)中傳遞數(shù)據(jù)。實(shí)現(xiàn)初始任務(wù)列表具體步驟如下。
① 在ToDoMain組件中定義可以從父組件中接收的數(shù)據(jù)
② 在App組件中定義頁面的初始數(shù)據(jù)
③ 通過自定義屬性進(jìn)行傳遞數(shù)據(jù)
④ 修改ToDoMain組件中的代碼,將接收到的list數(shù)據(jù)進(jìn)行展示。
四.新增任務(wù)
“ToDoList”案例中在文本框中輸入內(nèi)容,按下回車后添加任務(wù)到任務(wù)列表,將用戶 輸入的任務(wù)名稱通過自定義事件從ToDoHeader組件傳遞到App組件,具體步驟如下代碼省略。、
① 修改ToDoHeader組件中的代碼,添加頁面的初始數(shù)據(jù)
② 獲取input輸入框的值,修改ToDoHeader組件中的代碼
③ 修改ToDoHeader組件中的代碼,為input輸入框綁定回車事件,事件處理函數(shù) 名稱為enterName
④ 修改ToDoHeader組件中的代碼,通過調(diào)用defineEmits()方法來聲明自定義事 件
⑤ 在ToDoHeader組件中添加enterName()方法,通過調(diào)用emit()方法觸發(fā)自定義事 件
⑥ 在App組件中監(jiān)聽addTodo自定義事件,當(dāng)enterName事件觸發(fā)時(shí),調(diào)用 addToDo()方法
⑦ 添加addToDo方法,實(shí)現(xiàn)數(shù)據(jù)的處理
五.刪除任務(wù)
當(dāng)鼠標(biāo)指針滑到任務(wù)列表中每一項(xiàng)時(shí),在右側(cè)會(huì)出現(xiàn)“×”圖標(biāo),單擊該圖標(biāo)即可 進(jìn)行刪除當(dāng)條任務(wù)操作。首先在ToDoMain組件中聲明并觸發(fā)自定義事件,傳遞參數(shù) 6 id,接著在App組件中監(jiān)聽自定義事件,當(dāng)自定義事件被觸發(fā)時(shí),執(zhí)行對應(yīng)的方法,進(jìn) 行刪除操作,刪除任務(wù)的具體實(shí)現(xiàn)步驟如下。
① 在ToDoMain組件中,聲明自定義事件delTodo,用于表示刪除任務(wù)
② 在ToDoMain組件中定義delToDo()方法,觸發(fā)自定義事件
③ 修改刪除按鈕的代碼,添加點(diǎn)擊事件,傳入需要?jiǎng)h除的id
④ 在App組件中監(jiān)聽
⑤ 在App組件中添加delToDo方法,進(jìn)行列表中對應(yīng)任務(wù)的刪除操作
六.展示未完成條數(shù)
在任務(wù)狀態(tài)區(qū)域的左側(cè)會(huì)顯示未完成任務(wù)的條數(shù),接下來計(jì)算未完成任務(wù)的條數(shù)并 將其在頁面中渲染出來,具體步驟如下代碼省略。
① 在App組件中定義計(jì)算屬性,計(jì)算未完成的任務(wù)條數(shù)
?② 將自定義屬性傳給ToDoFooter組件
③ 在ToDoFooter組件中接收lastLength
④ 在ToDoFooter組件中將條數(shù)展示出來
七.切換狀態(tài)-篩選數(shù)據(jù)
單擊切換狀態(tài)區(qū)域時(shí),默認(rèn)狀態(tài)為all,即顯示全部任務(wù),當(dāng)狀態(tài)切換為active時(shí), 顯示未完成的任務(wù),當(dāng)狀態(tài)切換為completed時(shí),顯示已完成的任務(wù),實(shí)現(xiàn)切換數(shù)據(jù)篩選 狀態(tài)具體步驟如下代碼省略。
① 首先在App組件中定義頁面的使用一個(gè)任務(wù)狀態(tài)狀態(tài)屬性status
② 在App組件中通過不同的status展示不同的任務(wù),實(shí)現(xiàn)任務(wù)數(shù)據(jù)的切換
③ 修改App組件,將showList傳遞給ToDoMain組件
④ 設(shè)置自定義事件名稱
⑤ 在ToDoFooter組件中定義props屬性,表示從父組件中接收該數(shù)據(jù)
⑥ 在App組件中定義props,即從App組件中傳遞status到ToDoFooter組件中
⑦ 在ToDoFooter組件中單擊鏈接按鈕時(shí)更改狀態(tài)
⑧ 在App組件中監(jiān)聽updateStatus自定義事件,通過自定義事件將status屬性的值 從ToDoFooter組件傳遞到App組件中,具體代碼如下
⑨ 定義updateStatus()方法,用來更新狀態(tài),具體代碼如下。
八.待辦事項(xiàng)(全)代碼
ToDoFooter.vue代碼:
<template>
<div class="footer">
<span class="todo-count">共<strong>{{ lastLength }}</strong>條未完成任務(wù) </span>
<ul class="filters">
<ul class="filters">
<li>
<a @click.prevent="emit('updateStatus', 'all')" :class="{ selected: status === 'all' }"
href="#/">All</a>
</li>
<li>
<a @click.prevent="emit('updateStatus', 'active')" :class="{ selected: status === 'active' }"
href="#/active">Active</a>
</li>
<li>
<a @click.prevent="emit('updateStatus', 'completed')" :class="{ selected: status === 'completed' }"
href="#/completed">Completed</a>
</li>
</ul>
</ul>
</div>
</template>
<script setup>
const props = defineProps(['lastLength', 'status'])
const emit = defineEmits(['updateStatus'])
</script>
<style>
.footer {
padding: 10px 15px;
height: 20px;
text-align: center;
font-size: 15px;
border-top: 1px solid #e6e6e6;
}
.footer:before {
content: "";
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 50px;
overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6,
0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6,
0 17px 2px -6px rgba(0, 0, 0, 0.2);
}
.todo-count {
float: left;
text-align: left;
}
.todo-count strong {
font-weight: 300;
}
.filters {
float: right;
margin: 0;
padding: 0;
list-style: none;
}
.filters li {
display: inline;
}
.filters li a {
color: inherit;
margin: 3px;
padding: 3px 7px;
text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
border-color: #767676;
}
.filters li a:hover {
border-color: #db7676;
}
.selected {
border-color: #db7676;
}
</style>
ToDoHeader.vue代碼:?
<template>
<div>
<div class="header">
<p class="title">待辦事項(xiàng)</p>
<input class="new-todo" type="text" placeholder="請?zhí)顚懭蝿?wù)" v-model.trim="name" @keyup.enter="enterName" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const name = ref('')
const enterName = () => {
emit('addTodo', name.value)
name.value = ''
}
const emit = defineEmits(['addTodo'])
</script>
<style>
.title{
border-bottom:1px solid grey;
text-align:center;
font-size:36px;
color:brown;
}
.header{
border:1px solid grey;
}
.new-todo{
position: relative;
top:-20px;
left: 50px;
border: none;
font-size: 20px;
}
</style>
?ToDoMain.vue代碼:
<template>
<div class="main">
<ul class="todo-list">
<li v-for="item in list" :key="item.id" :class="{ completed: item.done }">
<div class="view">
<input class="toggle" type="radio" v-model="item.done" />
<label class="zi">{{ item.name }}</label>
<button class="destroy" @click="delTodo(item.id)"></button>
</div>
</li>
</ul>
</div>
</template>
<script setup>
const props = defineProps({
list: {
type: Array,
required: true
},
})
const emit = defineEmits(['delTodo'])
const delTodo = id => {
id && emit('delToDo', id) // 觸發(fā)事件
}
</script>
<style>
.toggle{
width: 30px;
height: 30px;
}
.view{
margin-left: -40px;
}
.zi{
font-size: 18px;
padding-left: 20px;
}
.destroy{
border: none;
margin-left: 10px;
}
</style>
App.vue代碼:
<template>
<ToDoHeader @addTodo="addTodo" />
<ToDoMain :list="showList" @delToDo="delToDo" />
<ToDoFooter :lastLength="lastLength" :status="status" @updateStatus="updateStatus" />
</template>
<script setup>
import ToDoHeader from './components/ToDoHeader.vue'
import ToDoMain from './components/ToDoMain.vue'
import ToDoFooter from './components/ToDoFooter.vue'
import { ref, computed } from 'vue'
const status = ref('all')
const list = ref([
{ id: 1, name: '晨練', done: false, },
{ id: 2, name: '練書法', done: true, },
])
const addTodo = name => {
list.value.push({ name, done: false, id: ~~(Math.random() * 1000) })
}
const delToDo = id => {
list.value = list.value.filter(item => item.id !== id)
}
// 計(jì)算剩下沒有完成任務(wù)的條數(shù)
const lastLength = computed(() => {
return list.value.filter(item => !item.done).length
})
const showList = computed(() => {
if (status.value === 'all') {
return list.value;
}
if (status.value === 'active') {
return list.value.filter(item => !item.done)
}
if (status.value === 'completed') {
return list.value.filter(item => item.done)
}
})
const updateStatus = (status1) => {
status.value = status1 // 將子組件的狀態(tài)賦值給父組件
}
</script>
main.js代碼:
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
?最終效果圖如下:
?功能展示:文章來源:http://www.zghlxwxcb.cn/news/detail-849122.html
今天就分享到此,感謝預(yù)覽~?文章來源地址http://www.zghlxwxcb.cn/news/detail-849122.html
到了這里,關(guān)于用vue.js寫案例——ToDoList待辦事項(xiàng) (步驟和全碼解析)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!