Vue问题汇总
一、双向数据绑定的问题
问题描述:一个list页,点击编辑数据是其中的一条。修改后,数据没有提交成功。再次点击此条数据编辑,显示的仍然是没有提交成功的数据。
解决方法:
/* 修改内容*/ handleUpdate(row) { this.form = JSON.parse(JSON.stringify(row)) //this.form = row 就会有双向数据绑定的问题
}
二、富文本编辑器的使用
参考:vue的富文本编辑器使用
1.富文本框显示输入字数,超过限制不能输入
vue代码,maxContent 自定义最大字符数
<el-form-item label="内容" prop="content"> <quill-editor ref="myQuillEditor" v-model="form.content" :options="editorOption" maxlength="10" @change="onEditorChange($event)" /> <span class="wordNumber">{{ TiLength }}/{{ maxContent }}</span> </el-form-item>
js部分
// 富文本显示字符数 onEditorChange(event) { event.quill.deleteText(this.maxContent, 7) if (this.form.content === '') { this.TiLength = 0 } else { // 样式也算字符数,因为存进数据库的也包含样式 this.TiLength = this.form.content.length - 7 // event.quill.getLength()-1 //获取实际文字长度,空格等不会计算在内 } }
css
.wordNumber{ position: relative; left: 420px; top: -25px; }
这样编辑富文本的时候就只能输入限定长度的字符了,但是这个防止不了粘贴到富文本的情况。因此提交时增加一个验证即可
if (this.form.content.length > (this.maxContent+7)) { this.$message({ message: '内容超过500字!', type: 'warning' }); return; }
三、动态数据验证
需求描述:一个表单,分上中下三部分。上面是必填,中间是选择项,如果中选择true则下边是必填。否则要去掉验证
vue
<el-form-item label="话题" prop="topic" :rules="[{ required: form.status === 0, message: '请输入话题标题!', trigger: 'blur' },{ min: 1, max: 20, message: '长度在20个字符', trigger: 'blur' }]"> <el-input v-model="form.topic" clearable /> </el-form-item> <el-form-item label="蓝方观点" class="blue" prop="bluePoint" :rules="[{ required: form.status === 0, message: '请输入蓝方观点!', trigger: 'blur' }]"> <el-input v-model="form.bluePoint" clearable maxlength="20" /> </el-form-item> <el-form-item label="初始人数" class="blue" prop="blueIni" :rules="[{ required: form.status === 0, message: '请填写蓝方初始票数!', trigger: 'blur' }]"> <el-input v-model="form.blueIni" clearable type="number" min="0" /> </el-form-item> <el-form-item label="红方观点" class="red" prop="redPoint" :rules="[{ required: form.status === 0, message: '请输入红方观点!', trigger: 'blur' }]"> <el-input v-model="form.redPoint" clearable maxlength="20" /> </el-form-item> <el-form-item label="初始人数" class="red" prop="redIni" :rules="[{ required: form.status === 0, message: '请填写红方初始票数!', trigger: 'blur' }]"> <el-input v-model="form.redIni" clearable type="number" min="0" /> </el-form-item> <el-form-item label="投票时间"> <el-col :span="11"> <el-form-item prop="begindate" :rules="[{ required: form.status === 0, message: '请选择投票开始日期', trigger: 'change' }]"> <el-date-picker v-model="form.begindate" type="datetime" placeholder="选择日期" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%;" /> </el-form-item> </el-col> <el-col class="line" :span="2" style="text-indent: 1em">至</el-col> <el-col :span="11"> <el-form-item prop="endDate" :rules="[{ required: form.status === 0, message: '请选择投票结束时间', trigger: 'change' }]"> <el-date-picker v-model="form.endDate" type="datetime" placeholder="选择日期" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%;" @change="checkDate" /> </el-form-item> </el-col> </el-form-item>
js去掉验证
// 选择隐藏话题去除话题验证 selectStatus() { if (this.form.status === 1) { this.$refs['form'].clearValidate(['topic', 'bluePoint', 'blueIni', 'redPoint', 'redIni', 'begindate', 'endDate']) } else { this.$refs['form'].validateField(['topic', 'bluePoint', 'blueIni', 'redPoint', 'redIni', 'begindate', 'endDate']) } }
四、富文本编辑器去除HTML标签
由于小程序页面不能直接显示,需要去除
// 移除文本内容中的HTML 标签 delHtmlTag(str) { return str.replace(/<[^>]+>/g, '') },
传参给后台的时候调用即可。
五、邮箱格式验证
insure_mailbox: [
{ required: this.insure_mailbox != null,
validator: (rule, value, callback) => {
if (value != "" && value != null) {
if (!/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(value)) {
callback(new Error("投保人邮箱格式不正确"));
return;
}
}
callback();
}, trigger: "click"}
]
六、手机号验证
insure_telephone: [
{ required: this.insure_telephone != null,
validator: (rule, value, callback) => {
if (value != "" && value != null) {
if (!/^1[3456789]\d{9}$/.test(value)) {
callback(new Error('投保人手机号码格式不正确'));
return;
}
}
callback();
}, trigger: "click"}
]
七、导入导出excel
参考:vue 导入导出Excel文件(使用js-xlsx库)
特别注意,这个里面已经封装了文件选择,就不要再使用element的组件了
<el-form-item label="导入文件" > <el-button size="small" type="primary" @click="chengFile">选择文件<i class="el-icon-upload el-icon--right"></i></el-button> <span style="font-size: x-small">*只能导入.et/.xlsx/.xlsx/.csv文件</span> </el-form-item>
chengFile() { excel.importExcel((data, dataRef) => { this.importInfo = "<p style=\"color: green\">读取数据中...</p>"; for (var i = 0; i < data.length; i++) { this.importInfo = this.importInfo + "<p style=\"color: \">"+data[i]+"</p>"; } this.importInfo = this.importInfo + "<p style=\"color: green\">读取完成,共" + data.length + "条数据!</p>"; this.fileData = data; }); }
导出excel
<el-button type="primary" icon="el-icon-upload2" size="small" plain @click="doExport"> <download-excel v-show="false" class="export-btn" id="exportbtn" :data="contentList" :fields="headerl" type="xlsx" :header="headName" :name="excelName"/> </el-button>
import JsonExcel from "vue-json-excel" components: { DownloadExcel: JsonExcel, }
doExport(){ document.getElementById("exportbtn").click() }
data() { return { headerl: { "投保人":"tname" , "被保人":"bname", "保险公司":"company" , "投保产品":"name" , "保单号":"number" , "理赔类型":"claimTypeName" , "出险日期":"outDate" , "申请日期":"applicationDate" , "申请金额":"applicationMoney" , "账单总金额":"money" , "社保报销":"socialSecurity" , "理赔结论" :"conclusionName", "理赔金额":"claimAmount" , "结案日期":"closeDate" , "到账日期":"arrivalDate" , "备注":"remark" }, headName: '', excelName: "理赔记录"+new Date().getTime().toString()+".xlsx" } }
八、打包上线隐藏源代码
productionSourceMap:false
参考 https://www.e-learn.cn/topic/3632410
九、自动定位到滚动条底部
如下,一个div内的元素会动态添加,设置了overflow:auto 希望每次加载后显示最底部的数据
<el-form-item label="导入信息"> <div v-html="importInfo" id="chatbox" style="width: 95%;height: 400px;font-size: x-small;border: 1px solid;padding-left: 10px;overflow:auto;" disabled>未选择文件</div> </el-form-item>
watch: { importInfo(val){ this.$nextTick(() => { var div = document.getElementById('chatbox'); div.scrollTop = div.scrollHeight }) } }
十、下载文件不直接打开
比如一个图片的url常用的方式浏览器会打开图片,而不是下载图片,这不是我们想要的。根据这个url获取文件流数据下载,后台无需另外提供接口。
//根据url下载文件,不打开 downloadFile (url, downloadName ) { var link = document.createElement('a');
// 关键部分,无需另外提供接口 fetch(url).then(res => res.blob()).then((blob) => { link.href = URL.createObjectURL(blob); link.download = downloadName; document.body.appendChild(link); link.click(); //document.body.removeChild(link); }); }, // 下载点击事件 download(row){ //点击下载多个文件,一个保单最多有5个文件 for(let i=0;i<row.documentsList.length;i++){ // 根据文件id请求访问路径url crudQiNiu.download(row.documentsList[i].id).then((response) => { this.downloadFile(response.url,row.documentsList[i].fileName); }).catch(err => { this.$message({ message: err.response.data.message, type: "error" }) }) }
实现效果
十一、分页默认index,size
<el-pagination style="margin: 10px 0;" :current-page="queryParams.pageIndex" :page-size="queryParams.pageSize" :page-sizes="[10, 20,25, 50,100]" layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
十二、实现复制功能
如题,用户点击复制按钮,past把信息发送给客户
copyNote(row) { let target = document.createElement('input') //创建input节点 target.value = "尊敬的"+row.nickName+",您好!您为"+row.bname+"购买的"+row.company+row.name+"将于"+row.renewalDate.substr(0,10)+"续期,续期保费为"+row.premium+"元。请您提前在绑定的尾号为"+row.bankCardNumber+"的"+row.bank+"卡内存入足够的保费。谢谢!此时,保单状态是“有效”。" // 给input的value赋值 document.body.appendChild(target) // 向页面插入input节点 target.select() // 选中input try { document.execCommand('Copy') // 执行浏览器复制命令 this.$message({ message: "复制成功!", type: "success" }) } catch { this.$message({ message: "复制失败!", type: "error" }) } }
十三、el-admin新增菜单页面,刷新报错404
找到 /src/router/routers.js
export default new Router({ // mode: 'hash', // mode: 'history', scrollBehavior: () => ({ y: 0 }), routes: constantRouterMap })