外贸网站建设案例,个人注册登录入口,html设计素材网站,企查查官网查询 续接Django REST Framework#xff0c;使用Vite构建Vue3的前端项目
1.跨域获取后台接口并展示
安装Axios
npm install axios --save
前端查看后端所有定义的接口
// 访问后端定义的可视化Api接口文档
http://ip:8000/docs/
// 定义的学生类信息
http://ip:8000/api/v1… 续接Django REST Framework使用Vite构建Vue3的前端项目
1.跨域获取后台接口并展示
安装Axios
npm install axios --save
前端查看后端所有定义的接口
// 访问后端定义的可视化Api接口文档
http://ip:8000/docs/
// 定义的学生类信息
http://ip:8000/api/v1/students/ 前端对后端发起请求
// 导入 axios
import axios from axios// 页面一加载便获取axios请求script// 获取所有信息const getStudents () {// axios请求axios.get(http://192.168.20.110:8000/api/v1/students/).then((res){// 请求成功console.log(成功,res)}).catch((error){// 请求失败console.log(失败,error)})}// 定义页面加载时自动执行的函数const autoRun () {// 获取所有信息getStudents() }// 调用自动执行函数执行autoRun()
/script
后端配置运行环境 // 或者直接在0.0.0.0:8000下运行
python manage.py runserver 0.0.0.0:8000// 后端开启跨域安装组件
pip install django-cors-headers
// 注册
INSTALLED_APPS[corsheaders
]
// 添加到中间件中
MIDDLEWARE [django.middleware.security.SecurityMiddleware,django.contrib.sessions.middleware.SessionMiddleware,corsheaders.middleware.CorsMiddleware,# 跨域请求django.middleware.common.CommonMiddleware,django.middleware.csrf.CsrfViewMiddleware,django.contrib.auth.middleware.AuthenticationMiddleware,django.contrib.messages.middleware.MessageMiddleware,django.middleware.clickjacking.XFrameOptionsMiddleware,
]
# 跨域配置
# 后端是否支持对 Cookis访问
CORS_ALLOW_CREDENTIALS True
# 白名单地址
CORS_ORIGIN_WHITELIST (http://192.168.20.110:8080,
) 跨域获取所有信息
// 导入 axios
import axios from axios// 添加信息获取提示
import { ElMessage } from element-plus// 页面一加载便获取axios请求script// 获取所有信息const getStudents () {// axios请求axios.get(http://192.168.20.110:8000/api/v1/students/).then((res){// 请求成功// console.log(成功,res)// 判断是否成功if (res.status200){// 成功执行Data.students res.data.results// 将记录总数绑定到分页的totalData.total res.data.countElMessage({message: 数据加载成功,type: success,})}}).catch((error){// 请求失败console.log(失败,error)})}// 定义页面加载时自动执行的函数const autoRun () {// 获取所有信息getStudents() }// 调用自动执行函数执行autoRun()
/script 分页优化
script langts setup
import { ref, reactive } from vue
import {More,Edit,Delete} from element-plus/icons-vue
import axios from axios
// 添加信息获取提示
import { ElMessage } from element-plus// 定义存储集合
var Data reactive({// 定义输入的查询条件q_str: ref(),// 存储从后台获取的所有院系信息FacultyOptions: reactive([{value:1,label:计算机学院},{value:2,label:外语学院},]),// 存储选择院系后的值FacultySelected: ref(),// 存储从后台获取的所有专业信息MajorOptions: reactive([{value:1,label:计算机专业},{value:2,label:外语专业},]),// 存储选择专业后的值MajorSelected: ref(),// 表格区域定义students: reactive([]),// 分页// 当前页currentsPage: ref(1),// 每页显示的数据量pageSize: ref(15),// 总数据量所有记录条数total: ref(0),
});// 分页中修改每页的pageSize
const handleSizeChange(size: any){// 修改记录条数Data.pageSize size// 重新获取所有信息getStudents()
}// 分页中修改每页的currentsPage
const handleCurrentChange(page: any){// 修改当前页Data.currentsPage page// 重新获取所有信息getStudents()
}// 前后端交互
// 获取所有信息
const getStudents () {// 定义一个集合存储分页参数let params {page: Data.currentsPage,size: Data.pageSize}// axios请求axios.get(http://192.168.20.110:8000/api/v1/students/,{params:params}).then((res){// 请求成功console.log(成功,res)// 判断是否成功if (res.status200){// 成功执行Data.students res.data.results// 将记录总数绑定到分页的totalData.total res.data.count// 成功提示ElMessage({message: 数据加载成功,type: success,})}}).catch((error){// 请求失败console.log(失败,error)})}// 定义页面加载时自动执行的函数const autoRun () {// 获取所有信息getStudents() }// 调用自动执行函数执行autoRun() /script
院系/专业信息展示优化
学生表里只记录了专业的id专业表里记录了院系的id要使在学生明细表中展示专业和院系信息则需要在后端序列化专业表和院系表
// serializer.py
# 导入模块
# models中的类与接口转换
from rest_framework import serializers
from studentweb.models import *# 学院序列化类
class FacultySerializer(serializers.ModelSerializer):class Meta:model Facultyfields __all__# 专业序列化类
class MajorSerializer(serializers.ModelSerializer):# 序列化学院idfaculty FacultySerializer()class Meta:model Majorfields __all__# 学生序列化类
class StudentSerializer(serializers.ModelSerializer):# 序列化专业信息major MajorSerializer()class Meta:model Studentfields __all__
// 专业的名字:major.name
// 院系的名字:major.faculty.name
{sno: 950001,major: {id: 2,faculty: {id: 1,name: 计算机学院},name: 计算机网络},name: 王晓宇,gender: 男,birthday: 2022-03-01,mobile: 13099881122,email: wangxiaoyuqq.com,address: 上海市闵行区春都路88号,image: }, 表格绑定展示
// 更改前端表格展示数据el-table-column propmajor.faculty.name label院系 aligncenter width120 /el-table-column propmajor.name label专业 aligncenter width120 /
表格过长数据处理
// 过长信息不展示完全使用...显示// 标签添加 :show-overflow-tooltiptrue属性
2.Axios模块化请求
request脚本实现
// 新建 /src/utils/request.ts
// 封装 axios代码实现模块化// 1.导入
import axios from axios
// 2.创建一个Axios的app
const request axios.create({// 定义基本 URLbaseURL: http://192.168.__.___:8000/api/v1/,// 设置超时timeout: 5000,})// 3.暴露
export default request // 添加request.ts配置的axiosscript langts setup
// 导入request
import request from ../../utils/request;
import { ref, reactive } from vue
import {More,Edit,Delete} from element-plus/icons-vue// 添加信息获取提示
import { ElMessage } from element-plus// 定义存储集合
var Data reactive({// 定义输入的查询条件q_str: ref(),// 存储从后台获取的所有院系信息FacultyOptions: reactive([{value:1,label:计算机学院},{value:2,label:外语学院},]),// 存储选择院系后的值FacultySelected: ref(),// 存储从后台获取的所有专业信息MajorOptions: reactive([{value:1,label:计算机专业},{value:2,label:外语专业},]),// 存储选择专业后的值MajorSelected: ref(),// 表格区域定义students: reactive([]),// 分页// 当前页currentsPage: ref(1),// 每页显示的数据量pageSize: ref(15),// 总数据量所有记录条数total: ref(0),
});// 分页中修改每页的pageSize
const handleSizeChange(size: any){// 修改记录条数Data.pageSize size// 重新获取所有信息getStudents()
}// 分页中修改每页的currentsPage
const handleCurrentChange(page: any){// 修改当前页Data.currentsPage page// 重新获取所有信息getStudents()
}// 前后端交互
// 获取所有信息
const getStudents () {// 定义一个集合存储分页参数let params {page: Data.currentsPage,size: Data.pageSize}// axios请求request.get(students/,{params:params}).then((res){// 请求成功console.log(成功,res)// 判断是否成功if (res.status200){// 成功执行Data.students res.data.results// 将记录总数绑定到分页的totalData.total res.data.count// 成功提示ElMessage({message: 数据加载成功,type: success,})}}).catch((error){// 请求失败console.log(失败,error)})}// 定义页面加载时自动执行的函数const autoRun () {// 获取所有信息getStudents() }// 调用自动执行函数执行autoRun() /script
Api数据集及请求类型以及url优化 接口实现
// 新建 /src/api/students.ts(majors.ts/facultys.ts)// 导入
import request from ../utils/request;// RESTFUL --- 6个接口【获取所有添加获取某一个修改删除】// 获取所有
const getAll (params ?: any) {// requestreturn request({method: GET,url: /students,params,})
}// 添加
const add (data: any) {// requestreturn request({method: POST,url: /students,data,})
}
// 获取单一数据
const getOne(id: any) {// requestreturn request({method: GET,url: /students/${id},})
}
// 修改
const edit(id: any, data: any) {// requestreturn request({method: PUT,url: /students/${id},data})
}
// 删除
const del (id: any) {// requestreturn request({method: DELETE,url: /students/${id},})
}
export default {getAll,add,getOne,edit,del,// 也可以直接在此处定义其他的 api
}
// 新建 index.ts用于导入所有api// 导入所有
import studentApi from ./students
import majorsApi from ./majors
import facultysApi from ./facultys// 封装并发布
export default {studentApi,majorsApi,facultysApi,
} // 使用 上述定义的接口script langts setup
import { ref, reactive } from vue
import {More,Edit,Delete} from element-plus/icons-vue
// 导入API
import indexApi from ../../api/index
// 添加信息获取提示
import { ElMessage } from element-plus// 定义存储集合
var Data reactive({// 定义输入的查询条件q_str: ref(),// 存储从后台获取的所有院系信息FacultyOptions: reactive([{value:1,label:计算机学院},{value:2,label:外语学院},]),// 存储选择院系后的值FacultySelected: ref(),// 存储从后台获取的所有专业信息MajorOptions: reactive([{value:1,label:计算机专业},{value:2,label:外语专业},]),// 存储选择专业后的值MajorSelected: ref(),// 表格区域定义students: reactive([]),// 分页// 当前页currentsPage: ref(1),// 每页显示的数据量pageSize: ref(15),// 总数据量所有记录条数total: ref(0),
});// 分页中修改每页的pageSize
const handleSizeChange(size: any){// 修改记录条数Data.pageSize size// 重新获取所有信息getStudents()
}// 分页中修改每页的currentsPage
const handleCurrentChange(page: any){// 修改当前页Data.currentsPage page// 重新获取所有信息getStudents()
}// 前后端交互
// 获取所有信息
const getStudents () {// 定义一个集合存储分页参数let params {page: Data.currentsPage,size: Data.pageSize}// axios请求indexApi.studentApi.getAll(params).then((res){// 请求成功console.log(成功,res)// 判断是否成功if (res.status200){// 成功执行Data.students res.data.results// 将记录总数绑定到分页的totalData.total res.data.count// 成功提示ElMessage({message: 数据加载成功,type: success,})}}).catch((error){// 请求失败console.log(失败,error)})}// 定义页面加载时自动执行的函数const autoRun () {// 获取所有信息getStudents() }// 调用自动执行函数执行autoRun() /scripttemplate!-- 1.顶部查询区域 stypledisplay: flax;横向显示--el-form :inlinetrue classdemo-form-inlineel-form-item label查询条件el-input v-modelData.q_str placeholder请输入查询条件 clearable //el-form-item!-- 动态获取院系信息 --el-form-item label院系el-select v-modelData.FacultySelected placeholder请选择院系el-option v-foritem in Data.FacultyOptions:keyitem.value:labelitem.label:valueitem.value /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-item!-- 动态获取专业信息 --el-form-item label专业el-select v-modelData.MajorSelected placeholder请选择专业el-option v-foritem in Data.MajorOptions:keyitem.value:labelitem.label:valueitem.value /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-item!-- el-form-item labelActivity timeel-date-pickertypedateplaceholderPick a dateclearable//el-form-item --el-form-itemel-button typeprimary!-- 引入方法1 --el-iconcomponent classicons isSearch/component/el-iconspan查询/span/el-buttonel-button typeprimary!-- 引入方法2 --el-iconFinished //el-iconspan全部/span/el-buttonel-button typeprimaryel-iconPointer //el-iconspan添加/span/el-button/el-form-item
/el-form!-- 2.表格信息部分 --el-table :dataData.students stripe border stylewidth: 100% :header-cell-style{ backgroundColor:#409EFF,color:#FFF,FontSize:14px }el-table-column label序号 typeindex aligncenter width60 /el-table-column propsno label学号 aligncenter width80 /el-table-column propname label姓名 aligncenter width80 /el-table-column propgender label性别 aligncenter width80 /el-table-column propbirthday label出生日期 aligncenter width180 /el-table-column propmajor.faculty.name label院系 aligncenter width120 :show-overflow-tooltiptrue/el-table-column propmajor.name label专业 aligncenter width120 /el-table-column propmobile label电话 aligncenter width140 /el-table-column propemail labelEmail aligncenter width180 :show-overflow-tooltiptrue /el-table-column propaddress label地址 aligncenter :show-overflow-tooltiptrue/!-- 按钮区域 --el-table-column label操作 aligncenterel-button typeprimary :iconMore circle sizesmall/el-button typewarning :iconEdit circle sizesmall/el-button typedanger :iconDelete circle sizesmall//el-table-column/el-table!-- 3.分页 currentPage4当前页 pageSize4每页大小 total记录条数 handleSizeChange改变每页大小 handleCurrentChange改变当前页 --el-pagination stylemargin-top: 28px;backgroundv-model:current-pageData.currentsPagev-model:page-sizeData.pageSize:page-sizes[10,12,15,17,20,25,40,50]layouttotal, sizes, prev, pager, next, jumper:totalData.totalsize-changehandleSizeChangecurrent-changehandleCurrentChange/
/templatestyle scoped
.demo-form-inline .el-input {--el-input-width: 220px;
}.demo-form-inline .el-select {--el-select-width: 220px;
}/style院系联级下拉框实现
// 1.重新定义FacultyOptions 结构
// 定义存储集合
var Data reactive({// 存储从后台获取的所有院系信息FacultyOptions: reactive([{ id:,name:}, ])
}),
// 定义页面加载时自动执行的函数// 获取所有信息
const getStudents () {// 定义一个集合存储分页参数let params {page: Data.currentsPage,size: Data.pageSize}// axios请求indexApi.studentApi.getAll(params).then((res){// 请求成功console.log(成功,res)// 判断是否成功if (res.status200){// 成功执行Data.students res.data.results// 将记录总数绑定到分页的totalData.total res.data.count// 成功提示ElMessage({message: 数据加载成功,type: success,})}}).catch((error){// 请求失败console.log(失败,error)})}// 2.获取所有院系信息
const getFacultys () {// 请求indexApi.facultysApi.getAll().then((res){// console.log(res.data)Data.FacultyOptions res.data.results;})}// 3.定义页面加载时自动执行的函数
const autoRun () {// 获取所有信息getStudents() // 获取院系填充信息getFacultys()
}// 调用自动执行函数执行
autoRun() 4.更改院系标签值
!-- 动态获取院系信息 clearable filterable 添加过滤--el-form-item label院系el-select v-modelData.FacultySelected placeholder请选择院系 clearable filterableel-option v-foritem in Data.FacultyOptions:keyitem.id:labelitem.name:valueitem.id /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-item
专业联动院系下拉框实现
script langts setup
import { ref, reactive } from vue
import {More,Edit,Delete} from element-plus/icons-vue
// 导入API
import indexApi from ../../api/index
// 添加信息获取提示
import { ElMessage } from element-plus// 定义存储集合
var Data reactive({// 定义输入的查询条件q_str: ref(),// 存储从后台获取的所有院系信息FacultyOptions: reactive([{ id:,name:}, ]),// 存储选择院系后的值FacultySelected: ref(),// 存储从后台获取的所有专业信息MajorOptions: reactive([{id: ,name: },]),// 存储选择专业后的值MajorSelected: ref(),// 前后端交互// 获取所有院系信息
const getFacultys () {// 请求indexApi.facultysApi.getAll().then((res){// console.log(res.data)Data.FacultyOptions res.data.results;})
};
// 获取院系对应的专业信息
const getMajors () {// 准备条件let params {// http://192.168.20.110:8000/api/v1/majors/?namefaculty1name:,faculty: Data.FacultySelected}// 请求indexApi.majorsApi.getAll(params).then((res){// console.log(res.data.results)Data.MajorOptions res.data.results;})
};// 定义页面加载时自动执行的函数
const autoRun () {// 获取所有信息getStudents() // 获取院系填充信息getFacultys()
}
// 调用自动执行函数执行
autoRun() /scripttemplate!-- 动态获取院系信息 --el-form-item label院系el-select v-modelData.FacultySelected placeholder请选择院系 clearable filterable changegetMajorsel-option v-foritem in Data.FacultyOptions:keyitem.id:labelitem.name:valueitem.id /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-item!-- 动态获取专业信息 --el-form-item label专业el-select v-modelData.MajorSelected placeholder请选择专业el-option v-foritem in Data.MajorOptions:keyitem.id:labelitem.name:valueitem.id //el-select/el-form-itemel-form-itemel-button typeprimary!-- 引入方法1 --el-iconcomponent classicons isSearch/component/el-iconspan查询/span/el-buttonel-button typeprimary!-- 引入方法2 --el-iconFinished //el-iconspan全部/span/el-buttonel-button typeprimaryel-iconPointer //el-iconspan添加/span/el-button/el-form-item
/el-form
/templatestyle scoped
.demo-form-inline .el-input {--el-input-width: 220px;
}.demo-form-inline .el-select {--el-select-width: 220px;
}/style
// 后端注意 filter.py Major筛选类的定义# Major的filter类
class MajorFilter(FilterSet):# 重写支持模糊匹配的字段name filters.CharFilter(field_namename, lookup_expricontains)class Meta:model Majorfields (name,faculty)
面向对象思维优化Api接口
// 新建 api/apibase.ts 定义基础类// 导入
import request from ../utils/request;export default class Apibase {// 定义属性public name : string;// 构造函数(器)constructor(name : string) {this.name name;}// 方法public getAll (params?: any) {// request请求return request({method: GET,url: ${this.name},params,})}// 添加public add (data: any) {// requestreturn request({method: POST,url: ${this.name},data,})}// 获取单一数据public getOne(id: any) {// requestreturn request({method: GET,url: ${this.name}/${id},})}// 修改public edit(id: any, data: any) {// requestreturn request({method: PUT,url: ${this.name}/${id},data})}// 删除public del (id: any) {// requestreturn request({method: DELETE,url: ${this.name}/${id},})}
}// 调用基础类 api/index.ts// 导入基础类
import Apibase from ./apibase// 实例化对象
let studentApi new Apibase(students);
let majorsApi new Apibase(majors);
let facultysApi new Apibase(facultys);// 封装并发布
export default {studentApi,majorsApi,facultysApi,
}// 删除/注销 facultys.ts、majors.ts、students.ts
联级信息过滤实现查询和展示全部的功能
// 输入关键字筛选实现// 后端输入筛选字段设置
# 学生视图
class StudentViewSet(ModelViewSet):create:创建院系信息retrieve:获取院系信息详情数据update:完整更新院系信息partial_update:部分更新院系信息destroy:删除院系信息list:获取所有院系信息queryset Student.objects.all()serializer_class StudentSerializer# 分页pagination_class MyPageNumberPaginationfilter_class StudentFilter# 指定查找匹配的字段search_fields (sno,name,mobile,email,address)// 前端获取所有信息中新增search筛选条件// 获取所有信息
const getStudents () {// 定义一个集合存储分页参数let params {page: Data.currentsPage,size: Data.pageSize,// 一对多,可以匹配多个字段 ?search...search: Data.q_str}// axios请求indexApi.studentApi.getAll(params).then((res){// 请求成功// console.log(成功,res)// 判断是否成功if (res.status200){// 成功执行Data.students res.data.results// 将记录总数绑定到分页的totalData.total res.data.count// 成功提示ElMessage({message: 数据加载成功,type: success,})}}).catch((error){// 请求失败console.log(失败,error)})
};// 绑定点击事件
el-button typeprimary clickgetStudentsel-iconcomponent classicons isSearch/component/el-iconspan查询/span
/el-button
// 点击全部按钮查询实现
// 定义函数
// 点击全部 清楚删选条件
const listAllStudent () {// 清空查询条件Data.q_str // 重新获取所有信息getStudents()
}// 绑定按钮el-button typeprimary clicklistAllStudentel-iconFinished //el-iconspan全部/span
/el-button
# 院系筛选条件 http://ip/api/v1/students/?snonamemobilemajorfaculty5# 更改后端代码 filter.pyclass StudentFilter(FilterSet):# 重写支持模糊匹配的字段sno filters.CharFilter(field_namesno, lookup_expricontains)name filters.CharFilter(field_namename, lookup_expricontains)mobile filters.CharFilter(field_namemobile, lookup_expricontains)# 添加专业字段匹配major filters.CharFilter(field_namemajor)# 专业表跳转到学院表faculty filters.CharFilter(field_namemajor__faculty)class Meta:model Student# 新增专业字段fields (sno,name,mobile,major)// 前端绑定
// 获取所有信息
const getStudents () {// 定义一个集合存储分页参数let params {page: Data.currentsPage,size: Data.pageSize,// 一对多,可以匹配多个字段 ?search...search: Data.q_str,// 添加院系字段 提供学院的 keyfaculty: Data.FacultySelected,}// axios请求indexApi.studentApi.getAll(params).then((res){// 请求成功// console.log(成功,res)// 判断是否成功if (res.status200){// 成功执行Data.students res.data.results// 将记录总数绑定到分页的totalData.total res.data.count// 成功提示ElMessage({message: 数据加载成功,type: success,})}}).catch((error){// 请求失败console.log(失败,error)})
};// 点击全部 清楚删选条件
const listAllStudent () {// 清空查询条件Data.q_str // 清空院系条件Data.FacultySelected // 重新获取所有信息getStudents()
}
// 专业信息筛选// 获取所有信息
const getStudents () {// 定义一个集合存储分页参数let params {page: Data.currentsPage,size: Data.pageSize,// 一对多,可以匹配多个字段 ?search...search: Data.q_str,// 添加院系字段 提供学院的 keyfaculty: Data.FacultySelected,// 添加专业筛选major: Data.MajorSelected}// axios请求indexApi.studentApi.getAll(params).then((res){// 请求成功// console.log(成功,res)// 判断是否成功if (res.status200){// 成功执行Data.students res.data.results// 将记录总数绑定到分页的totalData.total res.data.count// 成功提示ElMessage({message: 数据加载成功,type: success,})}}).catch((error){// 请求失败console.log(失败,error)})
};// 点击全部 清楚删选条件
const listAllStudent () {// 清空查询条件Data.q_str Data.FacultySelected Data.MajorSelected // 重新获取所有信息getStudents()
}配置Vue实例的全局变量
// 挂载全局对象
// Vue2.0--Vue.prototype.$api api
// Vue3.0--app.config.globalProperties.api api
// main.ts定义全局变量
// 导入所有数据集的 Api
import Apibase from ./api/apibase
// 将 Api挂载到全局的属性
app.config.globalProperties.api Apibase
// 全局定义Api使用 info.vue
import { ref, reactive, getCurrentInstance } from vue
// 获取当前实例
const indexApi (getCurrentInstance() as any).proxy.api;
请求拦截器和响应拦截器 请求拦截器 自动添加身份验证的token // 请求拦截器 utils/request.ts// 封装 axios代码实现模块化
// 1.导入
import axios from axios
// 2.创建一个Axios的app
const request axios.create({// 定义基本 URLbaseURL: http://192.168.20.110:8000/api/v1/,// 设置超时timeout: 5000,})// 请求拦截器发请求request基于上边创建的request
request.interceptors.request.use((config: any) {// 获取本地loalstorage中的totenlet token localStorage.getItem(toten)// 判断是否有tokenif(token) {// 如果有token就在请求头中添加tokenconfig.headers.common[token] token}// 返回return config},(error: any) {Promise.reject(error);},
);
// 响应拦截器反馈response 基于上边创建的request
request.interceptors.response.use();
// 3.暴露
export default request // 后端配置 settings.py
CORS_ALLOW_HEADERS (token,jwt,accept,accept-encoding,authorization,content-type,dnt,origin,user-agent,x-csrftoken,x-requested-with,
)
响应拦截器 自动提示所有的请求报错信息
// 封装 axios代码实现模块化
// 1.导入
import axios from axios
import {ElMessage} from element-plus
// 2.创建一个Axios的app
const request axios.create({// 定义基本 URLbaseURL: http://192.168.20.110:8000/api/v1/,// 设置超时timeout: 5000,})// 请求拦截器发请求request基于上边创建的request
request.interceptors.request.use((config: any) {// 获取本地loalstorage中的totenlet token localStorage.getItem(toten)// 判断是否有tokenif(token) {// 如果有token就在请求头中添加tokenconfig.headers.common[token] token}// 返回return config},(error: any) {Promise.reject(error);},
);// 响应拦截器反馈response 基于上边创建的request
request.interceptors.response.use((response: any) response,(error: any) {if (error error.response) {error.data {};switch (error.response.status) {case 400:error.data.msg 错误请求;ElMessage.error(error.data.msg)breakcase 401:error.data.msg 未授权请重新登录;ElMessage.error(error.data.msg)breakcase 403:error.data.msg 拒绝访问;ElMessage.error(error.data.msg)breakcase 404:error.data.msg 请求错误,未找到该资源;ElMessage.error(error.data.msg)breakcase 405:error.data.msg 请求方法未允许;ElMessage.error(error.data.msg)breakcase 408:error.data.msg 请求超时;ElMessage.error(error.data.msg)breakcase 500:error.data.msg 服务器端出错;ElMessage.error(error.data.msg)breakcase 501:error.data.msg 网络未实现;ElMessage.error(error.data.msg)breakcase 502:error.data.msg 网络错误;ElMessage.error(error.data.msg)breakcase 503:error.data.msg 服务不可用;ElMessage.error(error.data.msg)breakcase 504:error.data.msg 网络超时;ElMessage.error(error.data.msg)breakcase 505:error.data.msg http版本不支持该请求;ElMessage.error(error.data.msg)breakdefault:error.data.msg 连接错误${error.response.status};ElMessage.error(error.data.msg)}} else {error.data.msg 连接到服务器失败;ElMessage.error(error.data.msg)}return Promise.reject(error);}
);
// 3.暴露
export default request 3.信息弹出层的布局和数据填充实现
信息弹出层实现
// 定义存储集合
var Data reactive({// 定义输入的查询条件q_str: ref(),// 存储从后台获取的所有院系信息FacultyOptions: reactive([{ id:,name:}, ]),// 存储选择院系后的值FacultySelected: ref(),// 存储从后台获取的所有专业信息MajorOptions: reactive([{id: ,name: },]),// 存储选择专业后的值MajorSelected: ref(),// 表格区域定义students: reactive([]),// 分页// 当前页currentsPage: ref(1),// 每页显示的数据量pageSize: ref(15),// 总数据量所有记录条数total: ref(0),// 弹出层-----dialogFormVisible: ref(false),
});
// 弹出层顶部添加按钮
const addStudent () {Data.dialogFormVisible true;
}!-- 4.弹出层 --el-dialog v-modelData.dialogFormVisible title学生信息 width40%el-form :inlinetrueel-form-item label学号:el-input placeholder请输入 //el-form-itemel-form-item label姓名:el-input placeholder请输入 //el-form-itemel-form-item label性别: stylewidth: 20%;el-select placeholder请选择el-option label男 valueshanghai /el-option label女 valuebeijing //el-select/el-form-item!-- 动态获取院系信息 --el-form-item stylewidth: 32%; label院系:el-select v-modelData.FacultySelected placeholder请选择院系 clearable filterable changegetMajorsel-option v-foritem in Data.FacultyOptions:keyitem.id:labelitem.name:valueitem.id /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-item!-- 动态获取专业信息 --el-form-item stylewidth: 32%; label专业:el-select v-modelData.MajorSelected placeholder请选择专业 clearable filterableel-option v-foritem in Data.MajorOptions:keyitem.id:labelitem.name:valueitem.id /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-itemel-form-item label电话:el-input placeholder请输入 //el-form-itemel-form-item label邮箱:el-input placeholder请输入 //el-form-item!-- 日期 --el-form-item stylewidth: 32%; label出生日期:el-date-pickertypedateplaceholder请选择日期clearable//el-form-itemel-form-item stylewidth: 57%; label家庭住址:el-input typetextarea //el-form-item/el-formtemplate #footerdiv classdialog-footerel-button取消/el-buttonel-button提交/el-button/div/template/el-dialog 优化弹出层展示实现 // 弹出层定义
// 定义存储集合
var Data reactive({// 弹出层-----dialogFormVisible: ref(false),// 定义弹出层标题layerTitle: ref(),// 定义表单双向绑定的值studentform: reactive({sno: ref(),name: ref(),gender: ref(),birthday: ref(),faculty: reactive({// 存储从后台获取的所有院系信息FacultyOptions: reactive([{ id:,name:}, ]),// 存储选择院系后的值FacultySelected: ref(),}),major: reactive({// 存储从后台获取的所有专业信息MajorOptions: reactive([{id: ,name: },]),// 存储选择专业后的值MajorSelected: ref(),}),mobile: ref(),email: ref(),address: ref(),})
})// 弹出层顶部添加按钮
const addStudent () {Data.dialogFormVisible true;// 修改标题Data.layerTitle 【添加学生信息】
}// *************************
// 获取所有院系信息
const getFacultysTC () {// 请求indexApi.facultysApi.getAll().then((res){// console.log(res.data)Data.studentform.faculty.FacultyOptions res.data.results;})
};
// 获取院系对应的专业信息
const getMajorsTC () {// 准备条件let params {// http://192.168.20.110:8000/api/v1/majors/?namefaculty1name:,faculty: Data.studentform.faculty.FacultySelected}// 请求indexApi.majorsApi.getAll(params).then((res){// console.log(res.data.results)Data.studentform.major.MajorOptions res.data.results;})
};// 关闭弹出层
const closeLayer () {Data.dialogFormVisible false;
}// 定义页面加载时自动执行的函数
const autoRun () {// 获取所有信息getStudents() // 获取院系填充信息getFacultys()// 获取弹出层院系填充信息getFacultysTC()
}
// 调用自动执行函数执行
autoRun() // 动态标题绑定
!-- 标题 --
template #titlediv stylefont-size: 18px; color: #409eff; font-weight: bold; text-align: left{{ Data.layerTitle}}/div
/template// 表单数据显示
!-- 4.弹出层 --el-dialog v-modelData.dialogFormVisible width40%!-- 标题 --template #titlediv stylefont-size: 18px; color: #409eff; font-weight: bold; text-align: left{{ Data.layerTitle}}/div/template!--先在form上绑定 Data.studentform --el-form v-modelData.studentform :inlinetrue!-- 然后在每一个值上进行绑定 --el-form-item label学号:el-input v-modelData.studentform.sno placeholder请输入 //el-form-itemel-form-item label姓名:el-input v-modelData.studentform.name placeholder请输入 //el-form-itemel-form-item label性别: stylewidth: 20%;el-select v-modelData.studentform.gender placeholder请选择el-option label男 valueshanghai /el-option label女 valuebeijing //el-select/el-form-item!-- 动态获取院系信息 --el-form-item stylewidth: 32%; label院系:el-select v-modelData.studentform.faculty.FacultySelected placeholder请选择院系 clearable filterable changegetMajorsTCel-option v-foritem in Data.studentform.faculty.FacultyOptions:keyitem.id:labelitem.name:valueitem.id /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-item!-- 动态获取专业信息 --el-form-item stylewidth: 32%; label专业:el-select v-modelData.studentform.major.MajorSelected placeholder请选择专业 clearable filterableel-option v-foritem in Data.studentform.major.MajorOptions:keyitem.id:labelitem.name:valueitem.id /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-itemel-form-item label电话:el-input v-modelData.studentform.mobile placeholder请输入 //el-form-itemel-form-item label邮箱:el-input v-modelData.studentform.email placeholder请输入 //el-form-item!-- 日期 --el-form-item stylewidth: 32%; label出生日期:el-date-pickertypedateplaceholder请选择日期clearablev-modelData.studentform.birthday//el-form-itemel-form-item stylewidth: 57%; label家庭住址:el-input v-modelData.studentform.address typetextarea //el-form-item/el-formtemplate #footerdiv classdialog-footerel-button clickcloseLayer取消/el-buttonel-button提交/el-button/div/template/el-dialog三种状态加载弹出层实现
var Data reactive({// 弹出层中表单元素是否可编辑定义isView: ref(false), // 是否为查看状态 默认不是sEdit: ref(false), // 是否为编辑状态 默认不是
})// 查看信息
const viewStudent (row: any) {Data.dialogFormVisible true;// 修改标题Data.layerTitle 【查看学生信息】// 编辑状态Data.isEdit false// 查看状态Data.isView true
}// 编辑信息const editStudent (row: any) {Data.dialogFormVisible true;// 修改标题Data.layerTitle 【编辑学生信息】// 编辑状态Data.isEdit true// 查看状态Data.isView false
}!-- 按钮区域 --
el-table-column label操作 aligncenterel-button typeprimary :iconMore clickviewStudent circle sizesmall/el-button typewarning :iconEdit clickeditStudent circle sizesmall/el-button typedanger :iconDelete circle sizesmall/
/el-table-column!-- 4.弹出层 --el-dialog v-modelData.dialogFormVisible width40%!-- 标题 --template #titlediv stylefont-size: 18px; color: #409eff; font-weight: bold; text-align: left{{ Data.layerTitle}}/div/template!--先在form上绑定 Data.studentform --el-form v-modelData.studentform :inlinetrue!-- 然后在每一个值上进行绑定 --el-form-item label学号:!-- 设置字段是否可编辑 :disabledData.isEdit || Data.isView 若一个为 True则输入框即为禁用状态 --el-input v-modelData.studentform.sno :disabledData.isEdit || Data.isView placeholder请输入 //el-form-itemel-form-item label姓名:el-input v-modelData.studentform.name :disabledData.isView placeholder请输入 //el-form-itemel-form-item label性别: stylewidth: 20%;el-select v-modelData.studentform.gender :disabledData.isView placeholder请选择el-option label男 valueshanghai /el-option label女 valuebeijing //el-select/el-form-item!-- 动态获取院系信息 --el-form-item stylewidth: 32%; label院系:el-select v-modelData.studentform.faculty.FacultySelected :disabledData.isView placeholder请选择院系 clearable filterable changegetMajorsTCel-option v-foritem in Data.studentform.faculty.FacultyOptions:keyitem.id:labelitem.name:valueitem.id /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-item!-- 动态获取专业信息 --el-form-item stylewidth: 32%; label专业:el-select v-modelData.studentform.major.MajorSelected :disabledData.isView placeholder请选择专业 clearable filterableel-option v-foritem in Data.studentform.major.MajorOptions:keyitem.id:labelitem.name:valueitem.id /!-- el-option labelZone one valueshanghai /el-option labelZone two valuebeijing / --/el-select/el-form-itemel-form-item label电话:el-input v-modelData.studentform.mobile :disabledData.isView placeholder请输入 //el-form-itemel-form-item label邮箱:el-input v-modelData.studentform.email :disabledData.isView placeholder请输入 //el-form-item!-- 日期 --el-form-item stylewidth: 32%; label出生日期:el-date-pickertypedateplaceholder请选择日期clearablev-modelData.studentform.birthday:disabledData.isView//el-form-itemel-form-item stylewidth: 57%; label家庭住址:el-input v-modelData.studentform.address :disabledData.isView typetextarea //el-form-item/el-formtemplate #footerdiv classdialog-footerel-button clickcloseLayer取消/el-buttonel-button v-show!Data.isView提交/el-button/div/template/el-dialog
实现填充数据到弹出层
var Data reactive({// 定义表单双向绑定的值studentform: reactive({sno: ref(),name: ref(),gender: ref(),birthday: ref(),faculty: ref(),major: ref(),mobile: ref(),email: ref(),address: ref(),}),// 弹出层中表单元素是否可编辑定义isView: ref(false), // 是否为查看状态 默认不是isEdit: ref(false), // 是否为编辑状态 默认不是
});// 查看学生信息
const viewStudent (row: any) {// 设定标题Data.layerTitle 【查看学生信息】;// 设为查看Data.isView true;// 可见Data.dialogFormVisible true;// 当前行赋值为studentForm -- 深拷贝Data.studentform JSON.parse(JSON.stringify(row));
};// 编辑学生信息
const editStudent (row: any) {// 设定标题Data.layerTitle 【编辑学生信息】;// 设为编辑Data.isEdit true;// 可见Data.dialogFormVisible true;// 当前行赋值为studentForm -- 深拷贝console.log(row)// Data.studentform rowData.studentform JSON.parse(JSON.stringify(row));
};// 关闭弹出层
const closeLayer () {Data.dialogFormVisible false;// 编辑和查看设置为FalseData.isEdit false;Data.isView false;// 初始化表单Data.studentform.sno ;Data.studentform.name ;Data.studentform.gender ;Data.studentform.birthday ;Data.studentform.major ;Data.studentform.faculty ;Data.studentform.mobile ;Data.studentform.email ;Data.studentform.address ;
}!-- 按钮区域 --
el-table-column label操作 aligncentertemplate #defaultscopeel-button typeprimary :iconMore clickviewStudent(scope.row) circle sizesmall/el-button typewarning :iconEdit clickeditStudent(scope.row) circle sizesmall/el-button typedanger :iconDelete circle sizesmall//template
/el-table-column!-- 弹出层 --
el-dialog v-modelData.dialogFormVisible width40% closecloseLayer!-- 标题部分 --template #titlediv stylefont-size: 18px; color: #409eff; font-weight: bold; text-align: left{{ Data.layerTitle }}/div/templateel-form:modelData.studentform:inlinetruelabel-width100pxrefstudentFormRefel-form-item label学号: propsnoel-inputv-modelData.studentform.sno:disabledData.isEdit || Data.isView:suffix-iconEditplaceholder请输入//el-form-itemel-form-item label姓名: propnameel-inputv-modelData.studentform.name:disabledData.isView:suffix-iconEditplaceholder请输入//el-form-itemel-form-item label性别: stylewidth: 43%; propgenderel-selectv-modelData.studentform.gender:disabledData.isViewplaceholder请选择el-option label男 value男 /el-option label女 value女 //el-select/el-form-itemel-form-item label出生日期: propbirthday el-date-pickerv-modelData.studentform.birthdaytypedateplaceholder选择日期stylewidth: 212px:disabledData.isViewvalue-formatYYYY-MM-DD/el-date-picker/el-form-itemel-form-item label电话: propmobileel-inputv-modelData.studentform.mobile:disabledData.isView:suffix-iconEditplaceholder请输入//el-form-itemel-form-item label邮箱: propemailel-inputv-modelData.studentform.email:disabledData.isView:suffix-iconEditplaceholder请输入//el-form-itemel-form-item label家庭住址: propaddressel-inputv-modelData.studentform.address:suffix-iconEditstylewidth: 555px:disabledData.isViewplaceholder请输入/el-input/el-form-item/el-formtemplate #footerspan classdialog-footerel-button typeprimary v-show!Data.isView提交/el-buttonel-button clickcloseLayer取消/el-button/span/template/el-dialog
Cascader级联选择器使用
// *******后端取消默认分页 views.py*******# 学院视图
class FacultyViewSet(ModelViewSet):queryset Faculty.objects.all()serializer_class FacultySerializer# 取消默认分页pagination_class None# 专业视图
class MajorViewSet(ModelViewSet):queryset Major.objects.all()print(queryset)serializer_class MajorSerializer# 取消默认分页pagination_class None // *********前端*********var Data reactive({
// 弹出层级联选择器定义
layerFacultyMajor: reactive([]),
// 弹出层选中的专业
layerMajorSelected: ref(),
})// 查看学生信息
const viewStudent (row: any) {// 设定标题Data.layerTitle 【查看学生信息】;// 设为查看Data.isView true;// 可见Data.dialogFormVisible true;// 当前行赋值为studentForm -- 深拷贝Data.studentform JSON.parse(JSON.stringify(row));Data.layerMajorSelected row.major.id
};// 编辑学生信息
const editStudent (row: any) {// 设定标题Data.layerTitle 【编辑学生信息】;// 设为编辑Data.isEdit true;// 可见Data.dialogFormVisible true;// 当前行赋值为studentForm -- 深拷贝console.log(row)// Data.studentform rowData.studentform JSON.parse(JSON.stringify(row));Data.layerMajorSelected row.major.id
};// 关闭弹出层
const closeLayer () {Data.dialogFormVisible false;// 编辑和查看设置为FalseData.isEdit false;Data.isView false;// 初始化表单Data.studentform.sno ;Data.studentform.name ;Data.studentform.gender ;Data.studentform.birthday ;Data.studentform.major ;Data.studentform.faculty ;Data.studentform.mobile ;Data.studentform.email ;Data.studentform.address ;// 初始化表单专业的而选择Data.layerMajorSelected ;
}
// 构建弹出层树状结构的学院和专业
const getTreeMajor async () {// 定义集合let allFacultys reactive([]);let allMajors reactive([]);// 获取所有院系await indexApi.facultysApi.getAll().then((res){// console.log(res.data.results)allFacultys res.data;});// 获取所有专业await indexApi.majorsApi.getAll().then((res){console.log(res)allMajors res.data;});// 组合数据for (let faculty of allFacultys) {// 定义需要的结构var obj reactive({value: ${faculty.id}-${faculty.name},label: faculty.name,children: [],});// 遍历院系填充obj的childrenfor (let major of allMajors) {// 判断当前专业是否隶属于当前院系if (major.faculty.id faculty.id) {//添加obj.children.push({value: major.id,label: major.name,});}}// 附加到Data.layerFacultyMajor.push(obj);}
}// 定义页面加载时自动执行的函数
const autoRun () {// 获取所有信息getStudents() // 获取院系填充信息getFacultys()// 获取树状结构的学院和专业getTreeMajor()
}
// 调用自动执行函数执行
autoRun() // 定义级联标签
el-form-item label学院/专业:
el-cascader
v-modelData.layerMajorSelected
placeholder选择专业
:optionsData.layerFacultyMajor
filterable
stylewidth: 555px
:disabledData.isView/
/el-form-item