vue.js應用開發筆記

看vue.js有幾天了,以前也零零散散的瞅過,不過一直沒有動手去寫過demo,這幾天後臺事比較少,一直在討論各類需求(其實公司對需求仍是比較重視與嚴謹的,一個項目需求討論就差很少一週了,這要擱以前,天哪。。。),因而就琢磨着把vue簡單的過下,以下所講只是我的一些理解,不到的地方還望園友指正,涉及到的東西有vue、vue-router、vuex、axios以及nodejs一些後臺東西,廢話不說了直接上菜吧。javascript

1、vue.jscss

一、項目搭建使用vue-cli腳手架,首先必須安裝vue、vue-cli:cnpm i vue vue-cli -g,全局安裝完成以後咱們即可以使用vue-cli腳手架進行項目結構搭建,具體以下:html

vue init webpack frontend,以下:前端

這裏咱們環境部分選擇「運行環境+編譯環境」,這樣,後面直接可使用webpack進行編譯後部署,十分方便,再繼續:vue

通常每一個團隊都有本身的代碼規範,這時候打開eslint,配置本身團隊的代碼規範就顯得尤其重要,下面說下vscode編輯器下如何配置eslint,在以前項目基礎上咱們配置下eslint,首先是vscode安裝eslint插件:java

而後在用戶設置欄配置具體的eslint規則:node

依次打開vscode的「文件」->「首選項」->「用戶設置」,在右側編輯區輸入咱們定義好的eslint規則:react

{
    "editor.fontSize": 17,
    "editor.tabSize": 2,
    "editor.formatOnSave": false,
    "files.associations": {
        "*.vue": "vue"
    },
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "html",
        "vue",
        {
            "language": "html",
            "autoFix": true
        }
    ],
    "emmet.syntaxProfiles": {
        "vue-html": "html",
        "vue": [
            "css",
            "html",
            "less"
        ]
    },
    "editor.fontFamily": "Source Code Pro, 'Courier New', monospace",
    "files.autoSave": "off",
    "workbench.iconTheme": "vscode-icons"
}

這裏咱們設置字體大小爲17,tab縮進爲2個空格,eslint的校驗適用於js、html、vue,設置vscode圖標爲vscode-icons,其它規則能夠參考下eslint官方說明。webpack

二、項目結構ios

前面經過vue-cli生成的項目結構以下:

主要是src文件夾,咱們對其進行了一些拓展,其中api文件夾用來存放前端各類請求api模塊,components文件夾以下:

用來存放各類頁面組件,其中base爲公共組件,好比一些頁頭、頁尾、分頁組件等等,Home爲主界面,該頁面經過router路由來整合其它組件,Login爲登陸組件。mock文件夾用來進行mock.js配置,這樣前端能夠獨立於後端接口開發,使用虛擬數據不依賴後端從而更加高效。router文件夾用來配置vue-router下的各類前端路由,vuex文件夾主要用來配置vuex狀態管理相關:

其中modules文件夾用來存放各個vuex的module,分模塊配置的話有個好處就是項目比較龐大的時候便於數據查看與管理,mutation.types.js用來存放各類vuex的mutation類型常量,關於vuex後面繼續介紹。

三、關於vue.js一些知識點

1)、組件概念

組件這個比較好解釋,簡單理解就是一個個經過vue本身的方式註冊的頁面(能夠是公有頁面也能夠是單個頁面),組件化開發時經過template包裹的一系列部分功能頁面均可以稱做組件,好比咱們的App.vue:

固然,每一個組件都有屬於本身做用域,組件下的各個數據及相關操做均寫在當前組件下的script標籤中,以下:

能夠看到如上爲App.vue組件的數據結構,這裏經過ES6的export default導出當前vue實例,組件下包含不少東西,好比data(data是一個function,經過return一個數據對象來表示當前組件都有哪些數據實例)、components(組件是能夠被其它組件導入使用的,components就是用來聲明當前組件導入的子組件)、computed(計算屬性,和data相似,本質返回的是一個數據對象)、watch(監聽,主要是監聽數據對象的變化,有變化則執行對應的function)、mounted(鉤子函數,組件初始化時調用)、methods(用得最多,當前組件下的私有方法,可經過this.methodName調用)、events(事件,當前組件下的事件函數),這裏還有不少,具體能夠參考官網。

固然,每一個組件都有屬於本身的style樣式,使用以下定義:

這裏的scoped表示下方樣式僅僅當前組件有效,不然全局有效,經過@import咱們能夠導入外來樣式文件(這裏公共資源咱們通常定義在src的assets文件夾下,不用寫在static文件夾下,由於assets被打包時會自動打包,爲了統一仍是放在assets下面)

2)、組件間的數據交換

首先是父子組件間的數據交換:

