ElmentuUI
表单
- 设置必填但又不方便写在rules里面校验,加上
required
,然后在提交函数内校验判断 - 存在v-if判断,需要填写时显示必填样式(直接在rules里面写required: true,无论是否显示出来,都需要填(值不为空))
<el-form-item label="积分" required>
校验
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" > // :rules 注意有s
<el-form-item label="活动名称" prop="name"> // prop值必须与ruleForm的name属性一致
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="特殊资源" prop="resource">
<el-radio-group v-model="ruleForm.resource">
<!-- label的值会自动绑定到ruleForm.resource -->
<!-- 一般会这样做 label="1"获得的是字符串'1' :label="1"获得的是数字1 这里使用value="1"无效
<el-radio :label="1">{
{ "线上品牌商赞助" }}</el-radio>
<el-radio :label="2"> 线下场地免费 </el-radio>
-->
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
//<el-button type="primary" @click="add('ruleForm')">立即创建</el-button> 写在外面也可以的
//<el-button @click="resetForm('ruleForm')">重置</el-button>
<script>
export default {
data() {
return {
ruleForm: {
name: ''
},
rules: {
name: [ // name必须是ruleForm中的一个属性,否则获取不到值
{
required: true, message: '请输入活动名称', trigger: 'blur' },
{
min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
resource: [
{
required: true, message: '请选择活动资源', trigger: 'change' }
],
}
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// 校验成功
alert('submit!');
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
}
</script>
细节:
- 1.prop=“age” 是传入 Form 组件的 model 中的字段,如果v-model=“other”(other不是表单的属性),则校验需要在提交函数中判断一下
<el-form-item label="活动名称" prop="other">
<el-input v-model="other"></el-input>
</el-form-item>
if (!this.other) {
this.$message({
message: '请xxxx',
type: 'warning'
});
return
}
- 2.如果是比较难的校验且不需要复用的情况下也可以在提交函数中判断一下
type:
validator
Vue+Element ui中常用表单验证----手机号、座机、传真、邮箱、身份证号、数字和带小数点的数字https://blog.csdn.net/seeker_lqq/article/details/99679978
element+vue验证顺序:form–>prop–>rules–>validator–>自定义规则
data() {
let checkMobile = (rule, value, callback) => {
if (!value) {
callback(); // 不输入放行
// return new Error("请输入电话号码");
} else {
const reg = /^1[3|4|5|7|8][0-9]\d{8}$/;
const isPhone = reg.test(value);
value = Number(value); //转换为数字
if (typeof value === "number" && !isNaN(value)) {
//判断是否为数字
value = value.toString(); //转换成字符串
if (value.length < 0 || value.length > 12 || !isPhone) {
//判断是否为11位手机号
callback(new Error("请输入正确的手机号码"));
} else {
callback();
}
}
}
};
let xxx = (rule, value, callback) => {
...};
rerurn{
...
}
}
rules: {
mobileNumber: [{
required: true, message: "请输入手机号码", trigger: "blur" },
{
validator: checkMobile, trigger: "blur" }]
}
checkbox
v-model会获取 :label值 ,设置value没有效果
<el-form-item label="风格选择">
<el-checkbox-group v-model="modelForm.modelStyle">
<el-checkbox v-for="item in modelStyle"
:label="item.id" name="modelStyle" :key="item.id">{
{ item.styleName }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
data() {
return {
modelForm: {
modelStyle: [] // 这里必须显示声明为数组类型,否则不显示
},
}
表单重置
注意点:
- 我们需要为每个form-item加上prop属性,要不然无法清空(大部分的问题就是出在这)
resetFields()
方法是重置表单,重置为初始值,而不是设置为空值(如果没有设置默认值则会设置为空)- 在resetFields()方法之前,如果修改了data里的表单默认值,那么重置以后就是你修改以后的值,而不是data里的值了
element-ui表单使用点击重置后无法输入、输入没有显示
https://blog.csdn.net/TUTsmile/article/details/103598504
使用element-ui 的 form 组件的重置后
this.$refs[‘form’].resetFields()
若form对象没有设置默认值,此时的 form 为 {} 即一个空对象。
否则清空后,对象不存在对应的set (vue 对于对象无法及时显示的方法是使用#set()),此时的输入无法及时挂载到dom上。
弹出层
关闭弹窗时表单置空
addForm里面没有数组等引用类型可以使用
addForm={
...
}
// 需要置空的数据都放到addForm里面 或者触发一个函数
<el-dialog title="添加" :visible.sync="dialogVisibleAdd" @close="addForm={}">
editForm可以不重置,因为会覆盖掉前面的数据
修改弹窗
https://juejin.cn/post/6844903481224986638#heading-7
在修改数据的时候还有一个小坑需要主要。 当我们拿到需要修改行的数据时候不能直接将它直接赋值给dialog,不然会发生下面的问题。
如上图所示,我们在dialog里面改变状态的时候,遮罩下面的table里面该行的状态也在那里跟着一只变化着。原因想必大家都猜到了。赋值的数据是一个objec引用类型共享一个内存区域的。所以我们就不能直接连等复制,需要重新指向一个新的引用,方案如下:
//赋值对象是一个obj
this.editForm=Object.assign({
}, row) //这样就不会共用同一个对象
Object.assign(target, ...sources)
参数target目标对象。sources源对象。返回值:目标对象。
//数组我们也有一个巧妙的防范
newArray = oldArray.slice(); //slice会clone返回一个新数组
表单绑定对象输入时不显示 ***
https://blog.csdn.net/mad_house/article/details/106240194
重现
<!-- 编辑对话框 -->
<el-dialog
title="编辑"
:visible.sync="editDialogFormVisible"
// 最好把这句去掉 @close="editForm = {}" 要不然下一次editForm 又是一个空对象,反正修改的信息会覆盖原来的信息
>
<el-form :model="editForm" label-width="80px" :rules="rules" ref="editForm">
<el-form-item label="ID">
<el-input v-model="editForm.fileId " auto-complete="off" disabled></el-input>
</el-form-item>
<el-form-item label="软件名" prop="fileTypeName ">
<el-input v-model="editForm.fileTypeName " auto-complete="off"></el-input>
</el-form-item>
...省略
data(){
editForm: {},
}
表格点击编辑按钮
edit(row) {
this.editForm.fileId = row.id;
this.editForm.fileTypeName = row.fileType;
this.editDialogFormVisible = true;
},
发现 fileTypeName 无法双向绑定
解决办法
editForm: {
fileTypeName:'', // 把需要修改的属性名加上即可
},
原因:页面加载的时候,未在data进行定义(会出现第一次输入无用,点击其他地方的时候显示)
主要是保证输入框绑定的值在data中提前定义好,或者调用$set 进行数据的双向绑定。
https://www.cnblogs.com/xhliang/p/11940418.html
input绑定的是对象内的变量,首次进入关闭之后我进行了对象的重置直接置为空对象,这样会导致这种错误的发生;…
解决方法:
- 方案1:重置时精确到对应的变量(比如 this.addForm.id= ‘’ , this.addForm.arr=[])
- 方案2:给input绑定@input事件 有内容输入就实时更新视图
- 方案3:绑定到input中的双向数据变量 不是对象内部的值就不会遇到这个问题
- 方案4:对象全部重置,再用
Vue.set(object, propertyName, value)
手动添加为引用类型的属性
提醒:对象里面的引用属性不能销毁,比如数组,对象等等
销毁后vue就无法找不到该属性了,也就无法双向绑定。
深入响应式原理
官方文档
深入响应式原理
:https://cn.vuejs.org/v2/guide/reactivity.html
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter
。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
由于 JavaScript 的限制,Vue 不能检测数组
和对象
的变化。尽管如此我们还是有一些办法来回避这些限制并保证它们的响应性。
对象解决办法:
- 提前定义好对象以及其内部属性(引用类型的属性)
- ***使用
Vue.set(object, propertyName, value)
方法向嵌套对象添加响应式 property。(data里面的对象,该对象的属性,该属性的值)
例如,对于:Vue.set(vm.someObject, ‘b’, 2),您还可以使用vm.$set
实例方法,这也是全局 Vue.set 方法的别名:this.$set(this.someObject,‘b’,2)
//点击添加按钮
this.addForm = {
} // 清空对象
Vue.set(this.addForm, "roleIds", []) // 给对象添加属性并给添加双向绑定
this.addDialogFormVisible = true
数组
原文链接:https://blog.csdn.net/qq_28194001/article/details/112404153
对于数组:Vue 不能检测以下数组的变动:
当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
原因到这里就明了了,我们的数据没有进行渲染是因为在一开始,data下的form中就没有dataList这个属性,因此在后续即使该值产生了变化,Vue也就无法检测到它的改变。而且不仅仅是对数组,即使是js对象也是一样的。除此之外,直接按下标修改数组的元素,也不会触发视图渲染。
会触发数组渲染的有以下数组方法:
-
push(element) // 在数组末尾添加元素
-
pop() // 删除数组最后一个元素并将其返回
-
shift() // 删除数组第一个元素并将其返回
-
unshift(ele1, ele2, …, eleN) // 向数组的开头添加一个或更多元素,并返回新的长度
-
splice
(start, deleteCount?, …item) // 删除数组中的元素并在该元素所在位置替换为新元素 -
sort() // 对数组进行排序,会修改数组元素的位置
-
reverse() // 倒转数组元素,会修改数组元素的位置
数组对象的案例:https://blog.csdn.net/Kimser/article/details/108400369
表格
slot-scope=“scope“
通过 Scoped slot 可以获取到 row, column, $index 和 store(table 内部的状态管理)的数据,用法参考 官方文档
常用于对数据进行其他复杂操作,{
{ scope.row.xxx }}
插值内可以使用运算符、调用函数等其他操作
https://www.cnblogs.com/whoamimy/p/12419222.html
<el-table :data="tableData" style="width: 100%">
<el-table-column label="索引值" width="400">
<template slot-scope="scope"> <!-- slot-scope="scope" 这里获取到当前单元格 -->
<span>{
{ scope.$index }}</span> <!-- scope.$index 直接取到该单元格的下标,从0开始,不是表单数据的id -->
</template>
</el-table-column>
<el-table-column label="标题" width="350">
<template slot-scope="scope">
<span>{
{ scope.row.title }}</span>
<!-- scope.row 直接取到该单元格对象,即是tableData[scope.$index] -->
<!-- .title 是对象里面的title属性的值 -->
</template>
</el-table-column>
<el-table-column label="性别" width="350">
<template slot-scope="scope">
<span>{
{ scope.row.sex===0? '女':'男' }}</span>
</template>
</el-table-column>
<el-table-column label="等级" width="350">
<template slot-scope="scope">
<span>{
{ grade(scope.row.sex) }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="success" @click="update(scope.row)">修改</el-button>
<el-button type="danger" @click="delete(scope.row.id)">修改</el-button>
</template>
</el-table-column>
</el-table>
试验
<template slot-scope="scope">
<el-button type="success" @click="update(scope, scope.row)">修改</el-button
</template >
简单的数据也可以直接使用 prop
<el-table-column prop="name" label="姓名"width="180"></el-table-column>
slot-scope={ row }
类似于对象解构 { row }= scope 懂的都懂
建议使用对象形式,因为一般我们只会用到 该行的数据
<el-table-column label="ID">
<template slot-scope="{ row }">
<span>{
{ row }}</span>
</template>
</el-table-column>
修改,覆盖样式
https://juejin.cn/post/6844903481224986638#heading-12
axios
// vue-admin-manager
import axios from 'axios'
import qs from 'qs'
import {
MessageBox, Message } from 'element-ui'
import store from '@/store'
import {
getToken } from '@/utils/auth'
// create an axios instance
const service = axios.create({
// baseURL: 'http://xr.jxvive.com', // url = base url + request url process.env.VUE_APP_BASE_API,
baseURL: 'http://192.168.4.85', // url = base url + request url process.env.VUE_APP_BASE_API,
withCredentials: true, // send cookies when cross-domain requests
timeout: 500000 ,// request timeout
// responseType: "json",
// headers: {
// "Content-Type": "application/json;charset=utf-8"
// }
})
// request interceptor
service.interceptors.request.use(
// console.log(state.token),
config => {
// do something before request is sent
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()
config.headers['token'] = getToken()
}
// 拦截post请求 这里有点问题 ,文件上传
if (config.method==='post'){
config.headers['Content-Type']='application/json'
config.data=JSON.stringify(config.data) // qs.stringify()没效果 why
console.log(config) // 打印config看参数
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// service.interceptors.response.use(
// response => {
// const res = response.data
// console.info(res)
// if (res.token === null) {
// return Promise.reject(new Error(res.message || 'Error'))
// } else {
// return res
// }
// },
// error => {
// console.log('err' + error) // for debug
// return Promise.reject(error)
// }
// )
// export default service
// response interceptor
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
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 200) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 508 || res.code === 512 || res.code === 514) {
// to re-login
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
confirmButtonText: 'Re-Login',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
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
data
data是添加到请求体(body)中的, 一般用于post请求。
export function ToAuditItemUpdateSuccess(data) {
return request({
url: `/api/model/admin/auth/auditModel`,
method: 'post',
data // 会自动json序列化 不要 data:{data} 这样会变成?xx=xx
})
}
params
params是添加到url的请求字符串中的,一般用于get请求。
/*
data:{id:1,name:'jack'}
*/
export function ToAuditList(data, page = 1, limit = 10) {
return request({
url: `/api/model/admin/list/${
page}/${
limit}`,
method: 'get',
params: {
...data // 对象解构
}
})
}
// xxx/api/model/admin/list/${page}/${limit}?id=1&name=jack
Webpack
配置
- 普通项目
{
"name": "code",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack serve",
"build": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.5.1"
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/plugin-proposal-class-properties": "^7.12.1",
"babel-loader": "^8.2.1",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^5.0.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^4.5.0",
"less": "^3.12.2",
"less-loader": "^7.1.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"webpack": "^5.5.1",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
}
}
const path = require('path')
// 1. 导入插件,得到构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 2. 创建插件的实例对象
const htmlPlugin = new HtmlPlugin({
template: './src/index.html',
filename: './index.html',
})
const {
CleanWebpackPlugin } = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()
module.exports = {
mode: 'development', // development production
// eval-source-map 仅限在开发模式下使用
// devtool: 'eval-source-map',
// 生产环境下,建议关闭 SourceMap 或将 devtool 的值设置为 nosources-source-map
// devtool: 'nosources-source-map',
// devtool: 'source-map',
// 指定打包的入口
entry: path.join(__dirname, './src/index.js'),
// 指定打包的出口
output: {
// 表示输出文件的存放路径
path: path.join(__dirname, './dist'),
// 表示输出文件的名称
filename: 'js/bundle.js',
},
plugins: [htmlPlugin, cleanPlugin], // 3. 挂载插件的实例对象
devServer: {
open: true,
host: '127.0.0.1',
port: 80,
},
module: {
rules: [
{
test: /\.css$/, use: ['style-loader', 'css-loader'] },
{
test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
// { test: /\.jpg|png|gif$/, use: 'url-loader?limit=22228' }
{
test: /\.jpg|png|gif$/,
use: {
loader: 'url-loader',
options: {
limit: 22228,
outputPath: 'image',
},
},
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: ['@babel/plugin-proposal-class-properties'],
},
},
},
],
},
}
npm
npm install --registry=http://registry.npmjs.org
在使用 npm install 命令时,有许多指定参数的命令是可以进行缩写的,本文就简单梳理一下。
npm install本身有一个别名,即npm i,可以使用这种缩写方式来运行命令,打到简化的效果。
以下为指定的一些命令行参数的缩写方式:
-g
–global,缩写为-g,表示安装包时,视作全局的包。安装之后的包将位于系统预设的目录之下,一般来说
-S
–save,缩写为-S,表示安装的包将写入package.json里面的dependencies。
-D
–save-dev,缩写为-D,表示将安装的包将写入packege.json里面的devDependencies。
-O
–save-optional缩写为-O,表示将安装的包将写入packege.json里面的optionalDependencies。
-E
–save-exact缩写为-E,表示安装的包的版本是精确指定的。
-B
–save-bundle缩写为-B,表示将安装的包将写入packege.json里面的bundleDependencies。
来源:https://www.dazhuanlan.com/codemonkeydrive/topics/1144219