19: vue項目使用整理


 1.1  axios 基本用法

   安裝:npm install axios -S                   # 也可直接下載axios.min.js文件

  1、axios借助Qs對提交數據進行序列化

      axios參考博客:https://www.jianshu.com/p/68d81da4e1ad

                                https://www.cnblogs.com/yiyi17/p/9409249.html

      axios官網:https://www.npmjs.com/package/axios 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>發送AJAX請求</title>
</head>
<body>
<div id="itany">
  <button @click="sendGet">GET方式發送AJAX請求</button>
</div>

<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/qs.js"></script>
<script>
  window.onload=function(){
    new Vue({
      el:'#itany',
      data:{
        uid:''
      },
      methods:{
        sendGet(){
          // 1、發送get請求
          axios({
            url: 'http://127.0.0.1:8000/data/',                 //1、請求地址
            method: 'get',                                        //2、請求方法
            params: {ids: [1,2,3],type: 'admin'},                //3、get請求參數

            paramsSerializer: params => {                          //4、可選函數、序列化`params`
              return Qs.stringify(params, { indices: false })
            },
            responseType: 'json',                                //5、返回默認格式json
            headers: {'authorization': 'xxxtokenidxxxxx'},     //6、認證token
          })
          // 2、回調函數
          .then(resp => {
            console.log(resp.data);
          })
          // 3、捕獲異常
          .catch(err => {
            console.log('請求失敗:'+err.status+','+err.statusText);
          });
        }

      }
    });
  }
</script>
</body>
</html>
get:axios發送get請求
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>發送AJAX請求</title>
</head>
<body>
<div id="itany">
  <button @click="sendPost">POST方式發送AJAX請求</button>
</div>

<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/qs.js"></script>
<script>
  window.onload=function(){
    new Vue({
      el:'#itany',
      data:{
        uid:''
      },
      methods:{
        sendPost(){
          // 1、發送post請求
          axios({
            url: 'http://127.0.0.1:8000/data/',             //1、請求地址
            method: 'post',                                  // 2、請求方法
            data: Qs.stringify(                               //3、可選函數、序列化`data`
              {ids: [1,2,3],type: 'admin'},                  //4、提交數據
              { indices: false }                             // indices: false
            ),
            responseType: 'json',                           //5、返回默認格式json
            headers: {'authorization': 'xxxtokenidxxxxx'},//6、身份驗證token
        })
        // 2、回調函數
        .then(resp => {
          console.log(resp.data);
        })
        // 3、捕獲異常
        .catch(err => {
          console.log('請求失敗:'+err.status+','+err.statusText);
        });
        }
      }
    });
  }
</script>
</body>
</html>
post: axios發送post請求
def data(request):
    if request.method == 'GET':
        token_id = request.META.get('HTTP_AUTHORIZATION')  # header中的tokenid
        print(request.GET.getlist('ids'))                   # 獲取get請求中列表
        data = {
            'id':1,
            'name': 'zhangsan'
        }
        return HttpResponse(json.dumps(data))
    elif request.method == 'POST':
        token_id = request.META.get('HTTP_AUTHORIZATION')  # header中的tokenid
        print(request.POST.getlist('ids'))                  # 獲取post請求中的列表
        data = {
            'id':1,
            'name': 'zhangsan',
            'method': 'POST'
        }
        return HttpResponse(json.dumps(data))
views.py后端測試接口
#1、qs用途:  在 axios中,利用QS包裝data數據 #2、安 裝:  npm install qs -S #3、常見用法:
''' import Qs from 'qs'; Qs.stringify(data); Qs.parse(data) '''

  2、axios上傳文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>發送axios請求</title>
</head>
<body>
<div id="itany">
    <input type="file" name="fileUpload" id="fileUp" @change="change($event)" ref="inputFile" >

    <button @click="sendPost">POST方式發送axios請求</button>
</div>

<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/qs.js"></script>
<script>
    window.onload=function(){
        new Vue({
            el:'#itany',
            data:{
                uid:''
            },
            methods:{
                sendPost(){
                    // 1、發送post請求
                    var data = new FormData();
                    data.append("fafafa",this.file)  // 圖片對象
                    data.append("username","zhangsan")  // 其他key-value值
                    axios({
                        url: 'http://127.0.0.1:8000/data/',             //1、請求地址
                        method: 'post',                                  //2、請求方法
                        data: data,                                       //3、提交的數據
                        responseType: 'json',                           //4、返回默認格式json
                        headers: {'authorization': 'xxxtokenidxxxxx'},//5、身份驗證token
                    })
                    // 2、回調函數
                    .then(resp => {
                        console.log(resp.data);
                    })
                    // 3、捕獲異常
                    .catch(err => {
                        console.log('請求失敗:'+err.status+','+err.statusText);
                    });
                },
                change:function(event){
                    this.file = event.target.files[0]
                },
            },
        });
    }
