大概有小半年沒更新文章了,一直忙于公司的各種項目開發。期間也踩了不少坑,最近終于算是暫時忙完一個段落,有時間來繼續寫博客了。vue從零開始學系列筆記,之前斷斷續續寫了有三篇筆記,但是內容不是很多,做項目的這半年多時間,也在帶一些新人做開發。之前電腦里存的一些系列筆記,回頭去看,感覺缺少一些實戰的內容。所以還是決定推翻重寫之后再發出來給大家參考。

之前發布的三篇筆記,大概算是讓對vue一點都不了解的童鞋能夠配合vue-cli去快速構建一個vue的項目。從這篇文章開始,就進入實戰階段了。


定個小目標

其實很多時候我們在學習一個新的技術的時候,大多都停留在知識點,小demo的層次,一旦放到項目中,多少還是有些不會應用。所以這次我們就先定一個小目標,做一個任務清單應用,讓自己的時間得到規劃,并以此為基礎,去擴展。當然,整個應用還需要我們自己一步一步去實現。

那就先列一些功能點吧:

  1. 歡迎頁面(根據每日不同時段展示不同的歡迎語和日期)
  2. 記錄頁面(分為進行中、已完成、未完成三個列表,用于展示當前的任務狀況。 進行中的任務可以進行狀態變更)
  3. 添加頁面(添加一些新任務)

先來看看我們要實現什么樣的一個效果吧

歡迎頁

編寫第一個頁面

既然小目標已經確定好了,那我們就開始編寫第一個頁面吧。在src目錄下面創建我們小目標的相關目錄與文件。修改之前的項目文件,這里我們將頁面統一放到views文件夾下,在根據功能來劃分不同??椋ㄖ暗膁emo頁面寫在了pages文件夾下,這里我們用不到之前的小demo了,可以刪掉)。讓我們得小目標在項目初級就有一個比較明顯的層次結構。

├── src
│   ├── assets
│         ├── images   ---- 圖片文件夾
│   ├── components
│   ├── router   ----- 路由文件夾
│        ├── routes ---路由配置文件夾
│        ├── index.js
│   ├── views    ------ 視圖層
│       ├──  todo  ---- 任務???│       │   ├──  add.vue ---- 新建任務
│       │   ├──   list.vue  ----- 任務列表
│       └── index.vue   ---- 歡迎頁

