**vue 后台管理现成的项目vue-element-admin,搜索下载即可
创建vue项目(通常不操作index.html文件,因为它未被打包,东西越少越好)
D:(切换到自己想要的磁盘,我想存在d盘)
①node -v 检查node是否安装完成(未安装的话安装下)
②npm -v 检查npm是否安装(未安装的话执行 npm install - g npm)
③安装脚手架 npm install vue-cli -g(一台电脑安装一次就可以,检查是否安装用vue-cli -v)
④vue create webpack my-vue-demo(my-vue-demo是自己定义的项目名字,名字必须中划线链接),2.0以上项目
vue init webpack my-vue-demo (创建2.0项目)
⑤
⑥cd my-vue-demo(切换到文件所在的目录)
⑦npm i (安装依赖即可)
1.MVVM思想
MVVM是Model-View-ViewModel的缩写,Model由js对象表示,View负责显示,做到模型和视图最大限度的分离,而ViewModel充当模型和视图的中间人,把模型的数据同步到视图,把视图的修改同步回模型,这样做的好处是什么呢?js不用再频繁的操作dom节点,而是把注意力都放在Model这个js对象上
2.常用指令
2.1:属性值绑定(标签的任何属性) v-bind:id=‘domId’ (缩写:id=‘domId’);
v-bind:src=‘./log.png’ (缩写:src=‘./log.png’);
2.2:事件绑定 v-on:click=‘add’ (缩写@click=‘add’);
2.3:条件判断 v-if='seen’;
2.4:循环数组 v-for=‘todo in todos’; :key=“i”(加唯一标识)
循环对象 v-for=‘(val,key) in todos’
2.5:v-text=‘aaa’ ,替换标签全部内容,aaa=123=>123
2.6: v-html=‘bbb’ 能识别字符串中标签 ,bbb=234=>234
2.7:v-modal=‘msg’ ,绑定表单元素,并自动绑定value值
2.8 :v-bind绑定语法,对象语法,数组语法
2.8.1: v-bind:class=“{asd:daa}” asd是类名,daa是类名对应的值,在data 中
显示,简写:class=“{asd:daa}” ,等于一个对象,对象中的值是data中数据,
2.8.2: v-bind:class=“[asd,daa]” asd是类名,daa是类名对应的值,在data 中
data{asd:active,daa:color}
显示,简写:class=“{asd,daa}” ,等于一个对象,对象中的值是data中数据,
3.生命周期(常用)
created()|{ // 创建完成(可以访问当前this实例)请求网络数据
},
mounted() { 挂载完成(可以访问DOM元素)
},
4.插值表达式可以直接写data中数据,直接写XXX,不用加this
5,过滤器(某标签展示金钱样式,固定样式,保留两位小数)
filters:{
showPrice(price){
return ‘$’+price.toFixed(2)
}
}
使用:{{item.price | showPrice}}
6.模块化导出,避免命名冲突
6.1封装js方法
function throttle(fn, gapTime) { // 节流方法
let _nowTime = new Date().getTime();
if (_nowTime - this._lastTime > gapTime || !this._lastTime) {
fn();
this._lastTime = _nowTime;
}
}
module.exports = {
throttle,
};
6.2使用
import util from '../../../../utils/oldWechat/util.js'
jump:util.throttle(function(e) {
...
},2500),
7.导入导出方式
module.exports==>对应require() (这是common.js导出方式)
export==>对应import {asd} from ‘aaa.js’ (结构出来asd,使用必须是asd)等 价于import*as asd from ‘aaa.js’ 使用 asd.方法名 (es6导出方式)
export default ==>import aaa from ‘aaa.js’ (aaa名字自己定义的)
8.什么是webpack
webpack是前端模块化打包工具,附带文件压缩与处理功能,webpack更侧重于模块化。gulp更强调前端流程自动化,定义任务,只进行简单的合并压缩功能。
webpack依赖于node环境,node有个工具npm 可以安装各种包
9.安装webpack(全局和局部)
全局:npm i [email protected] -g
局部:开发时用到的依赖,打包后就不用了 npm i [email protected] --save -dev(–save -dev是开发时依赖,项目打包后不用)
package.json 文件中的东西
10.webpack使用
10.1js文件内容不能解析,script可以不直接引用。通过webpack打包转换为可解析的文件,script可以直接引用的
10.2使用代码:webpack ./src/main.js ./dist/bundle.js(将不能解析的main.js通过webpack转化为可解析的bundle.js,放至dist打包文件夹下)
10.3 项目一旦用到node中的东西,要创建package.json,先npm init 后npm i
10.4使用的const path=require(‘path’) 这个是基于node的文件引用
10.5配置入口出口文件
10.5.1创建webpack.config.js文件,只需执行webpack即可(不常用)
10.6配置图片文件
11.main.js文件解析
创建新项目 vue init webpack vueTest
移动端使用vant,有赞官网:https://youzan.github.io/vant/#/zh-CN/intro
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200715204909624.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTUwMjEwNg==,size_16,color_FFFFFF,t_70)
如下:存储: window.sessionStorage.setItem(‘lev’, json.token);
取出:window.sessionStorage.getItem(‘lev’)
清除:window.sessionStorage.clear()
3.更改data中变量,直接this.变量名=
4.1安装 npm install vue-router
4.2 在router文件夹的index.js(自动生成)中配置页面路由,如下图
4.3,使用方式1,
4.3.1 import router from '../router'
4.3.2 router.replace({
url:'login',//要跳转到的页面,不能以/开头
query:{redirect: router.currentRoute.fullPath} //登陆后返回之前页面
})
4.4,使用方式2
this.$router.replace({path:“/home”})
https://www.cnblogs.com/czy960731/p/9288830.html
$router:全局的,
$router.push({path:‘home’}),切换路由,有历史记录,
$router.replace({path:‘home’});//替换路由,没有历史记录
$route:是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部 的对象,可以获取对应的name,path,params,query等。
target=“_blank” 这是重新打开一个页面
第一种:window.open(‘asd.html’,“__blank”) //新页面打开asd页面
第二种:
10.input输入框监听输入值,并将参数e传入当前事件
**
**
this.$forceUpdate(校验中的required: true,会在标签前添加一个红色的*号,意思是必传)
第一步,(校验规则中的)
第二步
slot-scope="scope"取到当前单元格,一般放在template中,标签中取属性值:scope.row.selfImg
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200718134234497.png)
14.1:views页面下,如果创建的是XXX.vue,则引入的时候要引全部路径,,@/views/userManagement/userManagement
14.2:如果下main是index.vue 则只需引文件名即可,自己会找 ,即’@/views/userManagement
14.3 首先main.js中引入router文件并挂载,然后在router文件下的index.js文件中引入组件即可
修饰符.sync意义
.sync是用在数据双向绑定中,父子组件传值常用
15.1:子调父,子组件中点击事件触发某个方法,如onClick=“test”
方法中test(){
this.$emit(‘touch’) //touch 随便命名,和组件中名字对应即可
}
父组件中只需在引入的组件标签中写@touch=“getData”
即点击子组件时可以触发父组件的getData方法
15.2:父调子,父组件中子组件标签里面写ref属性,即
标签中添加:before-close属性等于一handleClose方法,方法中隐藏弹框即可。
handleClose(){
this.dialogVisible1=false}
在index.html 文件夹下,注意ico文件必须放在static文件夹下
handleCommand(commond) {
// 右上角三项点击事件
console.log("commond的值", commond);
switch (commond) {
case "auth":
this.authHandle();
return;
case "change":
this.changePwd();
return;
case "return":
this.returnLogin();
return;
}
},
23.1,属性使用法,
tipLoading: false, // loading动画data中定义变量控制是否显示loading
const loading = {
loadingState: null,
open() {
if (this.loadingState === null) {
this.loadingState = Loading.service({
text: '拼命加载中...', // 加载动画的文字
background: 'rgba(0, 0, 0, 0.3)', // 背景颜色
target: '.main', //需要遮罩的区域
})
}
},
close() {
if (this.loadingState !== null) {
this.loadingState.close()
}
}
}
调用的时候,即loading.open() loading.close()
24,后台管理系统,左侧导航栏数据返回展示
页面代码:menuList是下面的数组
首页
{{item.name}}
{{i.name}}
{{item.name}}
24.1 使用element router需要的返回数据格式如下,仅供参考
[
{
children: [
{
children: [],
code: "/administrator",
id: 2,
isCheck: true,
isMenu: 1,
name: "管理员管理",
parentId: 1,
rank: 1
},
{
children: [],
code: "/roleManagement",
id: 3,
isCheck: true,
isMenu: 1,
name: "角色管理",
parentId: 1,
rank: 2
}
],
code: "/systemManagement",
id: 1,
isCheck: true,
isMenu: 1,
name: "系统管理",
parentId: 0,
rank: 1
},
{
children: [],
code: "/userManagement",
id: 4,
isCheck: true,
isMenu: 1,
name: "用户管理",
parentId: 0,
rank: 2
},
{
children: [],
code: "/vehicleManagement",
id: 5,
isCheck: true,
isMenu: 1,
name: "用户车辆管理",
parentId: 0,
rank: 3
},
{
children: [],
code: "/VehicleProperties",
id: 6,
isCheck: true,
isMenu: 1,
name: "车辆属性管理",
parentId: 0,
rank: 4
},
{
children: [
{
children: [],
code: "/orderManagement",
id: 8,
isCheck: true,
isMenu: 1,
name: "飞猪订单管理",
parentId: 7,
rank: 1
},
{
children: [],
code: "/cashManagement",
id: 9,
isCheck: true,
isMenu: 1,
name: "提现管理",
parentId: 7,
rank: 2
}
],
id: 7,
isCheck: true,
isMenu: 1,
name: "订单管理",
parentId: 0,
rank: 5
}
];
24.2 使用本地的路由地址,数据如下
router 下的index.js 中写入
25,函数的节流方法1
25.1 写截节流函数
fnThrottle(method, delay, duration, ...params) {
// 节流方法,,delay延迟时间,多长时间内禁止重复点击
const that = this
const { timer } = that
let begin = new Date().getTime()
return () => {
const context = that
const args = params
// console.log('args',args);
const current = new Date().getTime()
clearTimeout(timer)
if (current - begin >= duration) {
method.apply(context, args)
begin = current
} else {
that.timer = setTimeout(() => {
method.apply(context, args)
}, delay)
}
}
},
25.2点击事件调用节流方法
保存
saveThrottle() {
this.fnThrottle(this.save, 500, 3000)()
},
26,函数的节流方法2
26.1,写方法
function throttle(fn, gapTime) {
let _nowTime = new Date().getTime();
if (_nowTime - this._lastTime > gapTime || !this._lastTime) {
fn();
this._lastTime = _nowTime;
}
}
26.2,调用方法
this.throttle(this.refundInterface.bind(this), 2000);
27.vue js文件中使用message提示框
import { Message } from 'element-ui'
Message.error(msg)
28.路由懒加载,避免首次加载白屏
{
path: '/home', // 页面路径
component: resolve => require(['@/views/layout.vue'], resolve), //按需加载,懒加载
meta: {
title: '首页' // 面包屑导航
},
children: [ // 子路由
{ path: '/home', component: resolve => require(['@/views/home'], resolve), meta: { auth: false } },
{ //车辆管理
path: '/vehicleManagement',
component: resolve => require(['@/views/vehicleManagement'], resolve),
meta: { auth: false },
},
{ //系统管理
path: '/systemManagement',
component: resolve => require(['@/views/roleManagement'], resolve),
meta: { auth: false },
children: [
{ path: '/roleManagement', component: resolve => require(['@/views/roleManagement'], resolve), meta: { auth: false } } //角色管理
]
},
]
},
29.vue项目配置本地ip打开
30.vue项目编译实时更新
package.json文件下script运行方式后添加–watch,如下图
31.vuex使用
31.1,链接是异步请求数据的情况
附链接:vuex超详细超完整使用链接
31.2 这是项目中写死列表的情况
31.2.1 先安装vuex,然后创建一个store文件,下面创建一个index.js文件,存放vuex公共数据,内容多的话也可分开创建(actions, getters,modules,都要导入到index.js里面),这个里面是创建了一个文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
nowMenu:[],
activeFather:'',
},
getters:{
getNowMenu:state => {
return state.nowMenu
},
getTopPath: state => {
return state.activeFather
}
},
mutations: {
setNowMenu(state,nowMenu){
state.nowMenu = nowMenu
},
setTopPath(state,activeFather){
state.activeFather = activeFather
}
},
actions: {
},
modules: {
}
})
32.2.2 将这个文件挂载到main.js里面
32.2.3更改值
点击事件跟一个更改事件,如changeHandle
changeHandle(){
// 触发store,mutations中的事件setNowMenu
this.$store.commit("setNowMenu", this.allTenantMenu);
}
32.2.3接收值
1.import { mapGetters } from “vuex”;
2.watch中监听store中变量NowMenu变化
watch: {
NowMenu: {
handler(val) {
if (val) {
this.changeMenu(1);
}
},
},
},
3.计算属性中同步监听数据变化
computed: {
...mapGetters({
NowMenu: "getNowMenu",
}),
},
4.页面created一挂载就触发对应更改的方法,
data(){
return {
navMenu :[], // 当前页面要渲染的列表数据
}
},
created() {
this.changeMenu();
},
methods:{
changeMenu(){
// NowMenu是获取store中的数据,可以直接this指
this.navMenu = this.NowMenu;
}
}
32.项目安装sass
按照此链接安装
sass-loader默认最新版本,会报错
给sass-loader降低版本,npm i [email protected] --D即可解决
注:写法是scss,安装是sass
33.router文件下配置项目路由
1.router文件下index.js文件中,‘/‘默认是根路由,即页面一加载默认的路由,如果想要定向到指定路由就重定向(redirect: ‘/home’,)
2,引入组件时,将路径写到resolve=>require([’@/views/order],resolve),meta:{title:‘订单’}}
34.setTimeout和setInterval
setTimeout()是延时器,只会执行一次,常用来演示执行逻辑
setInterval(),是定时器,可循环执行,常用来倒计时,务必要手动清除,,每次setInterval前要进行一次 clearInterval(timer),否则会越来越快
35.实现点击文字,文字后面radio选中效果
这个效果是前端很经常用到和遇到的效果了,实现这个效果的方式也很多,很多朋友用js和jquery来实现,但是最简单的,我们可以直接用lable标签的 for 属性来实现。
看下下面例子:
label 的for属性后面跟着input的id,就可以点击label,来触发input效果了,大家可以试一试!
36.怎么让Chrome支持小于12px 的文字?
这个我们在做移动端的时候,设计师图片上的文字假如是10px,我们实现在网页上之后。往往设计师回来找我们,这个字体能小一些吗?我设计的是10px?为啥是12px?其实我们都知道,谷歌Chrome最小字体是12px,不管你设置成8px还是10px,在浏览器中只会显示12px,那么如何解决这个坑爹的问题呢?
我们的做法是:
针对谷歌浏览器内核,加webkit前缀,用transform:scale()这个属性进行缩放!
haorooms博客测试10px
37.获取屏幕宽高
screenWidth: document.body.clientWidth, // 屏幕宽
screeHeight: document.body.clientHeight, // 屏幕高
38,标签中变量的使用和js中代码使用(``反引号)
this.$message({
type: 'warning',
message: `${error.data.msg}`,
})
39.element中使用dialog组件,拿到数据有误问题
表格组件通过template传递单个数据scope,里面有dialog组件,对话框组件拿到的scope的值是始终是最后一条数据的
40.修改el-input的属性
只需在el-input外层元素上添加一个class类,用外层类名加el-inut即可
.normalForm .halfInputItem .el-input {
width: 50%;
}
41.key报错
42.call使用(通常结合着实例使用)
function myfunc1() {
this.name = 'Lee';
this.myTxt = function (txt) {
console.log('i am', txt);
}
}
function myfunc2() {
myfunc1.call(this); // myfunc1放到this,即myfunc2中执行
}
var myfunc3 = new myfunc2();
myfunc3.myTxt('Geing'); // i am Geing
console.log(myfunc2.name); // Lee
console.log(myfunc3); // 继承了myfunc1函数,上面有myfunc1的属性和方法
43.项目中切换组织,刷新页面后组织信息未更新问题
43.1 app.vue中写个监听的方法,监听页面变化后重新请求用户信息
43.2.页面隐藏的时候,监听事件销毁
43.3 methods中声明对应要调用的方法
methods:{
changeHandle(e){
if(e.target.visibilityState==='visible'){
httpService.getCurrentUser().then((res) => {
if (res.code === 200) {
// console.log(res.data)
let org = globalLocal.getUserInfo().org;
let selfOrg = globalLocal.getUserInfo().selfOrg;
let isChangeOrg = false;
// if(res.data.unitOrganizeId !== selfOrg.unitOrganizeId){
org.length &&
org.forEach((v) => {
v.isSelected = 0;
if (v.unitOrganizeId === res.data.unitOrganizeId) {
v.isSelected = 1;
selfOrg = v;
isChangeOrg = true;
}
});
let user = globalLocal.getUserInfo();
user = { ...user, ...res.data };
user.selfOrg = selfOrg;
user.org = org;
// user["isChangeOrg"] = isChangeOrg;
globalLocal.setUserInfo(user);
// location.reload()
// this.$router.go(0)
// }
} else {
this.$message.error(res.message);
}
});
44.vue项目运行,实时监听更改
45.启动项目显示local和Network地址(2.0项目)
如下图:
45.1开始配置
首先设置localhost和本地ip访问
在config文件下的index.js文件中,修改host为:0.0.0.0
或者在package.json文件下"scripts"的"dev"值后新增–host 0.0.0.0",即
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 0.0.0.0 --watch",
45.2 webpack.dev.conf.js文件下compilationSuccessInfo对象中的messages更改为如下即可
messages: [
`App runing at: `,
`Local: http://localhost:${port}`,
`Network: http://${require('ip').address()}:${port}`,
],
45.3,重启项目即可
45.启动项目显示local和Network地址(3.0项目)
46,创建项目时不小心打开了eeslint校验,如何关闭
build文件----->webpack.base.conf.js文件下,这一行注释掉
或者vue.config.js文件中增加如下代码
47.安装axios报错,如下
原因可能是有缓存,需要清除下,执行命令
npm cache clean -f 重新执行安装axios的指令即可
48.解析token(登录完成后直接将拿到的token解析即可)
1.在cmd中输入以下命令,安装jwt模块
npm install jsonwebtoken
2.在js文件中引用
var jwt = require(“jsonwebtoken”);
3.解码
jwt.decode(‘token’)
49.element 级联选择框动态加载
49.1页面代码``
49.2,设置全局变量id
49.3 data中定义数据
49.4对应的接口
//获取第一级单位
queryTree(node, resolve) {
//此处要将本单位id作为参数提交
findNewAggrement().then((res) => {
const nodes = res.map((item) => {
return {
value: item.id.id,
label: item.label,
leaf: false,
};
});
resolve(nodes);
});
},
//获取下级单位
queryMoreTree(node, resolve) {
//注意此处要将node.value,也就是点击的节点单位的id,作为查询被点击单位下级单位的参数提交
// console.log("--node--", node);
findNewAggrementVersion("0", "999", "&jProtocolId=" + node.value).then(
(res) => {
if (res.data.length === 0) {
resolve({
value: "",
label: "",
leaf: true,
});
} else {
const secNodes = res.data.map((item) => {
return {
value: item.id.id,
label: item.verNo,
leaf: true,
};
});
resolve(secNodes);
}
}
);
},
50.vuex使用,项目中实战
50.1 npm install vuex --save
50.2 创建文件store,x下面创建一个index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
nowMenu:[],
},
getters:{
getNowMenu:state => {
return state.nowMenu
},
},
mutations: {
setNowMenu(state,nowMenu){
state.nowMenu = nowMenu
},
},
actions: {
},
modules: {
}
})
50.3 main.js中挂载vuex
50.4 页面使用
页面直接data中定义的变量navMenu即可
51.根据swagger地址配置前缀
51.1 swagger地址
http://151.111.43.1:9028/ry/swagger-ui.html
51.2 接口地址
即完整的地址为:/ry/api/ie/ry/personnelUnits/queryPersonnelUnits
51.3 config/index.js 文件下配置如下
51.4 页面请求的地址为(http:192.168.14.8080为本机地址),意义就是请求的地址简写,实际上请求的路径还是很长的,就看着美观而已
http:192.168.14.8080/ry/personnelUnits/queryPersonnelUnits
52.filter过滤器使用
53.导出excel 表格
const param={
aaa:"123" // (根据后端要求传即可)
}
startExport(param) {
axios({
url: process.env.VUE_APP_BASE_API + '/px-contract-extranet/sdcontractsign/contractSignExportNew',
method: 'post',
data: param,
responseType: 'arraybuffer'
})
.then(response => {
// 创建一个blob对象,file的一种
const blob = new Blob([response.data], {
type: 'application/octet-stream'
})
const link = document.createElement('a')
const href = window.URL.createObjectURL(blob)
link.href = href
// 配置下载的文件名
link.download = '日汇总合同曲线' + this.$moment(new Date()).format('YYYY-MM-DD') + '.xlsx'
document.body.appendChild(link)
link.click() // 点击下载
document.body.removeChild(link) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
})
.catch(() => {
this.$vMessage({
message: '导出失败',
type: 'warning'
})
})
},
54.vue项目Eslint校验警告(前提是项目使用了eslint校验)
**54.1配置设置中setting,右上角有个小书页,粘过去**
{
"eslint.enable": true,
"eslint.autoFixOnSave": true,
"eslint.run": "onSave",
"eslint.options": {
"extensions": [
".js",
".vue"
]
},
"eslint.validate": [
"javascriptreact",
"vue",
"javascript",
{
"language": "vue",
"autoFix": true
},
"html",
{
"language": "html",
"autoFix": true
}
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"[vue]": {
"editor.defaultFormatter": "octref.vetur"
},
"diffEditor.ignoreTrimWhitespace": false,
"diffEditor.renderSideBySide": false,
"editor.fontSize": 16,
"editor.tabSize": 2,
// "editor.formatOnSave": true, //针对prettier
"editor.renderIndentGuides": false,
"files.autoSave": "onWindowChange",
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"vetur.validation.interpolation": false,
"[javascript]": {
"editor.defaultFormatter": "HookyQR.beautify"
},
"fileheader.customMade": { //此为头部注释
"Description": "",
"Autor": "fuxiaojie",
"Date": "Do not edit",
"LastEditTime": "Do not edit"
},
"fileheader.cursorMode": { //此为函数注释
"description":"",
"param": "",
"return": "",
"author":"zhouchenchen"
},
"window.zoomLevel": 1,
}
54.2 插件安装
eslint beaulity veture
55.vue 动态加载组件
56.ip地址输入组件
1,组件
-
57.解决跳转同一路径报错问题
57.1 main.js 中加这一段代码
import Router from 'vue-router'
// 解决重复跳转一个路径的报错问题
const routerPush = Router.prototype.push
Router.prototype.push = function push(location) {
return routerPush.call(this, location).catch(error=> error)
}
58.vue页面中watch 使用
58.1 watch 用来监听数据的变化,data中的数据或者组件传来的数据都行
58.2 .使用场景,分页切换时监听,从而获取新数据,组件编辑更改的时候也可以使用
58.3监听对象中属性的写法
'demo.sex':{
handler: function(newValue, oldValue) {
...
},
59.js 二进制精度问题,输入0.3 显示0.300000000004
Number(0.3000000004).toFixed(2) // 保留几位小数toFixed后面就写几
60.多请求同时进行
Promise.all([
query.request({ url: "/statistics/day/total", data }),
query.request({ url: "/statistics/day/detail", data }),
])
.then((res) => {
// res[0],,上面总数,,res[1],下面表格数据
this.total = res[0].data.total;
(this.normal = res[0].data.checkSucc), //考勤正常人数
(this.workPeople = res[0].data.checkInSuccNum), // 上班已打卡人数
(this.offWorkPeople = res[0].data.checkOutSuccNum), // 下班已打卡人数
(this.gjNormalPeople = res[0].data.locusSuccNum); //轨迹正常人数
// 对勾,叉的逻辑下面表格渲染
this.dataList = res[1].data;
})
.catch((err) => {
});
61. 96刻钟时间格式化方法
// 00:00点 00:15点 00:30点 00:45点 01:00点
formatTime(serial) {
// 传值是1-96,值是对应的96个刻钟
const time = (serial - 1) * 15 // 总分钟数
const hour = Math.floor(time / 60) >= 10 ? Math.floor(time / 60) : '0' + Math.floor(time / 60)
const minute = time % 60 === 0 ? '00' : time % 60
return hour + ':' + minute
},
62.清除表单某一项校验
this.$refs[‘formName’].clearValidate(‘xxx’)
63.字母和数字不换行问题
css加如下两行
word-break:break-all;word-wrap:break-word
64.修改表单内容后又新增表单,表单清空不生效问题
this.KaTeX parse error: Expected '}', got 'EOF' at end of input: …{ this.refs.ruleFormDialog.resetFields()
Object.assign(this.ruleFormDialog, this.$options.data().ruleFormDialog)
})
65. el-table 表头和内容没对齐问题解决
el-table 加ref属性,如ref=“formatTable”,获取到表格数据之后加如下一行
this. r e f s . f o r m a t T a b l e . refs.formatTable. refs.formatTable.el.style.width = ‘99.99%’
66.request请求设置请求超时时间
66.1 customConfig设置
return request({
url: baseUrl + ‘/xxxxxx’, // 接口地址
method: ‘post’,
data: data,
customConfig: { timeout: 9000 }
})
66.2 第二种方式
static processGraph(data) {
request.defaults.timeout = 300000
return request({
url: '/px-common-workflow/workflow/queryProcessGraph',
method: 'post',
data: data
})
}
67,循环跳出
业务逻辑中有循环跳出的时候,只能用for循环,map(返回一个新数组),forEach等方法都不行
68. el-date-picker设置只可选择某一个月
68.1 el-data-picker 标签上添加:picker-options=“pickerChooseTime”
68.2 data 中添加如下方法pickerChooseTime
pickerChooseTime: {
disabledDate: (time) => {
// this.changeMonthSelect 是外层选择的月份
const mouth = this.changeMonthSelect.getMonth()
const year = this.changeMonthSelect.getFullYear()
const monthStart = new Date(year, mouth, 1)
const monthEnd = new Date(year, mouth + 1, 0)
return (time.getTime() > monthEnd || time.getTime() < monthStart)
69.字体大小12px限制修改
-webkit-text-size-adjust:none;或者transform 缩放
70.el-table 锁定二级表头后一级表头文字不展示问题解决
70.1 锁定二级表头部分列一级表头二级表头都要加fixed属性,并且一级表头要加width属性
70.2 style中加如下样式
/deep/ .el-table th.is-hidden>*, /deep/ .el-table td.is-hidden>* {
visibility: visible
}
71. 项目操作时提示文件名过长解决
git config --system core.longpaths true
72 change事件传val和其他参数
@change="changeHandle($event,'111')"
73.小数相加精度丢失(六位小数为例)
const numberMonth = monthArr.reduce((prev, curr) => {
return (Number((Number(curr) * 1000000).toFixed(0)) + Number((Number(prev) * 1000000).toFixed(0))) / 1000000
// return addtion(prev, curr)
}, 0)
74,mixin使用(存放页面公共变量)
74.1 创建一个mixin.js文件(类似如下,可写方法,变量等)
/*
* @Description:
* @Autor:
* @Date: 2022-11-28 15:09:28
* @LastEditTime: 2022-12-02 09:16:34
*/
import './styles/common.scss'
import PageConfigSerivce from '@/service/config/PageConfigSerivce.js'
import CurveManageApi from './api/MyCurveApi.js'
import moment from 'moment'
export default {
data() {
return {
pageObj: PageConfigSerivce.getPageObj(),
CurveManageApi: CurveManageApi
}
},
methods: {
formatDateMonth(row) {
return moment(row.ymDate).format('YYYY-MM')
},
formatDate(row) {
return moment(row.createDate).format('YYYY-MM-DD hh:mm:ss')
},
onKeyup(e) { // 输入0到1正则
e.target.value = e.target.value.replace(/[^\d.]/g, '')
if (e.target.value > 0.99) {
e.target.value = ''
}
if (e.target.value.length > 2) {
(!/^(1|0(\.\d{1,2})?)$/.test(e.target.value)) && (e.target.value = '')
}
return e.target.value
},
stlHeader() { // 样式居中
return 'text-align:center;'
}
}
}
75.箭头流程图css
{{item.id}}
{{!item.isDisabled?item.name:''}}
75.2 data中定义step和模拟的数据
step: 2, // 步骤,默认第一步
dealpieData: [
{
id: 1,
name: '通知',
color1BG: '#1EB678',
color2BG: '#75D8AF ',
color3BG: '#75D8AF',
colorText1: '#fff',
colorText2: '#fff',
colorText3: '#fff',
colorNumm1:'#1EB678',
colorNumm2:'#1EB678',
colorNumm3:'#1EB678'
},
{
id: 2,
name: '签到',
color1BG: '#F5F6F9',
color2BG: '#1EB678 ',
color3BG: '#75D8AF',
colorText1: '#666',
colorText2: '#fff',
colorText3: '#fff',
colorNumm1:'#666',
colorNumm2:'#1EB678',
colorNumm3:'#1EB678'
},
{
id: 3,
name: '参与',
color1BG: '#F5F6F9',
color2BG: '#F5F6F9 ',
color3BG: '#1EB678',
colorText1: '#666',
colorText2: '#666',
colorText3: '#fff',
colorNumm1:'#666',
colorNumm2:'#666',
colorNumm3:'#1EB678'
}
]
75.3 css如下
.flow-charts {
width: 100%;
display: flex;
justify-content: center;
.flow-charts-single {
flex: 1;
height: 30px;
background: var(--color);
position: relative;
display: inline-block;
margin-right: 34px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-bottom-right-radius: 2px;
border-top-right-radius: 2px;
.text {
font-size: 12px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #666666;
line-height: 12px;
.textNum {
display: inline-block;
width: 18px;
height: 18px;
border-radius: 18px;
background-color: #fff;
color: #666666;
font-size: 13px;
line-height: 18px;
margin-right: 8px;
}
}
&::after {
content: '';
border-bottom: 16px solid transparent;
border-left: 26px solid var(--color);
border-top: 16px solid transparent;
position: absolute;
right: -25px;
top: 0;
}
&::before {
content: '';
border-bottom: 16px solid var(--color);
border-left: 26px solid transparent;
border-top: 16px solid var(--color);
position: absolute;
left: -25px;
top: 0;
}
&:first-child {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
&::before {
display: none;
}
}
&:last-child {
margin-right: 0;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
&::after {
display: none;
}
}
}
}