</script>
</body>
</html>
test.html
def data(request):
    if request.method == 'GET':
        data = {
            'id':1,
            'name': 'zhangsan'
        }
        return HttpResponse(json.dumps(data))
    elif request.method == 'POST':
        username = request.POST.get('username')
        fafafa = request.FILES.get('fafafa')
        print(username, fafafa)

        with open(fafafa.name, 'wb') as f:
            for item in fafafa.chunks():
                f.write(item)
        ret = {'code': True, 'data': request.POST.get('username')}
        data = {
            'id':1,
            'name': 'zhangsan',
            'method': 'POST'
        }
        return HttpResponse(json.dumps(data))
views.py

 1.2 封裝axios發送請求 & 添加攔截器

    參考:https://blog.csdn.net/qq_40128367/article/details/82735310

  1、初始化vue項目

# vue init webpack deaxios
# npm install axios -S
# cnpm install vuex -S
# cnpm install vant -S
# cnpm install nprogress -S

  2、封裝axios(創建 src/api 文件夾)

export default {
  // api請求地址
  API_URL: 'http://127.0.0.1:8000/'
}
config\urls.js 配置全局url變量
import Qs from 'qs'
import instance from './axiosinstance'  // 導入自定義 axios 實例
// import instance from 'axios'           // 也可以直接使用原生 axios 實例,但無法添加攔截器

/* 1. 發送GET請求 */
export function get(url, params){
  return new Promise((resolve, reject) =>{
    // 1、發送get請求
    instance({
      url: url,                     //1、請求地址
      method: 'get',                //2、請求方法
      params: params,                //3、get請求參數
      headers: {
        'Content-Type': 'application/json'
      },
      paramsSerializer: params => {                          //4、可選函數、序列化`params`
        return Qs.stringify(params, { indices: false })
      },
    })
    // 2、回調函數
      .then(res => {
        resolve(res.data);
      })
      // 3、捕獲異常
      .catch(err => {
        reject(err.data)
      });

  });
}

/* 2. 發送POST請求 */
export function post(url, params) {
  return new Promise((resolve, reject) => {
    instance({
      url: url,             //1、請求地址
      method: 'post',                                  // 2、請求方法
      data: Qs.stringify(                               //3、可選函數、序列化`data`
        params,                  //4、提交數據
        { indices: false }                             // indices: false
      ),
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
      },
    })
    // 2、回調函數
      .then(res => {
        resolve(res.data);
      })
      // 3、捕獲異常
      .catch(err => {
        reject(err.data)
      })
  });
}
src\api\ajax.js 封裝axios請求
import Axios from 'axios'
import { Toast } from 'vant';
import URLS from '../../config/urls'

//1、使用自定義配置新建一個 axios 實例
const instance = Axios.create({
  baseURL: URLS.API_URL,
  responseType: 'json',
});

//2、添加請求攔截器:每次發送請求就會調用此攔截器,添加認證token
instance.interceptors.request.use(
  config => {
    //發送請求前添加認證token,
    config.headers.Authorization = sessionStorage.getItem('token')
    return config
  },
  err => {
    return Promise.reject(err)
  });

// 3、響應攔截器
instance.interceptors.response.use(
  response => {
    if (response.status === 200) {
      return Promise.resolve(response);
    } else {
      return Promise.reject(response);
    }
  },
  // 服務器狀態碼不是200的情況
  error => {
    if (error.response.status) {
      switch (error.response.status) {
        // 401: 未登錄
        // 未登錄則跳轉登錄頁面,並攜帶當前頁面的路徑
        // 在登錄成功后返回當前頁面,這一步需要在登錄頁操作。
        case 401:
          router.replace({
            path: '/login',
            query: { redirect: router.currentRoute.fullPath }
          });
          break;
        // 403 token過期
        // 登錄過期對用戶進行提示
        // 清除本地token和清空vuex中token對象
        // 跳轉登錄頁面
        case 403:
          Toast({
            message: '登錄過期,請重新登錄',
            duration: 1000,
            forbidClick: true
          });
          // 清除token
          localStorage.removeItem('token');
          store.commit('loginSuccess', null);
          // 跳轉登錄頁面,並將要瀏覽的頁面fullPath傳過去,登錄成功后跳轉需要訪問的頁面
          setTimeout(() => {
            router.replace({
              path: '/login',
              query: {
                redirect: router.currentRoute.fullPath
              }
            });
          }, 1000);
          break;
        // 404請求不存在
        case 404:
          Toast({
            message: '網絡請求不存在',
            duration: 1500,
            forbidClick: true
          });
          break;
        // 其他錯誤,直接拋出錯誤提示
        default:
          Toast({
            message: error.response.data.message,
            duration: 1500,
            forbidClick: true
          });
      }
      return Promise.reject(error.response);
    }
  }
);

