使用Mock模擬好後端數據之後(Mock模擬數據的使用參考:https://segmentfault.com/a/11...),就需要嘗試請求加載數據了。數據請求選擇了axios,現在都推薦使用axios。
axios(https://github.com/axios/axios)是基於 promise 的 HTTP 庫。如官網文檔介紹,npm i 之後,在需要的組件中加載就可以了。個人認爲,編碼的魅力在於,解決問題的方法不止一種,有時候這個方法在你的開發環境下ok,在我的開發環境下卻不ok,所以,問題是各式各樣的,而解決問題的方法也是百花齊放的。
axios的入門
1、安裝
npm i axios -S
2、引入
在src目錄下新建apis.js文件(項目逐漸完善的過程中會有很有個api接口,當然也可以命名爲axios.js,命名是爲了讓別人看懂),並引入:
import axios from 'axios';
之後,編輯apis.js文件,考慮封裝axios.get或post請求
3、apis.js文件的編輯
import axios from 'axios';
const Domain = "http://localhost:8080"; // 定義根域名
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; // 設置post默認的請求頭
// 封裝 post 請求
export function post(action, params){
return new Promise((resolve, reject) => {
// url 判斷是測試環境 就要拿 測試環境的域名, 正式環境的就要用 正式域名
let url = Domain + action;
axios.post(url, params)
.then(response => {
resolve(response.data)
})
.catch(error => {
reject(error)
})
});
}
// 封裝 get 請求
export function get(action, params){
return new Promise((resolve, reject) => {
axios.get(Domain + action, params)
.then(response => {
resolve(response.data)
})
.catch(error => {
reject(error)
})
});
}
export default {
postData(action, params){
return post(action, params)
},
getData(action, params){
return get(action, params)
}
}
4、在需要的組件中進行引用
import api from '../../apis.js';
export default {
name: "banner",
data() {
return {
bannerList: []
};
},
created(){
this.getBanner(); // 在頁面渲染完成即加載
},
methods: {
getBanner(){
this.$api.getData('/getBanner').then(val => {
this.bannerList = val.imgs;
});
}
}
}
5、全局配置axios
很多組件都需要請求數據,每用一次導入一次很麻煩,全局配置之後就不用在組件中導入了。
在入口文件main.js中引入,之後掛在vue的原型鏈上:
import api from './apis.js';
Vue.prototype.$http = api;
在組件中使用:
getBanner(){
this.$http.getData('/getBanner').then(val => {
this.bannerList = val.imgs;
});
}
6、axios結合vuex(在項目中還沒用到,如果有問題,歡迎指正)
在vuex的倉庫文件store.js中引用,使用action添加方法。action 可以包含異步操作,而且可以通過 action 來提交 mutations。action有一個固有參數context,但是 context 是 state 的父級,包含state、getters
import Vue from 'Vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
export default new Vuex.Store({
// 定義狀態
state: {
banners: {
name: 'pic'
}
},
actions: {
// 封裝一個 ajax 方法
saveBanner (context) {
axios({
method: 'get',
url: '/getBanner',
data: context.state.banners
})
}
}
})
在組件中發送請求的時候,需要使用 this.$store.dispatch 來分發
methods: {
getBananer() {
this.$store.dispatch('saveBanner') // actions裏的方法名
}
}
異步加載的幾種方法
1、$.ajax( url[, settings])
url: 要求爲String類型的參數,(默認爲當前頁地址)發送請求的地址。
type: 要求爲String類型的參數,請求方式(post或get)默認爲get。
data:規定要發送到服務器的數據。
async:布爾值,表示請求是否異步處理。默認是 true。
dataType: 要求爲String類型的參數,預期服務器返回的數據類型。
contentType:要求爲String類型的參數,當發送信息至服務器時,內容編碼類型默認爲"application/x-www-form-urlencoded"。
success:要求爲Function類型的參數,請求成功後調用的回調函數。
error:Function類型的參數,請求失敗後調用的回調函數。
jsonp:在一個 jsonp 中重寫回調函數的字符串。
$(function(){
$('#send').click(function(){
$.ajax({
type: "GET",
url: "test.json",
data: {username:$("#username").val(), content:$("#content").val()},
dataType: "json",
success: function(data){
// handle success
}
error: function(data){
// handle error
}
jsonp: ""
});
});
});
2、$.ajax 的跨域請求問題
當Ajax請求的url不是本地或者同一個服務器的地址時,瀏覽器會報一個錯誤:No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin…………由於瀏覽器的安全機制,不能調用不同服務器下的url地址。基於此,jQuery.ajax給出了jsonp的解決方案: 把服務器返回的數據類型設置爲jsonp。
$(function(){
$('#send').click(function(){
$.ajax({
type: "GET",
url: "test.json",
data: {username:$("#username").val(), content:$("#content").val()},
dataType: "jsonp", // jsonp格式
success: function(data){
// handle success
}
error: function(data){
// handle error
}
jsonp: "callback"
});
});
});
但是,jsonp是一種非官方的方法,而且這種方法只支持get請求,不如post請求安全。此外,jsonp需要服務器配合,如果是訪問的是第三方服務器,我們沒有修改服務器的權限,那麼這種方式是不可行的。
3、vue框架中的vue-resource
ue-resource是Vue.js的一款插件,它可以通過XMLHttpRequest或JSONP發起請求並處理響應。vue-resource體積小,支持主流瀏覽器。不過,vue2.0之後就不再更新了,尤大神推薦使用axios。
{
// GET /someUrl
this.$http.get('/someUrl').then(response => {
// get body data
this.someData = response.body;
}, response => {
// error callback
});
}
4、vue-resource的跨域請求問題
同樣地,由於瀏覽器的安全機制,vue-resource也面臨着跨域請求的問題。解決方案如下:在vue項目下的 config/index.js 文件裏面配置代理proxyTable:
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: { // 新增,解決跨域請求問題
'/api': {
target: 'http://192.168.1.103:8080/',
changeOrigin: true,
pathRewrite: {
'`/api': '/'
}
},
secure: false
},
target中寫你想要請求數據的地址的域名
4、axios跨域請求的問題
與vue-resource一樣,在vue項目下的 config/index.js 文件裏面配置代理proxyTable:
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: { // 新增,解決跨域請求問題
'/api': {
target: 'http://192.168.1.103:8080/',
changeOrigin: true,
pathRewrite: {
'`/api': '/'
}
},
secure: false
},
不過vue-resource和axios這兩個方法,可能配置了代理proxyTable還是會報:No 'Access-Control-Allow-Origin' header is present on ……的問題,這需要後端服務器配合設置:
header("Access-Control-Allow-Origin", "*");
header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
emmmm,總感覺自己還是有點懵 233