前后端跨域+父子组件传参

1 前后端跨域

1.1 前端

1.1.1 方法一
1)index.js
import axios from 'axios'
axios.defaults.baseURL="http://192.168.56.100:8000/"
axios.defaults.timeout = 1000000;
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.headers.put['Content-Type'] = 'application/json';

axios.interceptors.request.use(    
    config => {
        // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
        const token = sessionStorage.getItem("jwt_token")   
        console.log(token)  
        if (token){
            config.headers.Authorization = 'JWT '+ token
        }           
        return config;    
    },    
    error => {        
        return Promise.error(error);    
    })



axios.interceptors.response.use(    
    // 请求成功
    res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),    

    // 请求失败
    error => {
        if (error.response) {
            // 判断一下返回结果的status == 401?  ==401跳转登录页面。  !=401passs
            console.log(error.response)
            if(error.response.status===401){
                // 跳转不可以使用this.$router.push方法、
                // this.$router.push({path:'/login'})
                window.location.href="http://127.0.0.1:8080/#/login"
            }else{
                // errorHandle(response.status, response.data.message);
                return Promise.reject(error.response);
            }
            // 请求已发出,但是不在2xx的范围 
        } else {
            // 处理断网的情况
            // eg:请求超时或断网时,更新state的network状态
            // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
            // 关于断网组件中的刷新重新获取数据,会在断网组件中说明
            // store.commit('changeNetwork', false);
            return Promise.reject(error.response);
        }
    });


// 封装xiaos请求  封装axios里的get
export function axios_get(url,params){
    return new Promise(
        (resolve,reject)=>{
            axios.get(url,{params:params})
            .then(res=>{
                console.log("封装信息的的res",res)
                resolve(res.data)
            }).catch(err=>{
                reject(err.data)
            })
        }
    )
}


export function axios_post(url,data){
    return new Promise(
        (resolve,reject)=>{
            console.log(data)
            axios.post(url,JSON.stringify(data))
            .then(res=>{
                console.log("封装信息的的res",res)
                resolve(res.data)
            }).catch(err=>{
                reject(err.data)
            })
        }
    )
}

export function axios_put(url,data){
    return new Promise(
        (resolve,reject)=>{
            console.log(data)
            axios.put(url,JSON.stringify(data))
            .then(res=>{
                console.log("封装信息的的res",res)
                resolve(res.data)
            }).catch(err=>{
                reject(err.data)
            })
        }
    )
}

export function axios_delete(url,data){
    return new Promise(
        (resolve,reject)=>{
            console.log(data)
            axios.delete(url,{params:data})
            .then(res=>{
                console.log("封装信息的的res",res)
                resolve(res.data)
            }).catch(err=>{
                reject(err.data)
            })
        }
    )
}
2)apis.js
/* eslint-disable */
// 接口信息,生成请求方法
// 引入get方法,post方法

import {axios_get,axios_post,axios_delete,axios_put} from '../http/index'  

export const getBookList = p  => axios_get("/app01/books/",p)  
1.1.2 方法二
1)index.js
/* eslint-disable */
// 第一步:实例化axios对象,简单封装
const axios = require('axios');                         // 生成一个axios实例
axios.defaults.baseURL = 'http://192.168.56.100:8000';  // 设置请求后端的URL地址
axios.defaults.timeout = 10000;                         // axios请求超时时间
axios.defaults.withCredentials = true;
axios.defaults.headers['Content-Type'] = 'application/json';        // axios发送数据时使用json格式
axios.defaults.transformRequest = data => JSON.stringify(data);     // 发送数据前进行json格式化


//  第二:设置拦截器
// 
//  请求拦截器(当前端发送请求给后端前进行拦截)
//  例1:请求拦截器获取token设置到axios请求头中,所有请求接口都具有这个功能
//  例2:到用户访问某一个页面,但是用户没有登录,前端页面自动跳转 /login/ 页面
// 
axios.interceptors.request.use(config => {
    // 从localStorage中获取token
    // let token = localStorage.getItem('token');
    // 如果有token, 就把token设置到请求头中Authorization字段中
    // token && (config.headers.Authorization = token);
    return config;
}, error => {
    return Promise.reject(error);
});

//  响应拦截器(当后端返回数据的时候进行拦截)
//  例1:当后端返回状态码是401/403时,跳转到 /login/ 页面
// 
axios.interceptors.response.use(response => {
    // 当响应码是 2xx 的情况, 进入这里
    // debugger
    return response.data;
}, error => {
    // 当响应码不是 2xx 的情况, 进入这里
    // debugger
    return error
});
// 
//  get方法,对应get请求
//  @param {String} url [请求的url地址]
//  @param {Object} params [请求时携带的参数]
// 
export function get(url, params, headers) {
    return new Promise((resolve, reject) => {
        axios.get(url, { params, headers }).then(res => {
            resolve(res)
        }).catch(err => {

            reject(err)
        })
    })
}
//  第三:根据上面分装好的axios对象,封装 get、post、put、delete请求
// 
//  post方法,对应post请求
//  @param {String} url [请求的url地址]
//  @param {Object} params [请求时携带的参数]
// 
export function post(url, params, headers) {
    return new Promise((resolve, reject) => {
        axios.post(url, params, headers).then((res) => {
            resolve(res)
        }).catch((err) => {
            // debugger
            reject(err)
        })
    })
}
export function put(url, params, headers) {
    return new Promise((resolve, reject) => {
        axios.put(url, params, headers).then((res) => {
            resolve(res)
        }).catch((err) => {
            // debugger
            reject(err)
        })
    })
}
export function del(url, params, headers) {
    return new Promise((resolve, reject) => {
        axios.delete(url, { data: params, headers }).then((res) => {
            resolve(res)
        }).catch((err) => {
            // debugger
            reject(err)
        })
    })
}
export default axios;
2)api.js
/* eslint-disable */
import { get, post, put, del } from './index'