export default instance
src\api\axiosinstance.js 自定義axios 實例
import * as api from './api'

export default api
src\api\index.js 導出api模塊
import Vue from 'vue'
import Vuex from 'vuex'
import * as api from '../api/api'

Vue.use(Vuex);

export default new Vuex.Store({
    modules:{
        api
    }
});
src\store\index.js 全局導出路由方法變量
import Vue from 'vue'
import App from './App'
import router from './router'
import NProgress from 'nprogress'
import store from './store/index'

Vue.config.productionTip = false

/*  定義:路由鈎子主要是給使用者在路由發生變化時進行一些特殊的處理而定義的函數 */
router.afterEach(transition => {
  setTimeout(() => {
    NProgress.done()
  })
})

window.APP_INFO = process.env.APP_INFO

router.beforeEach((to, from, next) => {
  /*
  * to: router即將進入的路由對象
  * from: 當前導航即將離開的路由
  * next: 進行管道中的一個鈎子,如果執行完了,則導航的狀態就是 confirmed (確認的);否則為false,終止導航。
  * */
  NProgress.start()
  // 使用假數據模擬張三已經登錄
  localStorage.setItem('user', JSON.stringify({'username':'zhangsan'}) )
  if (to.path === '/login') {
    localStorage.removeItem('user')
  }
  let user = JSON.parse(localStorage.getItem('user'))
  if (!user && to.path !== '/login') {  // 如果用戶沒有登錄,且訪問url不是 '/login' 調整到登錄頁
    next({ path: '/login' })
  } else {
    next()
  }
})
/*  攔截器介紹位置 */


/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})
main.js 使用鈎子函數進行路由控制

  3、使用封裝的axios發送請求

import URLS from '../../config/urls'
import { get, post } from './ajax'
let base = URLS.API_URL

// 用戶相關
export const postLogin = p => post(`${base}/login/`, p);
export const getLogin = p => get(`${base}/login/`, p);
src\api\api.js 定義請求路由方法
<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
  import { postLogin,getLogin } from './api/api'  // 導入路由請求方法
  export default {
    name: 'App',
    created () {
      this.testGet();
      this.testPost();
    },
    methods: {
      // 獲取數據
      testPost() {
        // 調用api接口,並且提供了兩個參數
        postLogin({
          type: 0,
          sort: 1,
          lst:[1,2,3,4,5]
        }).then(res => {
          // 獲取數據成功后的其他操作
          console.log(res,1111111)
        }).catch(
        )
      },

      testGet() {
        // 調用api接口,並且提供了兩個參數
        getLogin({
          type: 0,
          sort: 1,
          lst:[1,2,3,4,5]
        }).then(res => {
          // 獲取數據成功后的其他操作
          console.log(res,22222222222222)
        }).catch(
        )
      },
    }
  }
</script>
App.vue 導入路由請求方法測試請求數據

   4、如果需要上傳圖片或文件 src\api\ajax.js 中傳入的 params參數不可使用Qs序列化

import Qs from 'qs'
import instance from './axiosinstance'  // 導入自定義 axios 實例
// import instance from 'axios'           // 也可以直接使用原生 axios 實例,但無法添加攔截器

/* 1. 發送GET請求 */
export function get(url, params){
    return new Promise((resolve, reject) =>{
        // 1、發送get請求
        instance({
            url: url,                     //1、請求地址
            method: 'get',                //2、請求方法
            params: params,                //3、get請求參數
            headers: {
                'Content-Type': 'application/json'
            },
            paramsSerializer: params => {                          //4、可選函數、序列化`params`
                return Qs.stringify(params, { indices: false })
            },
        })
        // 2、回調函數
            .then(res => {
                resolve(res.data);
            })
            // 3、捕獲異常
            .catch(err => {
                reject(err.data)
            });

    });
}