父組件比如咱們這裏的App.vue組件,子組件就比如咱們import進來的那些組件,vue.js提供了咱們很便捷的方式進行跨組件間的通訊,對於父子組件那即是:子組件dispatch事件到父組件,父組件broadcast事件到下面的全部子組件,默認事件傳輸爲冒泡傳輸。什麼意思呢,就是說在App.vue裏面咱們能夠直接經過dispatch方法向上派發事件,前提是父組件須要在methods或者events那裏配置好改事件(只有配置了該事件才能接收到,推薦寫在events裏面),固然派發時能夠傳遞一些數據,同理父組件也是經過broadcast廣播事件到子組件。二是咱們能夠經過props屬性進行,子組件在script標籤中寫明須要prop的哪些屬性,父組件在調用子組件的地方直接寫上該prop(若是添加v-bind:prop則爲動態prop),那麼該數據便直接從父組件傳遞到了子組件中三是咱們能夠經過全局的$emit進行事件通訊,這個能夠參考官網文檔。

其次是任意無關係的組件如何通訊:

這個時候須要使用中間組件進行數據傳輸,至關於搭建起一箇中央數據總線,好比A組件須要和C組件進行通訊,那麼咱們能夠在定義一個空的組件爲B,那麼在A組件中導入B組件,同時向B組件派發事件,同時在C組件中導入B組件,並在此進行事件接收便可。固然瞭解vuex的話,使用vuex能夠輕鬆解決任意組件間的通訊問題,這個後面說。

3)、vue.js實例屬性

一個是$.parent和$.children,這兩個一個是獲取當前組件的父實例,一個是獲取當前組件的全部子組件,獲取到組件後即可以方便訪問實例的方法、數據資源等了。$.refs是在父組件調用子組件的地方,爲了區分各個子組件,能夠爲組件指定不一樣的ref屬性,而後在經過this.$refs.xxx得到該子組件實例,而後能夠進行各類實例操做。

四、運行效果

剛剛說了那麼多,咱們的項目差很少搭起來了,經過命令行:npm run dev,而後直接在瀏覽器中能夠查看效果:

默認啓動的是8080端口,訪問下:

到這裏,一切都ok了,簡單的vue.js腳手架項目就搭建完畢了。

2、vue-router

看到router,顧名思義「路由」的意思,vue-router賦予SPA應用前端路由的權利,從而實現自定義頁面跳轉而不請求服務端,主要記錄以下:

一、配置vue-router

在前面的腳手架項目裏面咱們已經生成了自帶vue-router的腳手架項目,下面主要是對其進行一些修改說明:

import Vue from 'vue'
import Router from 'vue-router'
// import store from '../vuex'
// import App from '../App.vue'
// import _ from 'lodash'

Vue.use(Router)

export const router = new Router({
  mode: 'history',
  routes: [
    // 組件懶加載,這樣可防止組件太多時首屏打開慢的問題
    { path: '/user', component: resolve => require(['../components/user/User.vue'], resolve) },
    { path: '*', component: null }
  ]
})

router.beforeEach((to, from, next) => {
  // to and from are Route Object,next() must be called to resolve the hook
  // if (!store.getters.logined) {

  // } else {
  //   next()
  // }
  next()
})

router必須使用vue.use進行全局註冊方可以使用,mode參數用來配置router的模式,默認爲帶「#」的hash模式,固然配置爲history則使用H5的history模式,路由更像是普通url。routes用來配置各類具體路由信息,這裏routes是一個對象數組,每個對象都是一個路由對象,其中包括path(路由路徑,支持正則匹配)、component(該路由對應的組件實例),注意的是通常咱們會對路由組件作懶加載處理,以便加快首屏渲染速度。

二、在組件中配置使用

router-view是用來作路由視圖的顯示的,第一步配置了每一個路由對應的路由,那麼一旦某個頁面使用router-view進行視圖顯示的話,剛好該路由匹配了上面path,那麼path對應的組件將會展現在router-view的位置,至關於路由組件的填位吧。固然一個頁面或組件能夠配置多個router-view,那麼相應的就須要引入多個組件實例了。

router-link是一個路由跳轉標籤,能夠理解爲咱們html中的a標籤,router-link標籤內部包含屬性to,一樣能夠路由配置。

關於路由方法:

router.push()、router.replace():路由跳轉

router.back():路由回退

router.forward():forward跳轉

其它參考官網說明,應用較多的是beforeEach方法,全部路由調用以前均執行該方法,這裏咱們通常能夠作一些權限判斷、登陸判斷之類的操做:

3、vuex狀態管理

vuex主要用來進行全局狀態管理,能夠理解爲全局的數據管理,vuex主要由幾部分組成:action、mutation、getters、state組成,通常的使用流程是:組件中能夠直接調用上面四個部分,好比調用action,可使用:this.$store.actionName,mutation也是同樣,不一樣的是action支持異步調用,mutation下的操做徹底同步,也就是說,action下能夠調用各類api調用(api方法通常都是異步的,返回promise對象)。組件訪問getters:this.$store.getters.gettersName,組件中調用state:this.$store.moduleName.stateName(模塊化配置vuex時這樣訪問)。action通常commit事件到mutation,而後再在mutation中操做state中的數據,最後經過getters暴露state中的數據給組件使用,若是不涉及到異步操做的話,能夠直接在組件中dispatch到相應的mutation而跳過action直接操做state。

一、配置vuex

首先是module下的user模塊內容:

import * as types from '../mutation.types'
import * as http from '../../api/http'

