一、前言 博主也是vue道路上的行者,道行不深,希望自己的東西能對大家有所幫助。這篇博客針對 瞭解過vue基礎,但是沒有做過vue項目的童鞋。如果想看基礎指令,可以看我之前的一篇博客,請點擊 跳轉, 不過我還是建議看文檔比較好。os: Vue文檔是非常詳細的 二、準備 做vue單頁應用都需要會什麼? ...
一、前言
博主也是vue道路上的行者,道行不深,希望自己的東西能對大家有所幫助。這篇博客針對 瞭解過vue基礎,但是沒有做過vue項目的童鞋。如果想看基礎指令,可以看我之前的一篇博客,請點擊 跳轉, 不過我還是建議看文檔比較好。os: Vue文檔是非常詳細的
二、準備
做vue單頁應用都需要會什麼?
1. vue的腳手架,直接幫你建好項目。再看看自己想要啥,補充啥! os: Git 上有很多成品項目,可以找一個好點的拉下來
註: 路由按需載入、熱載入 等這些都是基礎功能,在這不多說。os: 慕課網有Vue的課程,網上有資源,挺不錯的
2. 引入並會使用 vuex。對共用變數進行統一管理,解決多層組件傳數據的問題。這個咱後面詳說。
3. 封裝 axios,對請求進行統一的管理,並減少代碼量。
三、關於vuex
出現背景: 瞭解過vue1.0的人應該都知道,vue的父子組件通信是很煩的,一層還好。如果有個3、4層,那父子組件通信,就頭疼了。以前,這是需要開發者捋清邏輯,在合適的地方修改並傳遞的。但是vue2.0為瞭解決這個問題,提出了vuex,狀態統一管理。
作用: vuex 將所有需要共用的變數放在一起,像一個倉庫一般,你想對倉庫中的變數 讀取、修改 ,直接調 指定方法就可以,超級方便。
結構: vuex的結構大致為:
state: 存放所有變數
mutations 存放同步讀取、修改state的的方法
action 存放非同步讀取、修改state的的方法
.......還有很多其他的 os: 這篇博客只是幫大家瞭解如何用Vue做單頁應用。
註: 1. 不是所有變數都要放到 state 中,vuex 創立的初衷是方便我們對變數的管理,然而對組件的一些私有變數,不需要和別的組件共用。所以,state裡面只放全局變數、多組件共用變數。
2. 解釋一下 action ,所謂非同步,就是在 action 文件中寫方法,調 axios,然後再 調 mutations 同步修改state。很多人不理解,其實,這就是一個概念性的問題。action並沒有從根本上解決非同步修改state的競爭問題,但是我們需要理解、並將 非同步這個操作 摘出來放在一起。
os: js腳本 本來就是同步的東西,一根筋,同一時間無法處理2件事,不存在多線程處理事務。不過,科技發展的這麼牛逼,大家懂得。這個非同步、競爭的思想還是要提出來的,指不定哪天就被大家研究出瞭解決方案。
四、關於vuex的具體使用
先看一下項目的部分目錄結構
1. state.js
const state = {
topList: {},
msgg: '1231321312',
alertFlag: {state: false, type: ''},
errorStatus: '',
alertData: {title: '警告', content: '這是敏感信息,一旦刪除,不可再恢復,確認刪除嗎', operateOk: '確定', operateCan: '取消', time: ''},
httpError: {
hasError: false,
status: '',
statusText: ''
},
tip: {
tipFlag: false,
tipMsg: ''
}
}
export default state
state 文件裡面存放一個state對象,具體的元素就是我們的變數了,需要什麼數據,和組件的data函數中一樣寫法。這裡只是起到存儲作用
2. mutations.js
import * as types from './mutation-types'
const mutations = {
// 顯示彈窗
[types.SET_ALERT_FLAG](state, data) {
state.alertFlag = data
},
// 設置彈窗內容
[types.SET_ALERT_DETAIL](state, data) {
Object.assign(state.alertData, data)
},
[types.ON_HTTP_ERROR](state, payload) {
state.httpError = payload
},
// 設置提示彈層
[types.SET_TIP_INFOR](state, data) {
state.tip = data
}
}
export default mutations
mutations 同步修改 state的值,僅僅是提供一個方法,接收參數,修改state值的文件。就是一個存儲修改state方法的倉庫。
一般我們在開發的時候請求比較多,我們會新建一個 mutation-types.js 文件,將所有函數用常量保存。其實也沒什麼特殊意義,僅僅是將方法統一保存,查找、維護比較方便而已。
3. action
import * as types from './mutation-types'
import { getTest } from '../server/index.js'
export const getData = function ({commit, state}, {list, index}) {
commit(types.SET_TIP_INFOR, {tipFlag: false, tipMsg: ''})
}
export const actionTest = function ({commit, state}, data) {
getTest({
url: 'getPhoneCode.php',
data: JSON.stringify({
'phone': '18862533985'
})
})
.then(response => {
console.log(response.data)
commit(types.SET_ALERT_DETAIL, {title: '提示', content: '您確定要還款嗎?'})
commit(types.SET_ALERT_FLAG, {state: true, type: ''})
})
}
action 非同步修改 state 的值。說白了,action也是一個存放修改state方法的倉庫,但是 這些方法都是要調axios請求的(所以叫非同步),請求完事了,再調 mutations 去同步修改state的值。所謂的非同步都是我們自己寫的。當然你不這麼寫也行,只是設計者的初衷是想讓讓開發者清楚非同步修改的概念,雖然暫時沒有解決根本問題。
這裡涉及到axios請求,這個下邊解釋,暫時先清楚 action的概念。
4. vuex和組件通信
上述介紹了 vuex的幾個部分的作用,那現在就是如何在組件中去使用 vuex
首先,在main.js中,你需要將store對象引入到整個應用中
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
然後在組件中使用
// 直接使用
<alert v-if="this.$store.state.alertFlag.state"></alert>
// 同步的 commit
this.$store.commit('SET_ALERT_DETAIL', {title: '提示', content: '您確定要還款嗎?'}
// 非同步的 dispatch
this.$store.dispatch('actionTest').then(() => {})
簡單介紹一下:
this.$store.state. 我們通過$store對象 ,直接使用state中的屬性
this.$store.commit('', {}) 通過 commit 方法調 mutations-types 中的方法(其實就是mutations的方法),這步是同步的,而且數據會自動監聽變化就行渲染
this.$store.dispatch('actionTest').then(() => {}) 通過 dispatch 的方法調 action 的方法,非同步修改 state
註:vue中的這個 this 註意他的指向,建議不確定時,先將this賦給變數保存起來,有時經常會和window對象混淆。
以上就是vuex最基礎的用法,也是最常用的方法。其他的像 getters 、如何組件中引入vuex等等,這裡就不細說了,大家可以根據自身需求自行看文檔補充。
五、 封裝axios
在一個完整的項目中,我們的和服務端的交互會很頻繁,一個項目會有很多請求,冗餘代碼很多。所以將請求封裝,統一管理還是很有必要的。我們現在做一個簡單的封裝。
1. 先看一下結構
2. 看一下具體代碼
axios.js 文件
import axios from 'axios'
// 創建axios實例 application/x-www-data-urlencoded application/json
const service = axios.create({
baseURL: 'http://www.niepengfei.cn/PHPFile/ybtDemo/',
timeout: 15000,
headers: {'Content-Type': 'application/json'}
})
service.interceptors.response.use(
function(response) {
// 請求正常則返回,這裡返回了所有的請求頭和請求體信息
return Promise.resolve(response)
},
function(error) {
// 請求錯誤則向store commit這個狀態變化
const httpError = {
alertFlag: true,
errorStatus: error.response.status,
msgg: error.response.statusText
}
this.$store.commit('SET_ALERT_FLAG', {state: false, type: 'ok'})
console.log(httpError)
return Promise.reject(error)
}
)
export default service
index.js 文件
import request from './axios.js'
export function getTest(axiosData) {
var data = {
url: '',
method: 'post',
data: ''
}
// 合成請求對象
Object.assign(data, axiosData)
return request(data)
}
這裡我們僅僅做了post 請求的封裝。先對axios做上預設請求的數據,封裝成函數,有傳參就合併修改參數數據,請求結束之後,根據response、error,分成成功和失敗兩個函數,並將整個promise對象返回。對於請求的攔截這裡沒做。而且對網路請求的錯誤碼也是大家根據項目具體提示的。我這裡也不做詳細的說明瞭
3. 組件中使用
import { getTest } from '../../server/index.js'
getTest({
url: 'login.php',
data: JSON.stringify({
'phone': thiss.phone,
'phoneCode': thiss.phoneCode
})
})
.then(response => {
console.log(response.data)
if (response.data.code === '0000') {
...
}
})
將封裝的axios引入組件,然後直接調用即可
六、總結
以上就是 vuex+axios封裝的實例,時間原因,這裡進提供思路和簡單的實現方法,至於具體項目具體分析,axios要怎麼封裝,vuex還需做什麼監聽,那就是大家為自己項目定製的東西了。
好了,以上就是整篇博客的所有內容,希望對大家有所幫助。如果,文中有錯誤的地方還請大家及時指出。
如果喜歡我博客的朋友可以添加個關註,以後多交流技術問題!近期還會在更新一些react的博客。