/* 2. 發送POST請求 */
export function post(url, params) {
    var isFormData = Object.prototype.toString.call(params) === '[object FormData]'
    var data = '';  // 如果是上傳文件傳入的 params是一個 FormData對象,不要用Qs序列化
    if(isFormData){
        data = params
    }else {
        data = Qs.stringify(                               //3、可選函數、序列化`data`
            params,                                        //4、提交數據
            { indices: false }                            // indices: false
        )
    }
    return new Promise((resolve, reject) => {
        instance({
            url: url,             //1、請求地址
            method: 'post',                                  // 2、請求方法
            data: data,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
            },
        })
        // 2、回調函數
            .then(res => {
                resolve(res.data);
            })
            // 3、捕獲異常
            .catch(err => {
                reject(err.data)
            })
    });
}
src\api\ajax.js 封裝axios請求(需要上傳圖片)
<template>
    <div id="itany">
        <input type="file" name="fileUpload" id="fileUp" @change="change($event)" ref="inputFile" >

        <button @click="sendPost">POST方式發送axios請求</button>
    </div>
</template>

<script>
    import { createGoods } from '../../api/api'
    export default {
        data() {
            return {}
        },
        methods: {
            sendPost(){
                // 1、發送post請求
                var data = new FormData();
                data.append("fafafa",this.file)  // 圖片對象
                data.append("username","zhangsan")  // 其他key-value值
                createGoods(data)
                // 2、回調函數
                    .then(resp => {
                        console.log(resp);
                    })
                    // 3、捕獲異常
                    .catch(err => {
                        console.log('請求失敗:'+err.status+','+err.statusText);
                    });
            },
            change:function(event){
                this.file = event.target.files[0]
            },
        }
    }
</script>

<style scoped>

</style>
Goods.vue 上傳圖片測試
def data(request):
    if request.method == 'GET':
        token_id = request.META.get('HTTP_AUTHORIZATION')  # header中的tokenid
        data = {'id':1,'name': 'zhangsan'}
        return HttpResponse(json.dumps(data))
    elif request.method == 'POST':
        username = request.POST.get('username')
        fafafa = request.FILES.get('fafafa')
        with open(fafafa.name, 'wb') as f:
            for item in fafafa.chunks():
                f.write(item)
        ret = {'code': True, 'data': request.POST.get('username')}
        data = {'id':1,'name': 'zhangsan','method': 'POST'}
        return HttpResponse(json.dumps(data))
views.py

 1.3 vue配置前端跨域

   參考博客:https://www.cnblogs.com/qqing/p/8980199.html

  1、初始化vue項目

vue init webpack my-project  # 初始化項目
cd my-project                # 進入項目路徑
cnpm install                 # 安裝依賴
cnpm install axios -S        # 安裝axios

  2、在 src/main.js 中如下聲明使用

import axios from 'axios'; Vue.prototype.$axios=axios;

  3、在 config/index.js 中的 的dev 添加以下代碼,設置一下proxyTable

    //加入以下
 proxyTable:{ '/api': { target : 'http://127.0.0.1:8000',   //設置你調用的接口域名和端口號.別忘了加http
        changeOrigin : true,                 //允許跨域
 pathRewrite : { '^/api':''
          // ''這里理解成用‘/api’代替target里面的地址,后面組件中我們掉接口時直接用api代替。
          // 比如我要調用'http://127.0.0.1:8000/index/',直接寫‘/api/index/’即可
 } } },

  4、在 config/dev.env.js 中設置以下代碼

module.exports = merge(prodEnv, { NODE_ENV: '"development"',  //開發環境
  API_HOST:"/api/" })

  5、在 config/prod.env.js 中設置以下代碼

module.exports = { NODE_ENV: '"production"',//生產環境
  API_HOST:'"127.0.0.1:8000"' }

  6、修改src\App.vue文件

<template>
  <div id="app">
    <button @click="testAxios()">測試axios</button>
  </div>
</template>

<script>
  import axios from 'axios';
  export default {
    data () {
      return {

      }
    },
    methods:{
      testAxios () {
        this.$axios.get('/api/index/')
          .then((response) => {
            console.log(response.data)
          })
      }
    }
  }
</script>

  7、說明

      1. vue前端結局跨域主要思想是代理功能,比如:
          vue項目:http://localhost:8080/
          后端項目:http://127.0.0.1:8000/

      2. 在瀏覽器端訪問 http://localhost:8080/api/index/ 路徑時,vue會匹配到以 /api/ 開頭的請求

      3. 此時 vue會使用代理功能 自動轉發到  http://127.0.0.1:8000/index/   此時就是同一個域,就不會觸發跨域問題

 

 

 

 

 

 

11111111111111


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM