Vue 系列二 之 猛龍行動之絕密代碼

Create by jsliang on 2019-1-2 08:46:46
Recently revised in 2019-1-10 08:19:41css

Hello 小夥伴們,若是以爲本文還不錯,記得給個 star , 大家的 star 是我學習折騰的動力!GitHub 地址html


【2019-08-16】Hello 小夥伴們,因爲 jsliang 對文檔庫進行了重構,這篇文章的一些連接可能失效,而 jsliang 沒有精力維護掘金這邊的舊文章,對此深感抱歉。請須要獲取最新文章的小夥伴,點擊上面的 GitHub 地址,去文檔庫查看調整後的文章。前端


關注 Vue 的小夥伴們可能知道前幾天尤神在微博發表了個動態:vue

而後,進行了更詳細瞭解的小夥伴,可能知道這個絕密代碼中寫的,就是 TodoList!git

恰好,本文拋開 Vue-Cli,使用最簡單原始的方式開發一個 TodoList,可是,此 TodoList 非彼 Todolist。github

本文的 TodoList 完成正在進行、完成列表、回收站這三個功能模塊,並實現下面這些功能:web

  • 新增任務
  • 改變狀態
  • 修改任務
  • 刪除任務
  • 成品展現

那麼,想知道這個 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.cssindex.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 數據簡化

返回目錄

在這裏,咱們稍微暫停下,觀察 todoInfosfinishInfosrecycleInfos 這三個數組,發現它們都是差很少的結構。那麼,咱們乾脆將它合併?

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 改變狀態

返回目錄

下面咱們進行 isCheckedstate 的改變,從而讓數據在這三種狀態中變化:

欄目 狀態
未完成 isChecked: falsestate: 0
已完成 isChecked: truestate: 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
  • 使用 HTML5manifest 來開發 離線存儲
  • ……

那麼,後面有機會折騰,咱再相會 Todolist ,打造升級版本的啦~


後記

若是小夥伴須要存放 jsliang.top 這樣的純靜態頁面或者 company.jsliang.top 這樣的具備 Node 後端支持的頁面,推薦購買雲服務器來存放。

若是小夥伴們不知道該怎麼選擇雲服務器,能夠查看 詳細介紹 或者加 jsliang QQ:1741020489 諮詢。

知識共享許可協議

jsliang 的文檔庫 由 梁峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議 進行許可。
基於 github.om/LiangJunron… 上的做品創做。
本許可協議受權以外的使用權限能夠從 creativecommons.org/licenses/by… 處得到。
相關文章
相關標籤/搜索