1.今天遇到个东西又加深了我的理解
给一个对象动态添加属性,然后el-input会绑定这个属性,然后发现,输入不了
后来想起来似乎是因为v-model的数据必须是被双向绑定追踪的数据,这样动态加的它没追踪的,于是用$set就可以了,哈哈
2.vue watch深度监听对象,新值和老值打印出来结果一致,都是最新的改变的那个属性的值,怎么解决?
这个问题,在公司开发的时候发现的
然后找到了两种解决方案,一种是不监听对象了,直接监听那个属性,不过这种局限太大,我肯定都要监听啊,不能只监听一个,业务需要
还一种,就是先写个computed返回这个对象的序列化json,然后watch监听这个computed,打印反序列化的新值旧值就行了
可以看看这两篇文章 http://www.imooc.com/article/286654 https://juejin.cn/post/6898347237173100558
3.cup密集型和io密集型
我们可以把任务分为计算密集型和IO密集型
什么是io密集型 简单来说就是io不太行,io太密集了扛不住
什么是cpu密集型,简单来说就是cup不太行,cpu计算强度太高扛不住
4.关于for循环的阻塞
https://zhidao.baidu.com/question/681246436992069252.html
https://www.cnblogs.com/hq233/p/8042995.html
5.正则的一些操作
https://blog.csdn.net/weixin_43788143/article/details/111871973 取中间,不取两边
还有这个,效果的话运行就知道了
// let str = "asfsasdf,$dc{asfsd},$dc{$dc{asdfasdf}},sadf\n";
// let str = "$dc{asfsd}\n";
// let str = "$dc{$dc{asdfasdf}}\n";
let str = "$dc{d}\n";
let flag = /(\$dc\{){1}\S+(\}){1}/g.test(str);
// let arr = str.match(/(\$dc\{){1}\S+(\}){1}/g);
let arr = str.match(/(?<=(\$dc\{))\S+(?=(\}))/g);
console.log(flag, arr);
6.获取对象长度 Object.keys()这个真的好用,感觉好多关键时候都用到了
https://www.cnblogs.com/ranyonsue/p/8494440.html
7.关于迭代器生成器与promise,反射,代理等
https://www.cnblogs.com/xiaohuochai/p/7253466.html https://blog.csdn.net/ligang2585116/article/details/79889527 https://www.jianshu.com/p/e8b68345bfdb https://cloud.tencent.com/developer/article/1410180
8.如果await接收的promise没有resolve,那么就会阻塞住
async function fuck() {
console.log(1)
await new Promise((rs, rj) => {
rs()
})
console.log(2)
}
fuck()
运行这段代码,尝试注释与不注释rs函数,看看效果
9.Object.keys()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
10.RSA加密解密
有很多包都有rsa加解密
这里列举一个包 jsencrypt
下包,然后 创个工具文件导出
import { JSEncrypt } from 'jsencrypt'
// 加密公钥
const publicKey= 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKjD/7zI9q6TbLVW5Qdp7Rm0C/vhPnrmI+pLRSMdJMLaazDvI8OAh7BR4RXHxstahA0CgZAnKNqCw3b9tHWNZrECAwEAAQ=='
// 加密
function setEncrypt (msg) {
const jsencrypt = new JSEncrypt()
jsencrypt.setPublicKey(publicKey)
return jsencrypt.encrypt(msg)
}
// 解密私钥
const privateKey = `MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAqMP/vMj2rpNstVblB2ntGbQL++E+euYj6ktFIx0kwtprMO8jw4CHsFHhFcfGy1qEDQKBkCco2oLDdv20dY1msQIDAQABAkBTFWrpfeYzu9Bg1g6av8NCTCk6L4Ga74Hu7m9zAf3/Dsu/he2W5Nb02aFYoZsBSuylwiMya33GBfteaoPa3NoBAiEA1xF0h7qEGTAxXMN0rvXVdlhpIt8+KG7kE4B4v1V2JokCIQDI4peDnzcZz0b/cpxQ4FO/sAnXpAjtvw+6RlNtj4y06QIgJNK7RgX8WiezO/PHRbGXs+SdU7gvd1LNQD2N7wyd5ykCIQCYt+LV9pGuNm1UQC5kMdaZcNxaquL603jCdTpxnWMsGQIhAJuYBx8aLNKZFcHDA0+ExG3LTqDRwzMXzgvx26gjn3IA`
// 解密
function decrypt (msg) {
let decrypt = new JSEncrypt()
decrypt.setPrivateKey(privateKey)
var decryptMsg = decrypt.decrypt(msg)
return decryptMsg
}
export default {setEncrypt,decrypt}
然后引入 进行加解密
import CryptTools from 'mone-test/utils/rsaCrypt'
let a = '123'
let b = CryptTools.setEncrypt(a)
let c = CryptTools.decrypt(b)
console.log(a, b, c);
可以看看这篇文章 讲的很好https://blog.csdn.net/weixin_42423019/article/details/82468626
11.校验ip正则
https://www.cnblogs.com/sirdong/p/12354930.html
12.用自执行函数包起来隔绝变量污染冲突 为什么自执行函数隔绝了作用域呢
// 用自执行函数
; (() => {
let a = 8
})()
; (() => {
let a = 9
console.log(1232)
})()
; (function fuck(win) {//这里接
console.log(win)//打印出node全局变量 global
let a = 10
console.log(1315)
})(global)//这里 传 这里传还是能传全局作用域的东西进来
// 那么至于这个自执行函数本身是在哪个作用域里呢
// 试着打印了一下,发现访问不到
// console.log(fuck) //fuck未定义
// 那么说明它本身也不属于全局作用域
// 说明()() 前面这个小括号就是这么神奇,可一个隔绝作用域
// 不报错
// ()() 这就是自执行函数,后面的括号代表调用,那么前面的括号势必要包
// 一个函数才行,毕竟后面要调用
// 而众所周知,函数是有作用域的,所以函数里的变量都不会被外面访问到
// 就不会互相污染了
// 自执行函数隔绝作用域
// 不用自执行函数
// let a = 8;
// let a = 9;
// 报错,变量重复定义, Identifier 'a' has already been declared
13.js滑动拼图
https://www.jianshu.com/p/16f7b55ddc6d
14.js词云插件
https://www.zhihu.com/question/355726361/answer/903099293
15.删除命令
可以用来删除node_modules 速度会快一点
https://www.cnblogs.com/xuepei/p/9429533.html
16.vue传值加冒号与不加冒号区别
https://blog.csdn.net/goudexingwu/article/details/104065164
就是都是一样的传值,只是用冒号的话,传的那个值会被当做变量读取其值
就像对象的[]一样,如果你用 obj['flag'] = 1
那么就是得到这个 { flag:1 }
而如果你是这样 let flag = 'hhh' obj[flag] = 1
那么得到的是这个 { hhh:1 }
17.keep alive学习
https://www.jianshu.com/p/ade6044185ad
原来keep alive的组件,不会触发那八个生命周期了
而是另外两个生命周期
18.element table
如何让内容超出table但是不会隐藏掉,默认是隐藏的
只需要
::v-deep .el-table {
overflow: auto;
}
::v-deep .el-table__footer-wrapper {
overflow: unset;
}
::v-deep .el-table__header-wrapper {
overflow: unset;
}
::v-deep .el-table__body-wrapper {
overflow: unset;
}
::v-deep .el-table .cell {
overflow: unset;
}
::v-deep .el-table__column-resize-proxy {
display: none;
}
不过这里两个东西以这个单元格为定位,还得在单元格上加个position relative
当然了,这种情况也可以用,el-popver
19.npm 或者yarn 吧项目打包成插件
"build:lib": "node build/build-lib.js",
```
yarn build:lib
yarn pack
```
然后得到一个tgz包
然后需要引用这个包的项目
使用yarn add file:包路径地址(一直到包名) 或者用npm
就能使用到这个包了,可以再dependence里看到,这就是npm包打包和下包
20.后台管理项目 git上的
https://github.com/PanJiaChen/vue-element-admin
21.https://www.jianshu.com/p/d42c508ea9de
这篇文章吧vue的sync讲透了,父子组件传值的双向绑定
不过其实我之前试过,好像你不用sync普通传值,它也是能够实现子组件改了传的值,父组件的也变了。。。回去验证下
22.刚刚试验了一个事情,就是请求头和请求体响应头,响应体(响应的话就是后端设置了)的内容是否是可以随便加的
然后发现是这样的,除了可以设置改变它内置的一些属性,比如conten-type啥,
而且还可以加自定义属性,比如我加了个mytoken 值是'token123' 请求的时候会发现请求头上也带着,所以说其实请求头和请求体响应头,响应体都是对象而已,当成对象增减属性就好了
23.vue的filters里拿不到this,如果需要的话就用的时候传进去,传method里的方法,data里的属性,啥的都行
或者外部引入的,它可以直接用,就是import引入的那种
https://blog.csdn.net/yehaocheng520/article/details/111998420?spm=1001.2014.3001.5506
24.关于get请求编码解码是为啥
可以看看这篇文章https://blog.csdn.net/Boboma_dut/article/details/79629553
然后ajax原生是没帮你做编码解码的,你要自己手动加
具体是这两个api
encodeURIComponent(url) 编码
decodeURIComponent(url) 解码
而axios似乎是帮你做了这个操作
估计fetch也是
然后想试试效果直接取菜鸟那里试 https://www.runoob.com/try/try.php?filename=tryjsref_encodeuricomponent
25.有个小问题,就是vscode那个eslint格式化老是自动去掉函数前的空格,后来的解决方法是把prettier那个格式化插件也安装就好了。。。。
26.发现自己有时候老是犯傻
今天调个接口,想await这个接口之后再执行接下来的操作
但可惜的是,这个接口用fetch封装的,总之就是它返回的不是一个promise,然后我居然就卡了半天,其实你再包一层promise 吧resolve放在需要resolve的地方一样的啊。。
代码如下
beforeToAddApi = (dinterface) => {
const params = {
input: { urlcode: dinterface },
sys: {
prcscd: "tranAutoCommit",
},
};
this.setState({ flag: false });
return new Promise((resolve, reject) => {
AgileTestService.tranAutoCommit(params, (res) => {
if (res && res.sys && res.sys.status == "S") {
// if (res.output.issuce == "true") {
const dirinfo = res.output.result;
this.setState({ diffDetail: dirinfo, flag: true });
debugger;
resolve();
// } else {
// message.error(res.output.mesage);
// }
} else {
message.error(res.sys.erortx);
}
});
});
};
addApi = async (record) => {
const self = this;
// await new Promise((resolve, reject) => {
// self.beforeToAddApi(record.dinterface);
// debugger;
// if (self.state.flag) {
// debugger;
// resolve();
// }
// });
await this.beforeToAddApi(record.dinterface);
debugger;
const tradir = localStorage.getItem("INTERMODULE");
// localStorage.setItem('INTERMODULE', selectedKeys[0]);
const { labelList, dirList } = this.state;
// if (!tradir) {
// message.error(i18n.selectDirectory);
// } else {
let list = {
id: "",
key: "add",
};
list = JSON.stringify(list);
hashHistory.push({
pathname: "/test/InterfaceManage/AddInterface",
query: {
id: list,
labelList: JSON.stringify(labelList),
dirList: JSON.stringify(dirList),
},
});
// }
};
27.element-ui组件中的input等的change事件中传递自定义参数
@input="val=>inputStatus(val, index)"
@change="val=>changeStatus(val, index)"
https://www.cnblogs.com/ttjm/p/10904160.html
28.el-select一个小bug,解决了,不好说,直接贴代码吧
<template>
<div class="test-resource-pool">
<p class="title">请选择测试资源池:</p>
<el-radio-group v-model="radio" @change="handleSwitch">
<el-radio label="virtualMachine">虚拟机资源</el-radio>
<el-radio label="container" style="margin-right: 60px">容器资源</el-radio>
</el-radio-group>
<!-- 虚拟机资源表格 -->
<el-table
v-show="radio == 'virtualMachine'"
:size="size"
:data="tableData"
border
class="virtual-table"
>
<el-table-column prop="id" label="主机名" width="238">
<template slot-scope="scope">
<div>
<el-select
:disabled="!editStatus"
:size="size"
v-model="scope.row.id"
placeholder="请选择虚拟机"
@change="handleChange"
>
<el-option
v-for="item in vListCompute"
:key="item.id"
:label="item.hostName"
:value="item.id"
></el-option>
</el-select>
</div>
</template>
</el-table-column>
<el-table-column prop="ip" label="IP+Port" width="249"></el-table-column>
<el-table-column prop="id" label="权重(%)" width="119">
<template slot-scope="scope">
<div>
<el-input
@input="val=>weightInput(val,scope.$index)"
:disabled="!editStatus"
:size="size"
v-model="scope.row.weight"
></el-input>
</div>
</template>
</el-table-column>
<el-table-column prop="id" label="操作">
<template slot-scope="scope">
<div class="button-style">
<p class="btn-add" @click="addVirtual">增加</p>
<p>|</p>
<p class="btn-delete" @click="deleteVirtual(scope.$index)">删除</p>
</div>
</template>
</el-table-column>
</el-table>
<el-form
ref="dockerForm"
:model="dockerForm"
:rules="dockerFormRules"
label-width="120px"
v-show="radio == 'container'"
>
<el-form-item label="容器资源:" prop="ids">
<el-select
:size="size"
v-model="dockerForm.ids"
placeholder="请选择容器资源"
style="width: 367px"
:disabled="!editStatus"
>
<el-option
v-for="item in containerList"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div class="btn-bottom">
<el-button :size="size" style="margin-left: 10px" v-show="!editStatus" @click="handleEdit">编辑</el-button>
<el-button :size="size" v-show="editStatus" type="primary" @click="handleSave">保存</el-button>
<el-button :size="size" v-show="editStatus" @click="handleReset">重置</el-button>
</div>
</div>
</template>
<script >
import Tools from "pte-ui/utils/Tools";
import { urlConfig } from "@/services/API.js";
import MyAxios from "pte-ui/utils/MyAxios";
const rowData = {
id: "",
ip: "",
weight: 0
};
export default {
name: "TestResourcePool",
components: {},
props: {},
data() {
return {
radio: "virtualMachine",
tableData: [],
editStatus: false,
dockerForm: {
ids: ""
},
dockerFormRules: {
host: [{ required: true, message: "请选择容器资源", trigger: "change" }]
},
size: "mini",
vList: [], //虚拟机资源列表
containerList: [], //容器资源列表
vListCompute: []
};
},
async created() {
await this.getVList();
await this.getContainerList();
this.getProject();
},
mounted() {},
methods: {
/**
* 查询项目,获取virtual和container信息
*/
getProject() {
MyAxios.invokeAPI(
`${urlConfig.addProject}/${this.$attrs.currentProjectId}`,
"GET"
)
.then(res => {
if (res && res.code == 200) {
if (
res.data.virtualMachines &&
res.data.virtualMachines.length != 0
) {
this.tableData = res.data.virtualMachines.concat();
// 等表格值渲染好了,这个时候要主动执行一下change事件,触发动态下拉
// 不过如果太紧凑,就会有问题,所以这里要异步弄一下。。
setTimeout(() => {
this.tableData.map(el => {
this.handleChange(el.id);
});
}, 0);
this.$refs.dockerForm.resetFields();
} else if (res.data.container) {
this.$set(this.dockerForm, "ids", res.data.container.id);
this.tableData = [].push({ ...rowData });
} else {
this.$refs.dockerForm.resetFields();
this.tableData = [].push({ ...rowData });
}
}
})
.catch(err => {});
},
/**
* 查询所有虚拟机资源不分页
*/
getVList() {
return MyAxios.invokeAPI(urlConfig.getVList, "GET")
.then(res => {
if (res && res.code == 200) {
this.vList = res.data.map(el => ({
hostName: el.hostName,
ip: el.ip,
id: el.id
}));
this.vListCompute = this.vList.concat();
}
})
.catch(err => {});
},
/**
* 查询容器资源列表不分页
*/
getContainerList() {
return MyAxios.invokeAPI(urlConfig.getContainerList, "GET")
.then(res => {
if (res && res.code == 200) {
this.containerList = res.data.map(el => ({
name: el.name,
id: el.id
}));
}
})
.catch(err => {});
},
/**
* 切换时
*/
handleSwitch(val) {
this.getProject();
},
/**
* 保存时
*/
handleSave() {
let param = {};
let formName = "";
if (this.radio == "virtualMachine") {
// param.ids = this.virtualForm.ids;
param.type = this.radio;
// formName = "virtualForm";
} else {
param.ids = this.dockerForm.ids;
param.type = this.radio;
formName = "dockerForm";
}
this.$refs[formName].validate(valid => {
if (valid) {
MyAxios.invokeAPI(
`${urlConfig.setResourcePool}/${this.$attrs.currentProjectId}?ids=${param.ids}&type=${param.type}`,
"POST"
)
.then(res => {
if (res && res.code == 200) {
this.$message({
message: "配置成功",
type: "success"
});
}
})
.catch(err => {
this.$message({
message: "配置失败",
type: "error"
});
});
}
});
},
/**
* 重置
*/
handleReset() {
MyAxios.invokeAPI(
`${urlConfig.resetResourcePool}/${this.$attrs.currentProjectId}?type=${this.radio}`,
"POST"
)
.then(res => {
if (res && res.code == 200) {
this.$message({
message: "重置成功",
type: "success"
});
this.getProject();
}
})
.catch(err => {
this.$message({
message: "重置失败",
type: "error"
});
});
},
/**
* 虚拟机资源下拉改变时
*/
handleChange(val) {
this.vListCompute = this.vList.filter(el => {
return !this.tableData.find(item => el.id == item.id);
});
let index = this.tableData.findIndex(el => el.id == val);
let item = this.vList.find(el => el.id == val);
this.$set(this.tableData[index], "ip", item.ip);
},
/**
* 增加虚拟机
*/
addVirtual() {
this.tableData.push({ ...rowData });
},
/**
* 删除虚拟机
*/
deleteVirtual(index) {
this.tableData.splice(index, 1);
},
/**
* 编辑点击处理
*/
handleEdit() {
this.editStatus = true;
if (this.tableData.length == 0) {
this.tableData.push({ ...rowData });
}
},
/**
* 权重验证,如果目前权重符合,就按目前的,否则就除以数量算出来
* 这是编辑的时候,切换,保存的时候,则就按照查出来的权重
*/
weightCheck() {},
/**
* 权重输入
*/
weightInput(val, index) {
console.log(val, index);
this.tableData[index].weight = val.replace(/[^\d]/g, "");
// this.leftComp1 = `rand('${this.min}', '${this.max}')`;
// this.tempGetParamConstruct();
}
}
};
</script>
<style lang='less' rel='stylesheet/less' type='text/less' scoped>
.test-resource-pool {
p {
margin: 0;
padding: 0;
}
.title {
margin-left: 20px;
font-family: "微软雅黑";
font-weight: 400;
font-style: normal;
font-size: 13px;
color: #333;
}
.el-radio-group {
margin: 15px 0 0 40px;
}
::v-deep .el-radio__input.is-checked + .el-radio__label {
color: #333;
}
.el-form {
margin-left: 20px;
}
.el-form-item__label {
font-family: "微软雅黑";
color: #333;
font-weight: 400;
font-style: normal;
font-size: 12px;
}
.btn-bottom {
margin-left: 250px;
margin-top: 50px;
}
.virtual-table {
margin: 20px 30px 0 30px;
max-height: 300px;
overflow: auto;
width: 90%;
.button-style {
color: #437dce;
.btn-add,
.btn-delete {
cursor: pointer;
}
}
}
}
</style>
28.
大于等于0小于等于100的正数用正则表达式表示
可以有小数:^100$|^(\d|[1-9]\d)(\.\d+)?$
不可以有小数:^100$|^(\d|[1-9]\d)$
29.vue父子组件生命周期执行顺序
30,dto什么意思
就是数据传输对象
https://www.cnblogs.com/simple-blog/p/7071740.html看看这个
31.关于dom到底是啥,和html和js啥关系
看这两篇文章
https://blog.csdn.net/weixin_44296929/article/details/103524070
https://www.cnblogs.com/buwuliao/p/9814627.html
而我们要想操作这些HTML节点,就引出了DOM的概念,DOM就是HTML 和 XML的编程接口,通俗的讲就是我们要想使用编程语言或脚本操作文档,就必须用到这些接口,即操作HTML文档就需要HTML DOM,操作XML文档就需要XML DOM,另外还有核心DOM,它可以针对任何结构化文档的标准模型,所以有了HTML DOM,我们可以间接的操作HTML文档。
相当于DOM是一个底层API;JS通过对底层API进行封装,提供了简单的操作方法;我们用JS最多,但如果不用JS,其他语言同样可以通过DOM操作HTML。这就是三者之间的关系了
32.输入框输入数字
numberReplace(value) {
let result = value
.replace(/[^\d]/g, "") //把非数字替换为空
.replace(/^$/g, 0) //吧空替换为0
.replace(/\d+$/g, result => +result); //吧05这种替换为+05,会转换成5
return result;
}
33.弹性盒子挤压了宽度的话,
设置flex-shrink:0可以让宽度保持,不被挤压
https://www.cnblogs.com/blogs-xlf/p/12332009.html
34.vue中key真的特别重要。。
今天遇到一个bug
一个页面用了两个一样的组件
但是他们传的是两份不同的数据
但是页面渲染切换的时候,他们会有一些bug
开始我以为是数据的问题
后来发现没加key,加了就正常了