前言

记录平时遇到的技术问题和学习到的新知识


form表单提交

使用form表单提交不会有跨域的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<form id="formId"
action="http://localhost:3000"
method="get">
<label>
<input type="text" placeholder="请输入手机号" id="inputId" name="mobile"
pattern="^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$"
required
>
</label>
<input type="submit" value="提交"/>
</form>

window.onload = function () {
var form = document.getElementById('formId')
var input = document.getElementById('inputId')
// form表单提交会先走下面的事件
form.onsubmit = function (e) {
e.preventDefault() // 会阻止表单提交
var value = input.value
var params = Base64.encode(value) // 使用Base64.js加密
input.value = 'xxxx' // 可以修改提交表单的值
form.submit() // 手动提交
input.value = '' // 清空vale
}
}

// 使用form表单提交无刷新
<form target="myIframe"></form> // 使用target
<iframe name="myIframe" style="display: none"></iframe>
// 该方法也可以是手动提交触发

路由参数补充

1
2
3
4
5
/* 路由注意点
1:路由传递参数(对象写法)path是否可以结合params参数不可以一起使用
2:指定params参数可传可不传,在path路径后加上?,如 /:xxx?
3:params参数但是如果传递是空串,则应该是undefined,如:xxx || undefined?
4:使用路由可以同时带params和query参数 */

vue的provide与inject

1
2
3
4
5
6
7
8
9
// 在爷孙传参中可使用(爷->孙)
// 父组件
provide(){
return {
getMap: this.getMap
}
}
// 子组件(孙组件)
inject:['getMap']

vue的$attrs与$listeners

$attrs就是一个容器对象,这个容器对象会存放:父组件传过来的且子组件未使用props声明接收的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// $attrs使用
// 在父组件传递的参数没事使用props接收会在$attrs里面存放
<father>
<Child
:msg0="msg0"
:msg1="msg1"
/>
</father>
// 子组件接收参数
props:['msg0'],
created(){
this.$attrs // 里面存放的就是msg1(未被接收的props)
}

// 在爷孙传值中,可以父元素直接v-bind="$attrs"传递给孙组件

export default {
// $attrs一般搭配interitAttrs 一块使用
inheritAttrs: false, // 默认会继承在html标签上传递过来的数据,类似href属性的继承
// 默认情况父作用域的不被认作 props 的 attribute 绑定
// 简单说就是绑定的属性没有props接收,组件根标签就会有该属性,但是style不受影响

/*
孙子组件通过props,就能接收到父组件传递过来的$attrs了,就能拿到里面的数据了,也就是:
爷传父、父传子。即:祖孙之间的数据传递。
*/


};

// ------------------------------

// listeners的使用
// 作用是将父的v-on自定义事件绑定到该组件上
// 使用$listeners可以实现孙组件的数据传递到爷组件中去
// 爷组件
<fu @fromSun="fromSun"></fu>
methods: {
fromSun(payload) {
console.log("孙传祖", payload);
}
}
// 父组件中
<sun v-bind="$attrs" v-on="$listeners"></sun>
// 类似于:<sun v-bind="$attrs" @fromSun="fromSun"></sun>
// 子组件(触发爷组件的方法)
methods: {
sendToZu() {
this.$emit("fromSun", this.data);
}
}

生成目录树结构

1
2
3
// windows 自带tree命令
// 指定生成到 name.text 文件
tree > name.txt

JSON格式转化正则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* JSON.stringify和JSON.parse都有第二个参数
* 如是:函数,每个属性都会经过该函数的转换和处理;
* 如是:数组,只有包含在这个数组中的属性名才会被序列化;为null或未提供所有属性都会被序列化;
*
* JSON.stringify第三个参数,用于增加返回的JSON字符串的可读性
* 如:4或"\t"
*/


// json字符串转json对象
export function parseJson(jsonStr) {
return JSON.parse(jsonStr, (k, v) => {
try {
// 将正则字符串转成正则对象
if (eval(v) instanceof RegExp) {
return eval(v);
}
} catch (e) {
// nothing
}
return v;
});
}

// son对象转json字符串
export function stringifyJson(json) {
return JSON.stringify(json, (k, v) => {
// 将正则对象转换为正则字符串
if (v instanceof RegExp) {
return v.toString();
}
return v;
});
}

vue的环境变量

1
2
3
4
5
6
7
8
9
10
// 只能是 NODE_ENV,BASE_URL 和以 VUE_APP_ 开头的变量
# 环境
NODE_ENV = development
# 请求地址
VUE_APP_BASE_API = ''

/* Vue-Cli中BASE_URL在vue.config.js中配置,
注意:BASE_URL从Vue-CLI3.3起已弃用,请使用publicPath
router里面的base: process.env.BASE_URL作用:
当publicPath配置后相当于在/xxx/目录下路由生效(不然输入地址路由响应出现问题) */