打開index.vue頁面,這個頁面我們把它定位歡迎頁,接著我們編寫以下內容(html和css的知識大家自己學習,這里默認為大家都有html、css的基?。?。

<template>
 <div class="index">
  <img class="index-bg" src="../assets/images/banner.jpg">
  <div class="index-topbox">
   <div class="index-topbox-radius">
    <div class="index-topbox-text">
     <h3>下午好</h3>
     <p>
      <span>May.</span><span>14</span><span>Mon</span><span>2018</span>
     </p>
    </div>
   </div>
  <router-link class="button button-error" :to="{ name: 'todoList' }">Do it</router-link>
  <span class="tip">習慣就是人生的最大指導</span>
  </div>
 </div>
</template>
<scrpt>
 export default {
  data () {
     return {}
    }
 }
</script>
<style>
.index, .index .index-topbox {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
.index>img.index-bg {
    width: 100%;
    height: 100%;
}
.index .index-topbox{
    position: absolute;
    background: rgba(206, 202, 202, 0.2);
}
.index .index-topbox-radius{
    margin: 3rem auto 0;
    width: 5.5rem;
    height: 5.5rem;
    border-radius: 50%;
    border: .08rem solid rgba(255, 255, 255, 0.5);
}
.index .index-topbox .index-topbox-text {
    margin-top: 1.4rem;
    margin-left: 1.4rem;
    width: 2.7rem;
    height: 2.7rem;
}
.index .index-topbox h3 {
    padding: .25rem 0;
    font-family: "宋體";
    font-size: .75rem;
    color: #fff;
    text-align: center;
    letter-spacing: .1rem;
}
.index .index-topbox .button-error {
    display: block;
    margin: .8rem auto 0;
    width: 2.7rem;
    height: .7rem;
    line-height: .7rem;
    border-radius: .7rem;
    box-shadow: 1px -1px #ff1a1a;
    font-size: .34rem;
    color: #fff;
}
.index .index-topbox p {
    padding: .15rem 0;
    border-top: .02rem solid #fff;
    border-bottom: .02rem solid #fff;
    font-size: .24rem;
    text-align: center;
    color: rgba(255, 255, 255, 0.7);
}
.index .index-topbox p span {
    margin-right: .05rem;
}
.index .index-topbox span.tip {
    padding: 0 .25rem;
    margin-top: 1.2rem;
    display: block;
    font-size: .22rem;
    color: rgba(255, 255, 255, 0.8);
    text-align: center;
}
.index .index-topbox p span:last-child {
    margin-left: .1rem;
    color: #fff;
}
</style>

這樣,歡迎頁的大概布局就出來了,接下來我們就該寫功能了,我們希望在下午好的這個地方,根據打開頁面的當前時間去展示不同的問候。在日期上面展示英文的縮寫(別問為啥用英文,因為逼格高)然后在最下面展示一條隨機的名人名言。點擊按鈕的時候,能夠進入任務列表頁面。

ok,在正式編寫功能之前,希望你先對vue的整個生命周期有一個初步了解,因為網上關于生命周期的詳解有不少了,這里就不多做贅述,直接掛鏈接vue生命周期,如果你對vue的生命周期有過了解,那我們接著往下看。

首先我們來寫日期轉換的函數,通過獲取當前時間和我們預設好的數組,獲取日期格式。

data () {
 return {
  date: {
   year: '',
   month: '',
   week: '',
   day: ''
  }
 }
},
methods: {
 setDate () {
  const now = new Date()
    const Month = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Spt', 'Oct', 'Nov', 'Dec' ]
    const Week = [ 'MON', 'TUSE', 'WED', 'THUR', 'FRI', 'SAT', 'SUN' ]
    this.date.month = Month[now.getMonth()] + '.'
  this.date.day = now.getDate()
  this.date.week = Week[now.getDay() - 1]
  this.date.year = now.getFullYear()
 }
}

在vue中,方法一般寫在methods里面,我們將轉換好的日期通過this.data的方式賦值給data,然后就可以通過{{}}雙括號的形式,展示到模板里了。

<div class="index-topbox-text">
 <h3>下午好</h3>
 <p>
  <span>{{ date.week }}</span><span>{{ date.day }}</span><span>{{ date.month }}</span><span>{{ date.year }}</span>
 </p>
</div>

然后,我們希望這個函數在一進入頁面就執行,通過前面生命周期的了解,我們把它放入created方法里。(這里我給setDate包了一層init方法用作初始化)

created () {
 this.init()
},
methods: {
 init () {
  this.setDate()
 }
}

接下來我們通過同樣的方式處理歡迎語和經典語句(記得同樣加到init方法里面,或created方法里)

setWelcomeWord () {
 const now = new Date()
 const hh = now.getHours()
 const time = [ 3, 6, 8, 11, 13, 17, 19, 23 ]
 const text = [ '深夜咯', '早上好', '上午好', '中午好', '下午好', '日暮里', '晚上好', '夜深了' ]
 time.map((item, index, arr) => {
  if (arr[0] <= hh && hh <= arr[arr.length - 1]) {
   if (item <= hh && hh <= arr[index + 1]) {
    this.welcomeWord = text[index]
   }
  } else {
   this.welcomeWord = text[arr.length - 1]
  }
 })
},
setTips () {
 const now = new Date()
 const tips = [
  '習慣就是人生的最大指導',
  '我們堅持一件事情,并不是因為這樣做了會有效果,而是堅信,這樣做是對的',
  '凡不能殺死你的,終使你更加強大',
  '要從容地著手去做一件事,但一旦開始,就要堅持到底',
  '向著某一天終于要達到的那個終極目標邁步還不夠,還要把每一步驟看成目標,使它作為步驟而起作用',
  '一個人只要強烈地堅持不懈地追求,他就能達到目的',
  '要在這個世界上獲得成功,就必須堅持到底:至死都不能放手'
 ]
 this.tips = tips[now.getDay() - 1]
}

在設置提示語的時候,我們使用了map方法去遍歷time數組,說起循環來,JS中的循環方法還是蠻多的,感興趣的童鞋可以去參考小萌寫的JS 循環遍歷方法的對比一文。

這樣下來,歡迎頁的頁面部分我們就完成了,但是如何才能看到我們的頁面呢?調整我們的router路由文件夾

├── src
│   ├── router   ----- 路由文件夾
│        ├── routes  ----- 路由配置文件夾
│             ├── routes.js
│             ├── todo.js
│        ├── index.js

打開routes.js文件,寫入以下內容

import App from '../../App.vue'
const Index = resolve => require.ensure([], () => resolve(require('../../views/index.vue')), 'index')
import ToDo from './todo.js'

export const appRouter = [ // 定義我們的主應用路由
 { path: '', name: 'index', component: Index },
 {
  path: '/todo',   // 路徑
  component: App,  // 頁面使用的模板
  children: [  // 子路由
   ...ToDo
  ]
 }
]

export const routes = [ // 將路由暴露出去
 ...appRouter
]

我們通過定義路由的方式,來配置我們應用的頁面訪問地址,最后我們將配置好的路由暴露出去。這里需要注意的是

import App from '../../App.vue'
// require.ensure 是webpack的特殊語法,用來設置code-split point  最后面的參數'index' 意思是代碼分塊(chunk)
const Index = resolve => require.ensure([], () => resolve(require('../../views/index.vue')), 'index')

這個語法跟我們引入app.vue文件不同,他們有什么區別呢?我們在前面的筆記中說過,Vue的項目其實是單頁面應用,可以避免頁面跳轉過程中的白屏現象,但是由于是單頁面應用,所以所有的文件都會在一進入應用中就全部加載,如果資源很大,首頁響應就會很慢,導致首頁白屏現象。于是我們通過懶加載的模式,讓應用只有進入到對應頁面時,才加載相關資源,達到優化的效果。

這里我們結合Vue的異步組件和webpack的code splitting feature,把路由對應的組件定義成異步組件,這里我們只需要明白這么用就可以實現路由懶加載就好了。

同理,我們將todo.js的路由也編寫好。

const ToDoList = resolve => require.ensure([], () => resolve(require('../../views/todo/list.vue')), 'todoList')

export default [
  { path: '/list', name: 'todoList', meta: { title: '任務列表' }, component: ToDoList }
]

最后我們在router/index.js中配置路由并在main.js中引用:

//index.js
import Vue from 'vue'
import Router from 'vue-router'
import {routes} from './routes/routes.js'

Vue.use(Router)

const RouterConfig = {
 routes
}
export const router = new Router(RouterConfig)

//main.js
import Vue from 'vue'
import App from './App.vue'
import {router} from './router/index.js'  // 引入路由
import './assets/css/global.css'  // 引入全局樣式
import './assets/css/animate.css' // 引入css動畫

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
 el: '#app',
 router: router,
 template: '<App/>',
 components: { App }
})

接著讓我們在todo/list.vue中,加點文字

<!-- 任務列表頁面 -->
<template>
 <div class="">
  任務列表
 </div>
</template>

OK,到這里我們小目標的第一個頁面就完成啦?;毓艘幌掄餛始塹哪諶?,消化一下吧。

  1. vue的生命周期以及數據渲染的方式
  2. map循環函數
  3. 定于路由
  4. 路由懶加載