vue的style有scoped时想要设置全局样式的方法
- :deep(选择器) 会把属性选择器加到该选择器的上一层,若为了摆脱scoped带来的自动附加的属性选择器,若再写一个
<style>
标签太累赘 - 可以通过 :global() 来实现全局选择
.info {
//外面这层选择器实际上是无效的,编译成css时 会以:global里的选择器作为第一层
:global(.el-dropdown-menu__item) {
line-height: 36px !important;
padding: 6px 22px;
}
}
图片懒加载的两种方案
- 目标:1.懒加载 2.图片加载成功前展示的图片可自定义
方案1(vue-lazyload)
- pnpm add vue-lazyload
main.js
import VueLazyLoad from "vue-lazyload";
Vue.use(VueLazyLoad, {
preLoad: 1,
error: require("./assets/person.png"),//加载失败的图片
loading: require("./assets/loading.gif"),//加载中的图片
attempt: 2,
});
3.
<img v-lazy="item.imgUrl"
alt=""
class="customer-img" />
方案2 (element-plus)
<el-image :src="headerImg"
fit="cover"
lazy
class="img">
<!-- 空白时期用图片占位(可以用) 图片加载慢/加载出错图片-->
<template #placeholder>
<img src="@/assets/loading.gif"
alt="" />
</template>
<template #error>
<img src="@/assets/profile.png"
alt="" />
</template>
</el-image>
- 用element就是代码有点长,可以在有占位图/出错图的前提下不懒加载,个别图片(登录用户头像这种)要用时可以用该方案
- vue-lazyload会简约很多,如果长列表这种,推荐用
flex布局练习游戏
各种语言入门网站
- b站 @程序员Sunday
混合开发通信(web视角)
web发给exe
- chrome.webview?.postMessage(JSON.stringify(params))
exe操作web
- 暴露方法给window。function setVal(val){...} window.setVal=setVal
正则里容易疏忽的地方
转义
- 元字符:([ { \ ^ $ |) ? * + . (若匹配元字符本身需要转义)
- ^ $ . * + ? | \ / ( ) [ ] { } - 无脑一律转义,总之不会出错
- 通过new RegExp创建正则时
/
转不转义都行,若直接写成字面量是需要转移的\/
const prefixRgx1 = new RegExp("<span.+?</span>")
const prefixRgx2 = /<span.+?<\/span>/
- [ ]内部不需要转义
- 跟字符组相关的元字符有[]、^、-。 在会引起歧义的地方进行转义
var reg=/[() +\]/; //匹配'(',')',' ','+','\'其中之一, []内部不需要转义
- 若要在中括号表达式中包括连字符
-
,请采用下列方法之一:- 用反斜杠将它转义:
[\-]
- 将连字符放在中括号列表的开始或结尾
[-a-z]
[a-z-]
- 用反斜杠将它转义:
- \w:[A-Za-z0-9_]
- ?:{0,1} // 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的,尽可能少地匹配所搜索的字符串
断言
慎用,苹果设备不支持,写完还得改
- x(?=y):匹配'x' 仅仅当'x'后面跟着'y'.这种叫做先行断言。
- x(?!y):仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找。
- (?<=y)x:匹配'x' 仅当'x'前面是'y'.这种叫做后行断言。
- (?<!y)x:仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找。
- (?:) 匹配组, ?:标记该匹配组不应被捕获
(?:pattern) 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
- www.matools.com/regex //配套正则说明比较全面
- 正则表达式在线测试 | 菜鸟工具 (runoob.com) //简约方便测试
实现关键字匹配高亮
function checkWordsList(wordList,originText) {
// 创建一个正则表达式,用于匹配所有关键字
const regex = new RegExp(
// repalce是要对正则特殊字符进行转义,防止匹配时被当成正则关键字 而不是要被匹配的字符
wordList.map((kw) => kw.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|'),
'gi'
)
// 使用正则表达式替换关键字
return originText.replace(regex, (match) => {
return '<span class="key-words">' + match + '</span>'
})
}
分析构成:
arr=['+aa','(12','*bc']
rawStr=arr.map((kw) => kw.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|') // '\\+aa|\\(12|\\*bc'
let reg=new RegExp(rawStr,'gi') // /\+aa|\(12|\*bc/gi
'..+aa...*bc...(12...'.replace(reg,(val)=>`-${val}-`) // '..-+aa-...-*bc-...-(12-...'
- 有两种方法可以创建一个
RegExp
对象:一种是字面量,另一种是构造函数。 - 如果要通过变量来生成正则,就要用new RegExp
- 当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠
\
) -
//这俩等价 一个反斜杠,new完就没了 var re = new RegExp("\\w+"); var re = /\w+/;
- 当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠
kw.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
等价于下面,目的是把正则关键字转义一下kw.replace(/[.*+?^${}()|[\]\\]/g,val=>`\\${val}`)
正则捕获组
'http://dev.baidu.com/gqq/?code=JSynfueD4d5WBCy6sADMGQXYk&state=STATE#/home'.replace(/(.*?)/?(.*)#(.*)/,"$1/#$3?$2")
'http://dev.baidu.com/gqq/#/home?code=JSynfueD4d5WBCy6sADMGQXYk&state=STATE'
[非]贪婪匹配最常用的方式
- 贪婪匹配下,.* 会匹配尽可能多的字符
- 非贪婪匹配的写法是.*? //它会尽可能少地匹配
'hellohellohello'.match(/h.*?o/) 结果是伪数组,相当于["hello"]
正则带g和不带g影响match里组的结果
- 不带g时,match出来的,会把正则 (捕获分组) 里匹配到的也放数组里
- 带g时就不放了
'123abcd'.match(/([1-9])([a-z]+)/)
//(3) ['3abcd', '3', 'abcd', index: 2, input: '123abcd', groups: undefined]
'123abcd'.match(/([1-9])([a-z]+)/g)
['3abcd']
匹配任意字符
- . 匹配除“\n”和"\r"之外的任何单个字符
- [\s\S] 这种是匹配所有字符
匹配url链接
/(?:http|https):\/\/(?:[a-z0-9-]+\.)+[a-z]{2,20}(?:\/[\w\d#_%@/]+)+(?:\?[\w\d#_%@=&.\u4e00-\u9fa5]+)?/g
- (?:) 非捕获组,减少性能消耗
分析:
/(http|https):\/\/([a-z0-9-]+\.)+[a-z]{2,20}(\/[\w\d#_%@/]+)+(\?[\w\d#_%@=&.\u4e00-\u9fa5]+)?/g
- (http|https)://([a-z0-9-]+.)+[a-z]{2,20} 是匹配 xxx.xxx.xx
- (/[\w\d#_%@/]+)+ 是匹配 /xxx/yyy
- (?[\w\d#_%@=&.\u4e00-\u9fa5]+)? 是匹配 ?id=13&content=12
文档(js使用正则的各种方法): developer.mozilla.org/zh-CN/docs/…
字符串中目标内容的位置生成数组
RegExp.exec()虽然能找到匹配项的位置,但执行一次只能得到一个,通过Sting.matchAll(/正则/g) 能拉到所有匹配项和它们的起始坐标
let testMessage="提取字符串位置 https://pinia.web3doc.top/introduction.html 开始啦 https://c.runoob.com/front-end/854 目标正则标定"
const urlRgx =
/(?:http|https):\/\/(?:[a-z0-9-]+\.)+[a-z]{2,20}(?:\/[\w\d#_%@]+)+(?:\?[\w\d#_%@=&.\u4e00-\u9fa5]+)?/g;
const matchUrlList=Array.from(testMessage.matchAll(urlRgx),(x)=>x)
const stopList=matchUrlList.map(el=>{
const s=el.index
const e=el.index+el[0].length
return {s,e}
})
//matchUrlList
[['https://pinia.web3doc.top/introduction', index: 8, input: '提取字符串位置 https://pinia.web3doc.top/introduction.html 开始啦 https://c.runoob.com/front-end/854 目标正则标定', groups: undefined]
['https://c.runoob.com/front', index: 56, input: '提取字符串位置 https://pinia.web3doc.top/introduction.html 开始啦 https://c.runoob.com/front-end/854 目标正则标定', groups: undefined]]
//stopList
0: {s: 8, e: 46}
1: {s: 56, e: 82}
match时正则g对捕获组的影响
- 当有捕获组时,若正则是全局匹配,则match方法不会把捕获组结果也放数组里
- 当有捕获组时,若是单次匹配,match会把捕获组匹配的结果也放到数组里
'23132134run12415465run'.match(/([1-9])([a-z]+)/g)
// 结果: ['4run', '5run']
'23132134run12415465run'.match(/([1-9])([a-z]+)/)
// 结果:伪数组的内容
['4run', '4', 'run', index: 7, input: '23132134run12415465run', groups: undefined]
// 圆括号会有一个副作用,使相关的匹配会被缓存,此时可用 ?: 放在第一个选项前来消除这种副作用。
'23132134run12415465run'.match(/(?:[1-9])(?:[a-z]+)/)
// 结果:['4run', index: 7, input: '23132134run12415465run', groups: undefined]
正则一些技巧
- 善于用
[^]
排除字符来凑
// var regex = /id=".*?"/
var regex = /id="[^"]*"/
var string = '<div id="container" class="main"></div>';
console.log(string.match(regex)[0]); // => id="container"
- 开头和结尾可以替换
var result = "hello".replace(/^|$/g, '#');
console.log(result);
// => "#hello#"
- 数字加,
var string1 = "12345678",
string2 = "123456789";
reg = /(?!^)(?=(\d{3})+$)/g;
var result = string1.replace(reg, ',')
console.log(result);
// => "12,345,678"
result = string2.replace(reg, ',');
console.log(result);
// => "123,456,789"
- 匹配,整块挪位
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1");
console.log(result);
// => "06/12/2017"
/*等价于*/
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, function(match, year, month, day) {
return month + "/" + day + "/" + year;
});
console.log(result);
// => "06/12/2017"
- 反向引用
里面的\1
,表示的引用之前的那个分组(-|/|.)
。不管它匹配到什么(比如-),\1
都匹配那个同样的具体某个字符。
我们知道了\1
的含义后,那么\2
和\3
的概念也就理解了,即分别指代第二个和第三个分组。
var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/;
var string1 = "2017-06-12";
var string2 = "2017/06/12";
var string3 = "2017.06.12";
var string4 = "2016-06/12";
console.log( regex.test(string1) ); // true
console.log( regex.test(string2) ); // true
console.log( regex.test(string3) ); // true
console.log( regex.test(string4) ); // false
- 匹配成对的标签
var regex = /<([^>]+)>[\d\D]*<\/\1>/;
var string1 = "<title>regular expression</title>";
var string2 = "<p>laoyao bye bye</p>";
var string3 = "<title>wrong!</p>";
console.log( regex.test(string1) ); // true
console.log( regex.test(string2) ); // true
console.log( regex.test(string3) ); // false
正则容易忽略的bug
全局匹配的正则表达式匹配错位问题
/xx/g
当使用它时,它会有个隐藏属性是lastIndex,使用test时会往后挪一下 导致后面方法开始位置有误,无法全部匹配- 不影响 str.match(Reg),好像在执行前会把正则的lastIndex重置为0
let str='ab------ab--------ab'
const Reg=/ab/g
Reg.test(str) //true
Array.from(str.matchAll(Reg))
// [['ab', index: 8, input: 'ab------ab--------ab', groups: undefined]
// ['ab', index: 18, input: 'ab------ab--------ab', groups: undefined]]
- RegExp.exec(String) 就是执行一次 会把正则后移一位,其它正则方法底层都用的它
const myRe = /ab*/g;
const str = "abbcdefabh";
let myArray;
while ((myArray = myRe.exec(str)) !== null) {
let msg = `Found ${myArray[0]}. `;
msg += `Next match starts at ${myRe.lastIndex}`;
console.log(msg);
}
exec mdn教程 在设置了
global
或sticky
标志位的情况下(如/foo/g
或/foo/y
),JavaScriptRegExp
对象是有状态的。它们会将上次成功匹配后的位置记录在lastIndex
属性中。