1.package.json 中配置 不是所有的都是 npm run dev,npm rn bulid 还要看配置文件
npm run dev 运行开发环境
npm run build:prod 运行生产环境 (打包)
2.elemnt-ui如何将文件流和其他字段一起提交
用element-ui框架的https://element.faas.ele.me/#/zh-CN/component/upload 上传组件
html层
<el-form ref="video" :model="video" :rules="submitRules" label-width="120px" > <!-- prop:表单域 model 字段,要和data中保持一致,在使用 validate、resetFields 方法的情况下,该属性是必填的--> <el-form-item prop="video_title" label="视频名称"> <el-input name="video_title" v-model.trim="video.video_title" /> </el-form-item> <el-form-item prop="video_file" label="视频文件"> <el-upload class="upload-demo" ref="upload" :action="upLoadUrl" :on-success="handleSuccess" :on-change="handleChange" :auto-upload="uploadStatus" :data="videoData" 额外的参数 :headers="myHeaders" accept="video/*" :limit="1" :file-list="fileList" name="video_file" file文件流的name,默认为file > <el-button size="small" type="primary">点击上传</el-button> </el-upload> <a :href="video.video_link" target="_blank" v-if="video.video_link"> <el-button type="success" size="small">视频预览 </el-button> </a> <div slot="tip" class="el-upload__tip">只能上传视频文件</div> </el-form-item> <el-form-item prop="label_id" label="标签"> <el-select v-model="label_array" multiple placeholder="请选择"> <el-option v-for="item in tags" :key="item.value" :label="item.label" :value="item.value" > </el-option> </el-select> <el-input style="position:absolute;z-index:-1;" v-model.trim="video.label_id" type="hidden" /> </el-form-item> <el-form-item prop="is_onsale" label="是否上架"> <el-radio-group v-model="video.is_onsale"> <el-radio label="0">下架</el-radio> <el-radio label="1" checked>上架</el-radio> </el-radio-group> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit2">提交</el-button> <el-button @click="onCancel">取消</el-button> </el-form-item> </el-form>
script
import { videoAdd, getTagList, getVideoData } from "@/api/video"; import { areaName } from "@/api/area"; import { getRegionList } from "@/api/business"; export default { name: "add", data() { return { // 接口地址 用上传组件 然后将其他字段加进去 upLoadUrl: "https://ixx.haoqianlei.com/admin/v1/video/add", fileList: [], files: "", uploadStatus: false, editVideo: false, videoData: { id: "", video_title: "", label_id: "", is_onsale: "", video_link: "" }, myHeaders: { "X-Requested-With": "XMLHttpRequest", Authorization: "Bearer " + this.cookies.get("Authorization") }, // 表单的对应数据 video: { video_title: "", video_file: "", label_id: "", is_onsale: "1", video_link: "" }, label_array: [], list: [], tags: [] }; }, watch: { label_array(newName, oldName) { console.log(newName); if (newName.length > 0) { var str = ""; newName.forEach(item => { str += item + ","; }); this.video.label_id = str.slice(0, -1); } console.log(this.video.label_id); } }, methods: { getList() { getTagList({ username: "" }).then(res => { this.tagFormatter(res.data); }); }, loadVideo(file, fileList) { this.video.video_file = file; }, handleRemove(file, fileList) { console.log(file, fileList); this.$confirm(`确定移除 ${file.name}?`) .then(() => { this.video.video_file = ""; }) .catch(() => {}); }, handleChange(res, file) { this.video.video_file = file; }, handleSuccess(res) { this.$message(res.data); this.labelName = ""; this.$refs.upload.clearFiles(); }, onSubmit2() { // this.$refs.video.validate(valid => { // if (valid) { if (this.video.video_title.length == 0) { this.$message({ message: "请输入视频名称", type: "error" }); return; } if (this.video.video_file == 0) { this.$message({ message: "请上传视频文件", type: "error" }); return; } if (this.video.label_id.length == 0) { this.$message({ message: "请选择标签", type: "error" }); return; } if (this.video.is_onsale.length == 0) { this.$message({ message: "请选择上架类型", type: "error" }); return; } this.videoData.video_title = this.video.video_title; this.videoData.label_id = this.video.label_id; this.videoData.is_onsale = this.video.is_onsale; // 上传 掉上传接口 this.$refs.upload.submit(); }, onCancel() { this.$message({ message: "取消!", type: "warning" }); this.video = { video_title: "", video_file: "", label_id: "", is_onsale: "" }; }, tagFormatter(data) { var arr = []; data.forEach(item => { arr.push({ value: item.id, label: item.label_title }); }); this.tags = arr; }, getLabelArr(data) { var arr = []; data.forEach(item => { arr.push(item.id); }); this.label_array = arr; }, }, mounted() { this.getList(); this.getreglist(); } };
3.路由拦截器 一些简单的配置
import axios from 'axios' import { MessageBox, Message } from 'element-ui' import store from '@/store' import { getToken, setToken } from '@/utils/auth' // 创建axios实例 const service = axios.create({ baseURL: 'https://ixx.haoqianlei.com/admin/v1', // baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests timeout: 5000 // request timeout 请求超时 }) // request interceptor request拦截器 请求拦截 service.interceptors.request.use( config => { // do something before request is sent if(config.headers.authorization){ config.headers['Authorization'] = `Bearer ${config.headers.authorization}` // commit('SET_TOKEN', config.headers.authorization) // 登录成功后将token存储在cookie之中 setToken(config.headers.authorization.slice(7)) return config } if (store.getters.token) { // let each request carry token // ['X-Token'] is a custom headers key // please modify it according to the actual situation // config.headers['token'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改 // config.headers['X-Requested-With'] = 'XMLHttpRequest'; config.headers['Authorization'] = `Bearer ${getToken()}` // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改 // config.headers['user-name'] = store.getters.name } return config }, error => { // do something with request error // console.log(error) // for debug return Promise.reject(error) } ) // response interceptor respone拦截器 响应拦截器 service.interceptors.response.use( /** * If you want to get http information such as headers or status * Please return response => response */ /** * Determine the request status by custom code * Here is just an example * You can also judge the status by HTTP Status Code */ response => { const res = response.data; //拦截响应,做统一处理 当token过期,接口会返回一个可用的token 前端接受以后替换当前token if (response.headers.authorization) { //设置token setToken(response.headers.authorization.slice(7)) } // if the custom code is not 20000, it is judged as an error. if (res.code != 200 ) { // 状态码 Message({ message: res.data || 'Error', type: 'error', duration: 5 * 1000 }) // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; // if (res.code === 422 || res.code === 401) { // console.log(211) // // to re-login 重新登录 // MessageBox.confirm('登录失效', 'Confirm logout', { // confirmButtonText: 'Re-Login', // cancelButtonText: 'Cancel', // type: 'warning' // }).then(() => { // store.dispatch('user/resetToken').then(() => { // // 为了重新实例化vue-router对象 避免bug // location.reload() // console.log(333) // }) // }) // }else{ // Message({ // // message: res.message || 'Error', // message: 'Error', // type: 'error', // duration: 5 * 1000 // }) // } return Promise.reject(new Error(res.message || 'Error')) } else { return res } }, error => { console.log('err' + error) // for debug Message({ message: error.message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } ) export default service
4. 修改基础配置
统一接口路径配置 vue.config.js
main.js 也要把mock的相关注释掉 防止接口掉错