export const getBookList = (params, headers) => get("/app01/books/", params, headers)
export const addBook = (params, headers) => post("/app01/books/", params, headers) 
export const editBook = (params, headers) => put("/app01/books/", params, headers) 
export const delBook = (params, headers) => del("/app01/book/", params, headers)

1.2 后端

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',
    'rest_framework',
    'apps.app01',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
  
'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware' ] ROOT_URLCONF = 'django01.urls' CORS_ORIGIN_WHITELIST = ( 'http://127.0.0.1:8080', 'http://localhost:8080', ) CORS_ALLOW_CREDENTIALS = True # 允许携带cookie

2 父子组件传参

2.1 思路

 2.2 总体代码

2.2.1 子组件代码
<template>
    <div>
        <el-dialog title="新增图书" :visible="visible" > 
            <div>
                <span>图书名称:</span> 
                <el-input class='elinput' v-model="data.books_name" ></el-input> 
            </div> 
            <div>
                <span>发布日期:</span> 
                <el-input class='elinput' v-model="data.public_time" ></el-input> 
            </div> 
            <div>
                <span>阅读量:</span> 
                <el-input class='elinput' v-model="data.read" ></el-input> 
            </div> 
            <div>
                <span>评论量:</span> 
                <el-input class='elinput' v-model="data.comment" ></el-input> 
            </div> 
            <el-button @click="cancel">取 消</el-button> 
            <el-button type="primary" @click="addBook" >确 定</el-button> 
        </el-dialog>
    </div>
</template>

<script>
export default {
    props: ['data', 'visible'],
    data() {
        return {

        }
    },
    methods: {
        addBook(){
            this.$emit('update:visible', false)
            this.$emit('save')
        },
        cancel(){
            this.$emit('update:visible', false)
        }
    },
    created() {

    }
}
</script>

<style scoped>
.elinput { 
    width: 220px; 
    height: 40px; 
}
</style>
2.2.2 总页面
<template>
    <div>
        <h1>图书管理系统</h1>

        <div style="margin: 30px;"> 
            <button @click="addNew">新增图书</button> 
            <BookEdit 
            v-show='dialogVisible' 
            :visible.sync='dialogVisible' 
            :data='editData' 
            @save='save' >
            </BookEdit> 
        </div>

        <div>
            <table style="margin:0 auto">
                <tr>
                    <th>图书编号</th>
                    <th>图书名字</th>
                    <th>出版时间</th>
                    <th>阅读数</th>
                    <th>评论数</th>
                    <th>操作</th>
                </tr>
                <tr v-for="(book, index) in books_list" :key="index">
                    <td>{{book.id}}</td>                    
                    <td>{{book.books_name}}</td>
                    <td>{{book.public_time}}</td>
                    <td>{{book.read}}</td>
                    <td>{{book.comment}}</td>
                    <td>
                        <button @click="edit(index)">修改</button>
                        <button @click="del(index)">删除</button>
                    </td>
                </tr>
            </table>
        </div>

    </div>
</template>

<script>

import { getBookList, addBook, editBook, delBook  } from '@/http/apis'
import BookEdit from '@/components/BookEdit'
export default {
    components: { 
        BookEdit 
    },
    data() {
        return {
            dialogVisible: false,
            books_list:[],
            editData: { 
                // 编辑的内容 
                books_name: "", 
                public_time: "", 
                read: 100, 
                comment: 0
            }
        }
    },
    methods: {
        // 1.点击新增图书时初始化数据 
        addNew() { 
            this.editData = { 
                // 初始化 编辑内容 
                books_name: "", 
                public_time: "", 
                read: '', 
                comment: '' 
            }
            this.dialogVisible = true
             // 显示弹框 
        },
        // 2.获取图书列表,获取数据
        get(){
            getBookList().then((data) =>{
                this.books_list = data.books
                console.log(this.books_list)
            })
        },
        // 3.修改或者添加图书 
        save() { 
                // 根据editData中的id判断是更新还是新增 
                // debugger 
                console.log(this.editData) 
                if (this.editData.id) { 
                    // 如果有id, 修改图书 
                    // 修改请求 
                    let params = this.editData 
                    editBook(params).then(res=>{ 
                        console.log(res) 
                        this.get() 
                        }) 
                } 
                else { 
                    // 增加图书 
                    addBook(this.editData).then(res => { 
                        this.get() 
                    }) 
                } 
            },
            // 点击修改弹出修改页面 
            edit(index) { 
                this.editData = JSON.parse(JSON.stringify(this.books_list[index])) 
                // 复制 this.books_list[index] 的数据
                // this.editData = this.books_list[index] 
                this.dialogVisible = true 
            },
        // 删除 
        del(index) { 
            let params = { 
                id: this.books_list[index].id 
            }
            delBook(params).then(res=>{ 
                console.log(res) 
                this.get() 
                }) 
        }
    },
    created() {
        this.get()
    }
}
</script>

<style scoped>

</style>
原文地址:https://www.cnblogs.com/mapel1594184/p/13899460.html