在字符串中使用正则的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
字符串的函数:
match()
格式:字符串.match(正则)
功能:在字符串匹配是否符合正则表达式
返回值:匹配成功,返回装有匹配到字串的数组
匹配失败,返回null
replace()
格式:字符串.replace(oldStr/正则,newStr);
功能:用newStr将oldStr替换
返回值:替换成功的新字符串
split()
格式:字符串.split(分割符/正则);
功能:用分割符将原字符串进行分割
返回值:分割剩下的字串组成的数组
search()
格式:字符串.search(字串/正则)
功能:找到符合条件的字串第一次出现的位置
返回值:
如果找到,返回>=0的下标否则,返回-1

npm补充

1
2
3
4
5
6
7
// 查看全局安装
npm list --depth 0 -g
// 全局卸载
npm uninstall -g name

// 注意laragon和本地的cmd的是不同的npm库,两者没有关系
// webstorm和vscode使用cmd (终端将默认的powershell换成cmd)

参考:webstorm配置cmd vscode配置cmd


vue使用SvgIcon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// components新建SvgIcon组件

<template>
<svg class="svg-icon" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>

<script>
export default {
name: "SvgIcon",
props: {
iconClass: {
type: String,
required: true
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
}
}
}
</script>

<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>

// scr下新建icons
// 其中svg目录放下载的svg文件
// 要能使用需要安装svg-sprite-loader
yarn add svg-sprite-loader --dev
// 配置 vue.config.js
chainWebpack: (config) => {
/** 设置 svg-sprite-loader */
const dir = resolve('src/icons') // 需要查找的路径
// 其他 svg loader 排除 icons 目录
config.module
.rule('svg')
.exclude.add(dir)
.end()
// 设置Icon
config.module
.rule('icons')
.test(/\.svg$/) // 匹配svg文件
.include.add(dir) // 包含上面添加的 icons 目录
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
},
// 这样就可以使用,相当于阿里的生成了一个js文件来使用

// index.js为全局注册SvgIcon组件

import Vue from "vue";
import SvgIcon from "@/components/SvgIcon"; // 引入Icon组件

Vue.component('SvgIcon', SvgIcon) // 注册全局组件

// 参考:https://webpack.docschina.org/guides/dependency-management/#require-context

/**
* Webpack 会在构建中解析代码中的 require.context()
* 三个参数:
* directory:说明需要检索的目录
* useSubdirectories:是否检索子目录
* regExp: 匹配文件的正则表达式
*
*/
let req = require.context("./svg", false, /\.svg$/)
/**
* context module API 会导出一个(require)函数,此函数可以接收一个参数:request
* 此导出函数有三个属性:resolve, keys, id
* keys 也是一个函数,它返回一个数组
*/
let requireAll = requireContext => requireContext.keys().map(requireContext)
// map循环,requireContext是req一个函数
try {
requireAll(req);
} catch (error) {
console.error(error)
}

// 使用时修改icon的大小与颜色
<SvgIcon iconClass="xxx" style="width: 16px;height: 16px;fill: red"></SvgIcon>

使用svgo优化svg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 安装svgo-loader
// 可以处理将svg文件多余的内容去除
// icons/svgo.yml

# Svgo 配置文件
# 参考:https://github.com/svg/svgo

plugins:
- removeStyleElement: true
- removeAttrs:
attrs:
- 'fill'
- 'fill-rule'

// package.json添加
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
// 下载后运行命令 npm run svgo 即可优化

表单的autocomplete

1
2
3
4
5
6
7
// autocomplete 在个别元素或整个表单上开启或关闭浏览器的自动完成功能。
// form、input(text、email等)与textarea、select默认开启
<form autocomplete="on | off">
// 注意:只有元素拥有name属性,该属性才有效

// 触发时机为输入相应表单值后,跳转页面即可(elementui也是如此)
// 清空 autocomplete 可以移到对应按Shift+Delete删除或者设置清空

直接修改整个state

1
2
3
4
5
6
7
8
9
REST_STATE(state) {
/**
* 必须使用 Object.assign 方法修改整个 vuex的state
* 函数默认接收一个参数为 state,修改 state 为当前函数作用域里面的值
* 以前修改state['xx']可以同时修改vuex的state,是当前的state与vuex的state的地址都指向同一个对象
* 使用 state = 'xx',是修改当前state的地址并没有影响指向的对象,而 Object.assign是改变对象的里面值并未修改地址
*/
Object.assign(state, initState())
}

JS中的注释

1
2
3
4
5
6
7
8
9
10
11
12
13
// 函数注释
/**
* @function 函数名
* @description 描述信息
* @param 参数 {string} 是否必传,描述信息
* @return {number} 描述信息
*/

// 对象key注释
/**
* @type {boolean} true | false
* @description 描述
*/

Sass 和 JS之间变量共享

1
2
3
4
5
6
7
8
9
10
// scss
$theme: blue;