// import _ from 'lodash'

const state = {
  userinfo: JSON.stringify(localStorage.getItem('userinfo') || {})
}

const actions = {
  setUserInfo ({ commit }, userinfo) {
    localStorage.setItem('userinfo', userinfo)
    commit(types.SET_USERINFO, userinfo)
  },
  login ({dispatch, commit, getters}, plyload) {
    return http.get('/user/caiya', {})
  }
}

const mutations = {
  [types.SET_USERINFO] (state, userinfo) {
    state.userinfo = userinfo
  },
  [types.LOGOUT] (state) {
    localStorage.setItem('userinfo', '')
    state.userinfo = ''
  }
}

const getters = {
  logined (state) {
    return state.userinfo !== '' && state.userinfo !== '{}'
  },
  userinfo (state) {
    if (state.userinfo !== '' && state.userinfo !== '{}' && typeof state.userinfo === 'string') {
      return JSON.parse(state.userinfo)
    } else if (typeof state.userinfo === 'object') {
      return state.userinfo
    }
    return null
  }
}

export default {
  state,
  actions,
  mutations,
  getters
}

每一個module都有相應的四個組成部分,分別定義如上,而後再在index.js中配置出該模塊:

import Vue from 'vue'
import Vuex from 'vuex'

import user from './modules/user'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    user
  }
})

最後再將該store配置到全局的vue實例中:

二、actions

actions接收鍵值對函數,該函數第一個參數爲vuex的context對象,其中包括dispatch、commit、getters對象函數,經過ES6結構的方式能夠直接取到:

而後能夠直接進行相關操做,也能夠在此將payload數據commit到mutation中在此進行處理。

三、mutation

mutation通常用來對state中的數據進行修改操做,其中第一個參數爲state對象,後面參數不定,均爲action傳過來的參數或者頁面經過dispatch直接傳過來的參數

四、getters

能夠看到getters其實就是用來過濾處理state中的數據的,每一個getters函數第一個參數爲當前module下的state對象,定義好getters後組件中直接獲取getters便可獲取到state中的過濾後的數據:

五、最後看下要操做的state

其實state就是json對象,用來保存任意狀態的:

六、組件輔助函數

輔助函數是幹嗎的呢,好比以前咱們定義好的action、mutation、getters、state後,在組件中想使用他們要怎麼作呢?必須使用this.$store.getters.xxx來獲取getters xxx,要調用action必須使用this.$store.actionName來調用,mutation同理,獲取state要使用this.$store.state.moduleName.stateName獲取指定moduleName下的stateName這個state數據,這樣調用比較麻煩,因此輔助函數就出現了。

好比咱們Login.vue組件須要調用actions中的Login方法,以下:

一樣地方式咱們能夠這樣直接調用mutation:

再來看個getters的:

4、axios

axios是一個http請求包,相似於vue-resource(該包已中止維護),vue官網推薦使用axios進行http調用,由於axios壓縮後體積更小,支持restful方法調用,關於axios的使用看以下代碼,其中有詳盡介紹:

import axios from 'axios'

axios.defaults.baseURL = 'https://cnodejs.org/api/v1'
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

const ACCESS_TOKEN = 'accesstoken=ed20aac8-9fd8-45bf-8112-62fd2425b4a5'

// 添加請求攔截器
axios.interceptors.request.use(config => {
  // 在發送請求以前作些什麼
  config.url = `${config.url}?${ACCESS_TOKEN}`
  return config
}, error => {
  // 對請求錯誤作些什麼
  return Promise.reject(error)
})

// 添加響應攔截器
axios.interceptors.response.use(response => {
  // 對響應數據作點什麼
  return response
}, error => {
  // 對響應錯誤作點什麼
  return Promise.reject(error)
})

export function fetch (url, params) {
  return new Promise((resolve, reject) => {
    axios.post(url, params).then(res => {
      resolve(res)
    }).catch(err => {
      reject(err)
    })
  })
}

export function get (url, params) {
  return new Promise((resolve, reject) => {
    axios.get(url, {
      params: params
    }).then(res => {
      resolve(res)
    }).catch(err => {
      reject(err)
    })
  })
}

這樣將該http.js文件導出後,能夠直接在action中調用,不用全局vue配置,十分方便。axios.interceptors.request方法主要用來給全部的請求添加攔截器,這裏能夠進行各類請求權限校驗、方法重寫等操做,axios.interceptors.response主要是對響應作攔截處理,好比說咱們服務端返回狀態碼爲403,表示無權限信息,那麼這裏能夠直接進行相關錯誤信息展現,或者直接跳轉至登陸或其它頁面。

5、一個簡單應用

閒暇時間作了個簡單的登陸及後臺管理系統(ps:剛開始作),簡單效果以下,github地址:https://github.com/caiya/frontend

 

6、最後想多說幾句

一、任何技術,想學就得多動手去作,實踐出真知啊,光看不作經不起實戰的考驗

二、多寫博客仍是不錯的哈哈哈,不光是練文筆,陶冶情操也是有的,更別提那些大無畏的分享精神了

相關文章
相關標籤/搜索