Create by jsliang on 2019-1-2 08:46:46
Recently revised in 2019-1-10 08:19:41
Hello 小夥伴們,如果覺得本文還不錯,記得給個 star , 你們的 star 是我學習折騰的動力!GitHub 地址
關注 Vue 的小夥伴們可能知道前幾天尤神在微博發表了個動態:
然後,進行了更詳細瞭解的小夥伴,可能知道這個絕密程式碼中寫的,就是 TodoList!
剛好,本文拋開 Vue-Cli,使用最簡單原始的方式開發一個 TodoList,但是,此 TodoList 非彼 Todolist。
本文的 TodoList 完成正在進行、完成列表、回收站這三個功能模組,並實現下面這些功能:
- 新增任務
- 改變狀態
- 修改任務
- 刪除任務
- 成品展示:
-
程式碼地址:功成千骨 – 程式碼地址
-
專案地址:功成千骨 – 線上地址
那麼,想知道這個 TodoList 怎麼實現的小夥伴,一起來看下吧!
一 目錄
不折騰的前端,和鹹魚有什麼區別
目錄 |
---|
一 目錄 |
二 前言 |
三 專案解析 |
四 骨架 – HTML |
五 功能 – JS |
5.1 頁面資料化 |
5.2 資料簡化 |
5.3 新增資料 |
5.4 改變狀態 |
5.5 修改內容 |
5.6 資料回收 |
5.7 徹底刪除 |
六 皮膚 – CSS |
6.1 重置樣式 |
6.2 偷天換日 |
七 總結 |
二 前言
經過系列的折騰,並且參照不同大佬的“新人作”,將五花八門的 TodoList 各種寫法綜合起來,從 0 到 1 不依賴 Vue-Cli 打造一個屬於自己的 TodoList,後期將加以 Node 的框架 Koa 連線 MySQL 提供介面,從而實現面向大眾的 TodoList!
欲練此功,必先自宮,額(⊙o⊙)…不對,必先學習 Vue 系列之 Vue 基礎。
三 專案解析
在我們平時的工作中,我們應該在拿到 PSD 設計稿或者原型設計的時候,我們應該對我們的功能進行劃分,對 HTML、CSS、JS 進行劃分,以便於後期的維護製作,下面我們先看一下我們的 UI:
額(⊙o⊙)…
好吧-_-||
慘不忍睹,我們還是按照這形式,將 HTML 搭建出來,並用 JS 實現功能先吧,後期再填充 CSS 了。
下面是目錄結構:
四 骨架 – HTML
現在,我們先完成 index.html
架構。
然後 index.css
和 index.js
這兩個檔案,可以是空的,因為我們先架好骨架,再進行 JS 的事件以及 CSS 的渲染。
index.html
<
!DOCTYPE html>
<
html lang="en">
<
head>
<
meta charset="UTF-8">
<
meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<
meta http-equiv="X-UA-Compatible" content="ie=edge">
<
link rel="shortcut icon" href="./img/favicon.ico" type="image/x-icon">
<
title>
功成千骨<
/title>
<
!-- css 區 -->
<
link rel="stylesheet" href="./css/reset.css">
<
link rel="stylesheet" href="./css/index.css">
<
style>
.content-list {
display: flex;
} <
/style>
<
/head>
<
body>
<
!-- html 區 -->
<
div class="main-container" id="app">
<
!-- 頭部標題 -->
<
div class="header">
<
h3>
功成千骨<
/h3>
<
/div>
<
!-- 內容區 -->
<
div class="content">
<
!-- 輸入區 -->
<
div class="content-input-todo">
<
input type="text" placeholder="第 n 個敵人" "v-model="todo">
<
button>
進擊<
/button>
<
/div>
<
!-- 列表區 -->
<
div class="content-list">
<
!-- 未完成 -->
<
div class="content-list-todo">
<
h4>
千軍萬馬取敵首<
/h4>
<
p>
(待完成)<
/p>
<
ul>
<
li>
<
input type="checkbox">
<
span class="todo-title">
敵軍 1<
/span>
<
span class="icon-recycle">
×<
/span>
<
/li>
<
li>
<
input type="checkbox">
<
span class="todo-title">
敵軍 2<
/span>
<
span class="icon-recycle">
>
×<
/span>
<
/li>
<
li>
<
input type="checkbox">
<
span class="todo-title">
敵軍 3<
/span>
<
span class="icon-recycle">
×<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 已完成 -->
<
div class="content-list-finish">
<
h4>
敵羞吾去脫他衣<
/h4>
<
p>
(已完成)<
/p>
<
ul>
<
li>
<
input type="checkbox">
<
span class="todo-title">
亡軍 1<
/span>
<
span class="icon-recycle">
×<
/span>
<
/li>
<
li>
<
input type="checkbox">
<
span class="todo-title">
亡軍 2<
/span>
<
span class="icon-recycle">
×<
/span>
<
/li>
<
li>
<
input type="checkbox">
<
span class="todo-title">
亡軍 3<
/span>
<
span class="icon-recycle">
×<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 回收站 -->
<
div class="content-list-recycle">
<
h4>
潰不成軍鳥獸散<
/h4>
<
p>
(回收站)<
/p>
<
ul>
<
li>
<
span class="content-list-recycle-back">
返回<
/span>
<
span class="todo-title">
逃軍 1<
/span>
<
span class="icon-delete">
×<
/span>
<
/li>
<
li>
<
span class="content-list-recycle-back">
返回<
/span>
<
span class="todo-title">
逃軍 2<
/span>
<
span class="icon-delete">
×<
/span>
<
/li>
<
li>
<
span class="content-list-recycle-back">
返回<
/span>
<
span class="todo-title">
逃軍 3<
/span>
<
span class="icon-delete">
×<
/span>
<
/li>
<
/ul>
<
/div>
<
/div>
<
!-- -->
<
/div>
<
!-- 底部資訊 -->
<
div class="footer">
<
p>
不折騰的前端<
/p>
<
p>
和鹹魚有什麼區別<
/p>
<
p>
@2019 <
a href="" target="_blank">
jsliang 文件庫<
/a>
<
/p>
<
/div>
<
/div>
<
!-- js 區 -->
<
script src="https://cdn.bootcss.com/vue/2.5.21/vue.js">
<
/script>
<
script src="./js/index.js">
<
/script>
<
/body>
<
/html>
複製程式碼
此時頁面內容如下所示:
五 功能 – JS
搭建好網頁的骨架,我們先讓它跑起來吧。
你可以上面的 HTML 步驟想象成造了一個骷髏人,然後現在你要施法,要讓骷髏人跑起來了。
奔跑吧,骷髏人~
5.1 頁面資料化
現在,我們進行頁面的資料化,我們需要考慮有哪幾塊是需要變成資料的:輸入的內容、todo 項、完成項、未完成項。
那麼,我們先進行簡單抽取:
index.html 程式碼片段
<
!-- 內容區 -->
<
div class="content">
<
!-- 輸入區 -->
<
div class="content-input-todo">
<
input type="text" placeholder="第 n 個敵人" v-model="todo">
<
button>
進擊<
/button>
<
/div>
<
!-- 列表區 -->
<
div class="content-list">
<
!-- 未完成 -->
<
div class="content-list-todo">
<
h4>
千軍萬馬取敵首<
/h4>
<
p>
(待完成)<
/p>
<
ul>
<
li v-for="todoItem in todoInfos" :key="todoItem.id">
<
input type="checkbox" v-model="todoItem.isChecked">
<
span class="todo-title" v-text="todoItem.todoTitle">
<
/span>
<
span class="icon-recycle">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 已完成 -->
<
div class="content-list-finish">
<
h4>
敵羞吾去脫他衣<
/h4>
<
p>
(已完成)<
/p>
<
ul>
<
li v-for="finishItem in finishInfos" :key="finishItem.id">
<
input type="checkbox" v-model="finishItem.isChecked">
<
span class="todo-title" v-text="finishItem.todoTitle">
<
/span>
<
span class="icon-recycle">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 回收站 -->
<
div class="content-list-recycle">
<
h4>
潰不成軍鳥獸散<
/h4>
<
p>
(回收站)<
/p>
<
ul>
<
li v-for="recycleItem in recycleInfos" :key="recycleItem.id">
<
span class="content-list-recycle-back">
返回<
/span>
<
span class="todo-title" v-text="recycleItem.todoTitle">
<
/span>
<
span class="icon-delete">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
/div>
<
/div>
複製程式碼
在這裡,我們將頁面資料化了,現在看下我們的 index.js
內容:
index.js
var app = new Vue({
el: "#app", data: {
id: 1, todo: "", todoInfos: [ {
id: 7, isChecked: false, todoTitle: "敵軍 1",
}, {
id: 8, isChecked: false, todoTitle: "敵軍 2",
}, {
id: 9, isChecked: false, todoTitle: "敵軍 3",
}, ], finishInfos: [ {
id: 1, isChecked: true, todoTitle: "亡軍 1",
}, {
id: 2, isChecked: true, todoTitle: "亡軍 2",
}, {
id: 3, isChecked: true, todoTitle: "亡軍 3",
}, ], recycleInfos: [ {
id: 4, isChecked: false, todoTitle: "逃軍 1",
}, {
id: 5, isChecked: false, todoTitle: "逃軍 2",
}, {
id: 6, isChecked: false, todoTitle: "逃軍 3",
}, ]
}
})複製程式碼
這樣,我們就通過 v-for
完成了資料的渲染,同時頁面和之前的一樣:
5.2 資料簡化
在這裡,我們稍微暫停下,觀察 todoInfos
、finishInfos
、recycleInfos
這三個陣列,發現它們都是差不多的結構。那麼,我們乾脆將它合併?
index.js
var app = new Vue({
el: "#app", data: {
id: 1, todo: "", todoInfos: [ {
id: 7, // id 唯一且自增 isChecked: false, // 未完成和放棄為 false,完成為 true isEdit: false, // 是否在編輯 todoTitle: "敵軍 1", state: 0, // 0 - 未完成,1 - 完成,2 - 放棄完成
}, {
id: 8, // id 唯一且自增 isChecked: false, // 未完成和放棄為 false,完成為 true isEdit: false, // 是否在編輯 todoTitle: "敵軍 2", // todo 標題 state: 1, // 0 - 未完成,1 - 完成,2 - 放棄完成
}, {
id: 9, // id 唯一且自增 isChecked: false, // 未完成和放棄為 false,完成為 true isEdit: false, // 是否在編輯 todoTitle: "敵軍 3", // todo 標題 state: 2, // 0 - 未完成,1 - 完成,2 - 放棄完成
}, ]
}
})複製程式碼
這樣一來,我們就可以修改 HTML,讓它通過 state
來區分這三塊的資料:
index.html 程式碼片段
<
!-- 內容區 -->
<
div class="content">
<
!-- 輸入區 -->
<
div class="content-input-todo">
<
input type="text" placeholder="第 n 個敵人" v-model="todo">
<
button>
進擊<
/button>
<
/div>
<
!-- 列表區 -->
<
div class="content-list">
<
!-- 未完成 -->
<
div class="content-list-todo">
<
h4>
千軍萬馬取敵首<
/h4>
<
p>
(待完成)<
/p>
<
ul>
<
li v-for="todoItem in todoInfos" :key="todoItem.id" v-if="todoItem.state == 0">
<
input type="checkbox" v-model="todoItem.isChecked">
<
span class="todo-title" v-if="!todoItem.isEdit" v-text="todoItem.todoTitle">
<
/span>
<
span class="icon-recycle">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 已完成 -->
<
div class="content-list-finish">
<
h4>
敵羞吾去脫他衣<
/h4>
<
p>
(已完成)<
/p>
<
ul>
<
li v-for="finishItem in todoInfos" :key="finishItem.id" v-if="finishItem.state == 1">
<
input type="checkbox" v-model="finishItem.isChecked">
<
span class="todo-title" v-if="!finishItem.isEdit" v-text="finishItem.todoTitle">
<
/span>
<
span class="icon-recycle">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 回收站 -->
<
div class="content-list-recycle">
<
h4>
潰不成軍鳥獸散<
/h4>
<
p>
(回收站)<
/p>
<
ul>
<
li v-for="recycleItem in todoInfos" :key="recycleItem.id" v-if="recycleItem.state == 2">
<
span class="content-list-recycle-back">
返回<
/span>
<
span class="todo-title" v-if="!recycleItem.isEdit" v-text="recycleItem.todoTitle">
<
/span>
<
span class="icon-delete">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
/div>
<
/div>
複製程式碼
此時,我們的頁面還是如修改之前一般,但是已經實現了資料化。
下面我們開始寫增刪改資料的功能方法。
5.3 新增資料
首先,我們往 HTML 中新增點選事件,當然,如果每次都要點選按鈕,就太麻煩了,乾脆我們再加個鍵盤迴車事件:
index.html 程式碼片段
<
!-- 輸入區 -->
<
div class="content-input-todo">
<
input type="text" placeholder="第 n 個敵人" v-model="todo" @keyup.enter="addTodoItem">
<
button @click="addTodoItem">
進擊<
/button>
<
/div>
複製程式碼
然後,我們往 JS 中新增點選方法:
index.js
var app = new Vue({
el: "#app", data: {
id: 1, todo: "", todoInfos: [ // 已不需要,註釋掉 // {
// id: 7, // id 唯一且自增 // isChecked: false, // 未完成和放棄為 false,完成為 true // isEdit: false, // 是否在編輯 // todoTitle: "敵軍 1", // state: 0, // 0 - 未完成,1 - 完成,2 - 放棄完成 //
}, ]
}, methods: {
addTodoItem() {
// 每次點選,往陣列中新增一組資料 this.todoInfos.push({
id: this.id, // id 唯一且自增 isChecked: false, // 未完成和放棄為 false,完成為 true isEdit: false, // 是否在編輯 todoTitle: this.todo, // todo 標題 state: 0, // 0 - 未完成,1 - 完成,2 - 放棄完成
}) // id 自增 this.id++;
// 清空輸入框 this.todo = "";
},
}
})複製程式碼
最後,我們檢視下新增功能是否實現:
5.4 改變狀態
下面我們進行 isChecked
與 state
的改變,從而讓資料在這三種狀態中變化:
欄目 | 狀態 |
---|---|
未完成 | isChecked: false 、state: 0 |
已完成 | isChecked: true 、state: 1 |
回收站 | state: 2 |
在本章節,我們實現 未完成 ->
已完成 的轉變,這裡只需要修改下 HTML 程式碼即可:
index.html 程式碼片段
<
!-- 未完成 -->
<
div class="content-list-todo">
<
h4>
千軍萬馬取敵首<
/h4>
<
p>
(待完成)<
/p>
<
ul>
<
li v-for="todoItem in todoInfos" :key="todoItem.id" v-if="todoItem.state == 0">
<
input type="checkbox" v-model="todoItem.isChecked" @change="todoItem.state = 1">
<
span class="todo-title" v-if="!todoItem.isEdit" v-text="todoItem.todoTitle">
<
/span>
<
span class="icon-recycle">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 已完成 -->
<
div class="content-list-finish">
<
h4>
敵羞吾去脫他衣<
/h4>
<
p>
(已完成)<
/p>
<
ul>
<
li v-for="finishItem in todoInfos" :key="finishItem.id" v-if="finishItem.state == 1">
<
input type="checkbox" v-model="finishItem.isChecked" @change="finishItem.state = 0">
<
span class="todo-title" v-if="!finishItem.isEdit" v-text="finishItem.todoTitle">
<
/span>
<
span class="icon-recycle">
x<
/span>
<
/li>
<
/ul>
<
/div>
複製程式碼
我們可以檢視下結果:
OK,成功完成 待完成 ->
已完成 的轉變。
5.5 修改內容
現在,我們實現點選 todoTitle
,變成修改模式,修改完後點選其他地方,或者按下回車按鈕,從而實現資料的修改:
index.html 程式碼片段
<
!-- 列表區 -->
<
div class="content-list">
<
!-- 未完成 -->
<
div class="content-list-todo">
<
h4>
千軍萬馬取敵首<
/h4>
<
p>
(待完成)<
/p>
<
ul>
<
li v-for="todoItem in todoInfos" :key="todoItem.id" v-if="todoItem.state == 0">
<
input type="checkbox" v-model="todoItem.isChecked" @change="todoItem.state = 1">
<
span class="todo-title" v-text="todoItem.todoTitle" v-if="!todoItem.isEdit" @click="todoItem.isEdit = true">
<
/span>
<
input v-if="todoItem.isEdit" @blur="todoItem.isEdit = false" @keyup.enter="todoItem.isEdit = false" type="text" v-model="todoItem.todoTitle">
<
span class="icon-recycle">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 已完成 -->
<
div class="content-list-finish">
<
h4>
敵羞吾去脫他衣<
/h4>
<
p>
(已完成)<
/p>
<
ul>
<
li v-for="finishItem in todoInfos" :key="finishItem.id" v-if="finishItem.state == 1">
<
input type="checkbox" v-model="finishItem.isChecked" @change="finishItem.state = 0">
<
span class="todo-title" v-text="finishItem.todoTitle" v-if="!finishItem.isEdit" @click="finishItem.isEdit = true">
<
/span>
<
input v-if="finishItem.isEdit" @blur="finishItem.isEdit = false" @keyup.enter="finishItem.isEdit = false" v-model="finishItem.todoTitle" type="text">
<
span class="icon-recycle">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 回收站 -->
<
div class="content-list-recycle">
<
h4>
潰不成軍鳥獸散<
/h4>
<
p>
(回收站)<
/p>
<
ul>
<
li v-for="recycleItem in todoInfos" :key="recycleItem.id" v-if="recycleItem.state == 2">
<
span class="content-list-recycle-back">
返回<
/span>
<
span class="todo-title" v-text="recycleItem.todoTitle" v-if="!recycleItem.isEdit" @click="recycleItem.isEdit = true">
<
/span>
<
input v-if="recycleItem.isEdit" type="text" @blur="recycleItem.isEdit = false" @keyup.enter="recycleItem.isEdit = false" v-model="recycleItem.todoTitle">
<
span class="icon-delete">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
/div>
複製程式碼
在這裡,我們僅需要在點選 span
標籤的時候,改變下 isEdit
的狀態,即進入編輯模式,同時,在 input
標籤失去焦點或者在輸入完成後點選回車按鈕,就可以實現資料的修改。
最後,我們檢視下實現情況:
5.6 資料回收
同理,如果我們要將資料扔進回收站中去,那就需要將 state
改為 2 即可。
如果資料是從回收站返回待完成,我們只需要將 state
改為 0 即可。
index.html 程式碼片段
<
!-- 未完成 -->
<
div class="content-list-todo">
<
h4>
千軍萬馬取敵首<
/h4>
<
p>
(待完成)<
/p>
<
ul>
<
li v-for="todoItem in todoInfos" :key="todoItem.id" v-if="todoItem.state == 0">
<
input type="checkbox" v-model="todoItem.isChecked" @change="todoItem.state = 1">
<
span class="todo-title" v-text="todoItem.todoTitle" v-if="!todoItem.isEdit" @click="todoItem.isEdit = true">
<
/span>
<
input v-if="todoItem.isEdit" @blur="todoItem.isEdit = false" @keyup.enter="todoItem.isEdit = false" type="text" v-model="todoItem.todoTitle">
<
span class="icon-recycle" @click="todoItem.state = 2">
x<
/span>
<
/li>
<
/ul>
<
/div>
<
!-- 已完成 -->
<
div class="content-list-finish">
<
h4>
敵羞吾去脫他衣<
/h4>
<
p>
(已完成)<
/p>
<
ul>
<
li v-for="finishItem in todoInfos" :key="finishItem.id" v-if="finishItem.state == 1">
<
input type="checkbox" v-model="finishItem.isChecked" @change="finishItem.state = 0">
<
span class="todo-title" v-text="finishItem.todoTitle" v-if="!finishItem.isEdit" @click="finishItem.isEdit = true">
<
/span>
<
input v-if="finishItem.isEdit" @blur="finishItem.isEdit = false" @keyup.enter="finishItem.isEdit = false" v-model="finishItem.todoTitle" type="text">
<
span class="icon-recycle" @click="finishItem.state = 2">
x<
/span>
<
/li>
<
/ul>
<
/div>
複製程式碼
實現結果:
5.7 徹底刪除
首先,我們給 HTML 新增點選事件,將引數傳遞給方法體中
index.html 程式碼片段
<
!-- 回收站 -->
<
div class="content-list-recycle">
<
h4>
潰不成軍鳥獸散<
/h4>
<
p>
(回收站)<
/p>
<
ul>
<
li v-for="recycleItem in todoInfos" :key="recycleItem.id" v-if="recycleItem.state == 2">
<
span class="content-list-recycle-back" @click="recycleItem.state = 0;
recycleItem.isChecked = false">
返回<
/span>
<
span class="todo-title" v-text="recycleItem.todoTitle" v-if="!recycleItem.isEdit" @click="recycleItem.isEdit = true">
<
/span>
<
input v-if="recycleItem.isEdit" type="text" @blur="recycleItem.isEdit = false" @keyup.enter="recycleItem.isEdit = false" v-model="recycleItem.todoTitle">
<
span class="icon-delete" @click="deleteInfo(recycleItem)">
x<
/span>
<
/li>
<
/ul>
<
/div>
複製程式碼
然後,我們通過編寫 deleteInfo
來刪除 todoInfos
中的資料:
index.js 程式碼片段
methods: {
addTodoItem() {
// 每次點選,往陣列中新增一組資料 this.todoInfos.push({
id: this.id, // id 唯一且自增 isChecked: false, // 未完成和放棄為 false,完成為 true isEdit: false, // 是否在編輯 todoTitle: this.todo, // todo 標題 state: 0, // 0 - 未完成,1 - 完成,2 - 放棄完成
}) // id 自增 this.id++;
// 清空輸入框 this.todo = "";
}, /** * 這裡使用了三種寫法 * 1. map + splice * 2. splice + findIndex * 3. filter */ // // 1. map + splice 寫法 // deleteInfo(recycleItem) {
// this.todoInfos.map((item, index) =>
{
// if(item.id == recycleItem.id) {
// this.todoInfos.splice(index, 1);
//
} //
}) //
}, // // 2. splice + findIndex 寫法 // deleteInfo(recycleItem) {
// this.todoInfos.splice( this.todoInfos.findIndex( v =>
v.id === recycleItem.id), 1);
//
}, // 3. filter 寫法 deleteInfo(recycleItem) {
this.todoInfos = this.todoInfos.filter( (x) =>
{
return x.id != recycleItem.id;
})
}
}複製程式碼
興致突來,想起 茴字的四種寫法,於是,這裡也奉上刪除資料的三種寫法,這裡就不估算效能損耗了,哪種喜歡就用哪種吧。
此時完成功能如下所示:
到此,我們完成了所有的功能實現~
六 皮膚 – CSS
那麼,我們回來我們的大難題,就是給這個頁面增加皮膚,讓這個頁面漂亮點。
6.1 重置樣式
enm……因為不同瀏覽器對於一些 DOM 元素的渲染不同,所以我們先重置下瀏覽器樣式吧:
reset.css
/* * reset 的目的不是讓預設樣式在所有瀏覽器下一致,而是減少預設樣式有可能帶來的問題。 * The purpose of reset is not to allow default styles to be consistent across all browsers, but to reduce the potential problems of default styles. * create by jsliang*//** 清除內外邊距 - clearance of inner and outer margins **/body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* 結構元素 - structural elements */dl, dt, dd, ul, ol, li, /* 列表元素 - list elements */pre, /* 文字格式元素 - text formatting elements */form, fieldset, legend, button, input, textarea, /* 表單元素 - from elements */th, td /* 表格元素 - table elements */ {
margin: 0;
padding: 0;
}/** 設定預設字型 - setting the default font **/body, button, input, select, textarea {
font: 18px/1.5 '黑體', Helvetica, sans-serif;
}h1, h2, h3, h4, h5, h6, button, input, select, textarea {
font-size: 100%;
}/** 重置列表元素 - reset the list element **/ul, ol {
list-style: none;
}/** 重置文字格式元素 - reset the text format element **/a, a:hover {
text-decoration: none;
}/** 重置表單元素 - reset the form element **/button {
cursor: pointer;
}input {
font-size: 18px;
outline: none;
}/** 重置表格元素 - reset the table element **/table {
border-collapse: collapse;
border-spacing: 0;
}/** 圖片自適應 - image responsize **/img {
border: 0;
display: inline-block;
width: 100%;
max-width: 100%;
height: auto;
vertical-align: middle;
}/* * 預設box-sizing是content-box,該屬性導致padding會撐大div,使用border-box可以解決該問題 * set border-box for box-sizing when you use div, it solve the problem when you add padding and don't want to make the div width bigger*/div, input {
box-sizing: border-box;
}/** 清除浮動 - clear float **/.jsliang-clear:after, .clear:after {
content: '\20';
display: block;
height: 0;
clear: both;
}.jsliang-clear, .clear {
*zoom: 1;
}/** 設定input的placeholder - set input placeholder **/input::-webkit-input-placeholder {
color: #919191;
font-size: 16px
} /* Webkit browsers */input::-moz-placeholder {
color: #919191;
font-size: 16px
} /* Mozilla Firefox */input::-ms-input-placeholder {
color: #919191;
font-size: 16px
} /* Internet Explorer */複製程式碼
6.2 偷天換日
然後,我們就面臨一個問題,要怎麼美化呢?
腦闊疼,我們還是去網上盜個皮膚下來吧:
很好,然後我們對著修改下 CSS:
index.css
/* 共用 */html, body {
height: 100%;
}body {
background: url("../img/background.jpg") no-repeat center;
background-size: 100% 100%;
}/* 多項選項框 */input[type="checkbox"] {
width: 25px;
height: 25px;
background-color: #fff;
-webkit-appearance: none;
border: 1px solid deepskyblue;
border-radius: 2px;
outline: none;
}input[type="checkbox"]:hover {
cursor: pointer;
}input[type="checkbox"]:checked {
background: url("../img/icon-checked.png") no-repeat center;
background-size: 100%;
}/* 共用標題樣式 */.todo-title {
margin-top: 10px;
word-break: normal;
width: 75%;
display: block;
white-space: pre-wrap;
word-wrap: break-word ;
overflow: hidden ;
}/* 圖示樣式 */.icon-recycle {
width: 25px;
height: 25px;
background: url("../img/icon-recycle.png") no-repeat center;
background-size: 100%;
}.icon-delete {
width: 25px;
height: 25px;
background: url("../img/icon-delete.png") no-repeat center;
background-size: 100%;
}.content-list-recycle-back {
display: block;
width: 20px;
height: 20px;
background: url("../img/icon-back.png") no-repeat center;
background-size: 100%;
}/* 頁面主體 */.main-container {
width: 1200px;
height: 100%;
margin: 0 auto;
position: relative;
}/* 頭部標題 */.header {
width: 100%;
height: 150px;
background: url("../img/title.png") no-repeat center;
}/* 內容區 */.content {
text-align: center;
}/* 內容區 - 輸入區 */.content-input-todo {
height: 40px;
}.content-input-todo input {
height: 40px;
padding-left: 20px;
padding-right: 20px;
border: none;
border-radius: 20px;
}.content-input-todo button {
width: 100px;
padding: 5px;
border-radius: 20px;
background: #36AF9E;
color: #fff;
outline: none;
}/* 內容區 - 列表區 */.content-list {
display: flex;
margin-top: 30px;
}.content-list div {
width: 380px;
margin-right: 20px;
border: 1px solid #ccc;
padding: 30px;
border: 15px solid transparent;
border-image: url("../img/border.png") 60 60 stretch;
}.content-list div ul {
text-align: left;
}.content-list div ul li {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #ccc;
}.content-list div ul li:hover {
cursor: pointer;
}.content-list div ul li input[type="checkbox"] {
margin-right: 10px;
}.content-list div ul li input[type="text"] {
outline: none;
border: none;
background: rgba(255, 255, 255, 0);
color: #000;
border-bottom: 1px solid #ccc;
}/* 底部區 */.footer {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
}.footer a {
color: deepskyblue;
}.footer a:hover {
color: deepskyblue;
}複製程式碼
大功告成,看下我們的成品:
七 總結
到此,我們就寫完了這個簡單的小 Demo 咯~
下面將程式碼地址和專案地址貼出來,需要 參考 的小夥伴自行下載或者觀看。
-
程式碼地址:功成千骨 – 程式碼地址
-
專案地址:功成千骨 – 線上地址
當然,還沒完!
我們還可以折騰更多:
- 使用
ElementUI
或者Bootstrap
進行多端適配 - 使用
localStorage
來進行本地版開發 - 使用
Node
來進行資料多端使用 - 使用 視覺化配置,將 DOM 元素的 CSS 抽取成資料,讓使用者可以配置自己的 Todolist
- 使用
HTML5
的manifest
來開發 離線儲存 - ……
那麼,後面有機會折騰,我們再相會 Todolist ,打造升級版本的啦~
後記
如果小夥伴需要存放 jsliang.top 這樣的純靜態頁面或者 company.jsliang.top 這樣的具有 Node 後端支援的頁面,推薦購買雲伺服器來存放。
如果小夥伴們不知道該怎麼選擇雲伺服器,可以檢視 詳細介紹 或者加 jsliang QQ:1741020489
諮詢。
jsliang 的文件庫 由 樑峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議 進行許可。
基於 github.om/LiangJunron… 上的作品創作。
本許可協議授權之外的使用許可權可以從 creativecommons.org/licenses/by… 處獲得。
來源:https://juejin.im/post/5c39d37851882525846930b8#chapter-one