:export {
theme: $theme;
}

// js
import variables from '@/styles/var.scss'
console.log(variables.theme) // blue

v-bind绑定对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<component :is="type" v-bind="link"></component>
</template>

<script>

export default {
computed: {
type() {
return 'a'
},
link() {
return {
href: to,
target: '_blank',
rel: 'noopener'
}
}
}
}
</script>

移动端rem与vw适配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// rem 适配,参考:vant
// 安装:postcss-pxtorem (npm install postcss-pxtorem@5.1.1 -D)
// 安装:amfe-flexible (npm i amfe-flexible)
// main.js
import 'amfe-flexible'
// postcss.config.js
/** postcss.config.js */
module.exports = {
plugins: {
'postcss-pxtorem': {
rootValue: 37.5,
propList: ['*'],
},
},
};
// 注意:px 自动转 rem 只在css中生效,行内样式不会生效

// scss单文件使用vw()
// 参考:https://juejin.cn/post/6963815704239800357
@function px2vw($px) {
@return $px * 100vw / 750;
}
div{
width: px2vw(100)
}

vue中css使用data数据

1
2
3
4
5
6
7
8
9
10
11
12
13
// 1.css(伪元素)使用自定义data数据
// 注意:针对伪元素的content使用var()函数动态改变无效,需要使用attr()函数
<div :data-content="true"></div>
div:after {
content: attr(data-content)
}

// 2.自定义data失效,使用css变量(--xxx)
// 注意:attr好像不能生效,只能使用变量
<div :style="{'--bodyHeight': window.innerHeight + 'px'}"></div>
div {
height: calc(var(--bodyHeight) - 100px);
}

滚动条样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 滚动条样式
@mixin scrollbar() {
/* 整个滚动条 */
&::-webkit-scrollbar {
/* 对应纵向滚动条的宽度 */
width: 5px;
/* 对应横向滚动条的宽度 */
height: 10px;
}

/* 滚动条上的滚动滑块 */
&::-webkit-scrollbar-thumb {
background-color: #BEBEBE;
border-radius: 32px;
}

/* 滚动条轨道 */
&::-webkit-scrollbar-track {
background-color: transparent;
border-radius: 32px;
}
}

/* 使用 */
div {
@include scrollbar;
}

/* 注意如果不生效,则添加如下样式*/
&::-webkit-scrollbar {
display: block
}

/* 横向滚动条到顶部 */
/* 父元素反转180度,子元素再反转回来,注意子元素的高度 */
<div class="father">
<div class="son"></div>
</div>

.father {
overflow-x: auto;
transform: scaleY(-1);
@include scrollbar;
.son {
transform: scaleY(-1);
height: 100%;
}
}

elementui 表单重置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// elementui 表单重置失效,必须要写prop属性才可以

// vue3 中的reactive 重置
// 改为使用ref数据,xxx.value
// 添加外部data包裹

// 或者如下
const info = {
a: 1,
b: 2,
}
const keys = Object.keys(info);
keys.forEach((item) => {
info[item] = "";
});

pnpm 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cnpm install -g pnpm  # 全局安装 pnpm
pnpm config set registry https://registry.npm.taobao.org/ # 设置镜像源
# 使用pnpm安装包报错,使用下面两个命令
#(只使用 pnpm setup 其他全局包会用不了,使用下面的命令可能会解决,暂不知道其他方案)
#(注意:不报错千万不要使用)
pnpm setup # 自动设置环境变量,会出现环境全部错误cnpm yarn等都用不了
pnpm config set global-bin-dir "D:\nodejs" # pnpm全局bin路径


pnpm install # 安装
pnpm add xxx # 安装生产依赖
pnpm add xxx -D # 安装本地依赖
pnpm add -g xxx # 全局安装
pnpm remove # 移除依赖
pnpm store prune # 清除缓存

其他配置

注意:不要随便使用下面的配置,会出现错误,如果配置了可以删除配置即可

​ 项目文件夹名称改了,需要删除node_modules重新安装(不然安装新的包会报错)

1
2
3
4
5
6
7
8
9
10
11
12
13
pnpm config set store-dir "D:\.pnpm-store" # pnpm全局仓库路径(类似 .git 仓库)
pnpm config set global-dir "D:\nodejs\pnpm\pnpm-global" # pnpm全局安装路径
pnpm config set global-bin-dir "D:\nodejs" # pnpm全局bin路径
pnpm config set state-dir "D:\nodejs\pnpm" # pnpm创建pnpm-state.json文件的目录
pnpm config set cache-dir "D:\nodejs\pnpm\cache" # pnpm全局缓存路径


npm config get userconfig # 用户配置文件
npm config edit # 编辑查看配置
npm config delete xxx # 删除某个配置
npm rm -g pnpm # 卸载全局包
npm ls -g # 查看全局包
npm cache clean --force # 强制清除缓存