案例:todolist
- 專案結構
- 專案功能
- 實作效果
- 完整代碼
- 結束語
專案結構
1 參考todomvs,網站:http://todomvc.com/
2 模板倉庫地址:https://github.com/tastejs/todomvc-app-template.git
3 git拉取:git clone https://github.com/tastejs/todomvc-app-template.git

4 拉取下來檔案如圖

.gitgit版本管理器
cssapp.css樣式
jsapp.js書寫效果
.editorconfig編輯器設定
.gitattributesgit的設定
.gitignoregit管理忽略的檔案的配置
.app-readme.md可洗掉
index.htmlhtml主體
.package.json專案描述;使用命令列:npm i 下載專案依賴包
readme.md上傳git展示的檔案
專案功能
1 展開事項串列
2 添加事項
3 編輯事項
4 洗掉事項
5 切換單條事項狀態
6 批量切換事項狀態
7 清除已完成事項
8 同步未完成事項總數
9 顯示/隱藏清除已完成按鈕
10 切換不同事項的顯示
11 資料同步到本地存盤
實作效果

完整代碼
一、HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Template ? TodoMVC</title>
<link rel="stylesheet" href="node_modules/todomvc-common/base.css">
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
</head>
<body>
<section class="todoapp">
<header class="header">
<h1>todos</h1>
<!-- 變化1 -->
<!--
v-model.trim:實時獲取去除前后空格的文本框輸入的值;
@keyup.enter:按下回車時執行add方法
-->
<input class="new-todo" placeholder="What needs to be done?"
autofocus
v-model.trim="newTask"
@keyup.enter="add"
>
</header>
<section class="main">
<input id="toggle-all" class="toggle-all" type="checkbox">
<!-- 變化2 -->
<!--
@click:系結點擊事件,當點擊時執行toggleAll函式;
v-show:當Shown值為true時讓其顯示,反之隱藏
-->
<label for="toggle-all" @click="toggleAll" v-show="Shown">Mark all as complete</label>
<ul class="todo-list">
<!-- 變化3 -->
<!-- 類名:completed改變事項的狀態為已完成;類名:editing讓文本框進入編輯狀態-->
<!--
v-for:遍歷陣列tasks;
:class:當task.completed傳回的值為true時添加類名completed,當isEditing==task.id時添加類名editing
v-if:獲取completed狀態
-->
<li v-for="task in tasks"
:class="{completed:task.completed,editing:isEditing==task.id}"
v-if="show(task.completed)"
>
<div class="view">
<!-- 變化4 -->
<!-- v-model:實時獲取task.completed的值 -->
<input class="toggle" type="checkbox" v-model="task.completed">
<!-- 變化5 -->
<!--
@dblclick:雙擊isEditing=task.id的文本框,也就是讓當前文本框進入編輯狀態;
v-text:更新task.title
-->
<label
@dblclick="isEditing=task.id"
v-text="task.title"
></label>
<!-- 變化6 -->
<!-- @click:點擊洗掉按鈕時判斷是否是當前的事項,是就洗掉 -->
<button class="destroy" @click="remove(task.id)"></button>
</div>
<!-- 變化7 -->
<!--
v-todo-focus:如果isEditing==task.id為true,就讓input自動聚焦;
v-model:更新task.title;
@keyup.enter:當按下回車鍵時讓isEditing=-1;
@blur:當焦點離開文本框時,讓isEditing=-1
-->
<input class="edit"
v-model="task.title"
@keyup.enter="isEditing=-1"
@blur="isEditing=-1"
v-todo-focus="isEditing==task.id"
>
</li>
</ul>
</section>
<!-- 變化8 -->
<!-- v-show:當Shown值為true時讓其顯示,反之隱藏 -->
<footer class="footer" v-show="Shown">
<span class="todo-count"><strong v-text="activeNum"></strong> item left</span>
<ul class="filters">
<li>
<!-- 變化9 -->
<!-- :class:當flag的路由全等于''時,添加類名selected -->
<a :class="{selected:flag===''}" href="#/">All</a>
</li>
<li>
<!-- 變化10 -->
<!-- :class:當flag.completed全等于false時,添加類名selected -->
<a :class="{selected:flag.completed===false}" href="#/active">Active</a>
</li>
<li>
<!-- 變化11 -->
<!-- :class:當flag.completed全等于true時,添加類名selected -->
<a :class="{selected:flag.completed===true}" href="#/completed">Completed</a>
</li>
</ul>
<!-- 變化12 -->
<!--
@click:點擊清除按鈕時執行函式clearAll;
v-if:當有已完成事項時,回傳true讓其顯示
-->
<button class="clear-completed" @click="clearAll" v-if="isShow">Clear completed</button>
</footer>
</section>
<script src="node_modules/todomvc-common/base.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="js/app.js"></script>
</body>
</html>
二、JS
(function (window) {
'use strict';
// 里面的變數都是區域變數,除非系結在window上
// 書寫本地存盤的存取方法
window.storage = {
getStorage(){
// 獲取本地存盤,并轉換成json物件
return JSON.parse(window.localStorage.getItem('todos')||'[]');
},
setStorage(json){
// 把傳入的json物件轉成json字串,存入本地存盤
window.localStorage.setItem('todos',JSON.stringify(json));
}
}
// 創建一個vue實體
window.app = new Vue({
el:".todoapp",
data:{
tasks:window.storage.getStorage(),
newTask:"",
isEditing:-1,
status:true,
count:0,
flag:location.hash=="#/active"?({completed:false}):(location.hash=="#/completed"?({completed:true}):"")
},
directives:{
"todo-focus":function(el,binding){
if(binding.value){
el.focus()
}
}
},
computed:{
activeNum(){
this.count = 0;
this.tasks.forEach((task)=>{
if(!task.completed){
this.count++;
}
})
return this.count;
},
isShow(){
for(var i=0;i<this.tasks.length;i++){
if(this.tasks[i].completed){
return true;
}
}
return false;
},
Shown(){
if(this.tasks.length>0){
return true;
}
}
},
methods:{
show(i){
if(this.flag===""){
return true;
}else if(this.flag.completed===i){
return true;
}
window.storage.setStorage(this.tasks);
},
clearAll(){
this.tasks = this.tasks.filter(task=>!task.completed);
window.storage.setStorage(this.tasks);
},
toggleAll(){
this.tasks.forEach((task)=>{
task.completed = this.status
});
this.status = !this.status;
// 同步到本地存盤中
window.storage.setStorage(this.tasks);
},
remove(id){
this.tasks = this.tasks.filter(task=>{
return task.id!=id
})
// 同步到本地存盤中
window.storage.setStorage(this.tasks);
},
add(){
var task = {
title:this.newTask,
completed:false,
id:Date.now()
}
if(task.title!=''){
this.tasks.push(task);
}
// 輸入完成后,清空文本框
this.newTask = ""
// 同步到本地存盤中
window.storage.setStorage(this.tasks);
}
}
})
// 監控路由的變化
window.onhashchange = function(){
console.log(location.hash);
// 專門在vue實體里面宣告一個變數由于標識當前是在哪個路由
if(location.hash=="#/active"){
window.app.flag = {completed:false}; //active就是要顯示未完成任務,flag最好有意義
return;
}else if(location.hash=="#/completed"){
window.app.flag = {completed:true}; //completed就是要顯示已完成任務,flag最好有意義
return;
}else{
// 如果是其他路由,都顯示全部任務
window.app.flag = "";
return;
}
}
})(window);
結束語
你那么可愛,肯定會點贊,一起加油!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/204882.html
標籤:其他
