vue中识别文本中的’/n’并实现自动换行
在vue中,直接渲染带有\n的语句,渲染失败,用 style="white-space: pre-wrap;
Lodash是一个JavaScript库,可在underscore.js顶部使用。 Lodash帮助处理数组,集合,字符串,对象,数字等。
_.sortBy()方法创建一个元素数组,该数组按通过每个迭代器运行集合中每个元素的结果以升序排序。而且此方法执行稳定的排序,这意味着它保留了相等元素的原始排序顺序。
用法:
_.sortBy(collection, iteratees)
**参数:**该方法接受上述和以下所述的两个参数:
- **collection:**此参数保留要迭代的集合。
- **iteratees:**此参数保存要进行排序的迭代对象,并使用一个参数(值)进行调用。
**返回值:**此方法用于返回新的排序数组。
// Requiring the lodash library
const _ = require("lodash");
// Original array
var object = [
{
'obj':'moto', 'price':19999 },
{
'obj':'oppo', 'price':18999 },
{
'obj':'moto', 'price':17999 },
{
'obj':'oppo', 'price':15999 } ];
// Use of _.sortBy() method
let gfg = _.sortBy(object,
[function(o) {
return o.obj; }]);
// Printing the output
console.log(gfg);
yyyy-MM-dd HH:mm:ss和yyyy-MM-dd hh:mm:ss的区别:
无论是在springboot 还是在其他中,
yyyy-MM-dd HH:mm:ss代表24小时制,
yyyy-MM-dd hh:mm:ss代表12小时制
0.0199
0.7
JS 数值不进制处理 保留N位小数
不进制处理,可以数值截取指定小数位
dealDecimal(val) {
let num = val.toString() // 先转化为字符串 调用substring方法
num = num.substring(0, num.indexOf('.') + 3) // 保留两位小数
return num
},
JS 小数四舍五入
四舍五入可以使用 toFixed() 方法,toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。
// toFixed() 方法
var num = 2.446242342;
num = num.toFixed(2); // 输出结果为 2.45
另外像 round()、floor()、ceil() 等都不能真正的四舍五入,有精度问题。
正则校验 0 ~ 10000000000之间的数值,最多两位小数:
/^(?!0$)([1-9][0-9]{0,9}|0)(\.(?![0]{1,2}$)[0-9]{1,2})?$/
正则 不含特殊字符:
valids.pattern(/^[\u4E00-\u9FA5A-Za-z0-9]*$/, '权益名称只可输入中文、英文及数字'),
JavaScript 中 ?? 与 || 的区别:
相同点:用法相同,都是前后是值,中间用符号连接。根据前面的值来判断最终返回前面的值还是后面的值。
值1 ?? 值2
值1 || 值2
不同点:判断方式不同:
使用 ?? 时,只有当值1 为 null 或 undefined 时才返回 值2;
使用 || 时,值1会转换为布尔值判断,为true返回值1,false 返回值2
// ??
undefined ?? 2 // 2
null ?? 2 // 2
0 ?? 2 // 0
"" ?? 2 // ""
true ?? 2 // true
false ?? 2 // false
// ||`
undefined || 2 // 2
null || 2 // 2
0 || 2 // 2
"" || 2 // 2
true || 2 // true
false || 2 // 2
// 总的来说,??更加适合在不知道变量是否有值时使用。
微前端浏览器缓存问题
微信小程序前端开发踩坑——页面跳转层级限制
微信小程序发版审核不通过提示使用定位相关api:更新神策版本优化定位问题(由于埋点功能涉及的神策包有定位api)
小程序中使用在线图片时注意酌情加时间戳,避免强缓存导致图片不替换问题
微信小程序中不展示滚动条:
view ::-webkit-scrollbar {
width: 0;
height: 0;
background-color: transparent;
display: none;
}
微信小程序订阅消息相关:
wx.getSetting({
withSubscriptions: true,
success: res => {
// 是否开启订阅消息提醒
const flag1 = res?.subscriptionsSetting?.mainSwitch
const itemSettings = res?.subscriptionsSetting?.itemSettings || {
}
// 是否开启指定消息订阅模板id的“一直选中”消息提醒
const flag2 = itemSettings['5692Ap1Vn2lZ-SUp0pddfscdFRIsnUgN0n77Mrsdxcj-yI']
console.log('mainSwitch: ', res, flag1, flag2)
// 开启指定消息订阅模板id的消息提醒但是未“一直”选中
if (flag1 && !flag2) {
console.log('一些操作,例如动画引导用户勾选“总是”')
} else {
// 未开启消息提醒 + 开启并选中总是,直接调用即可
wx.requestSubscribeMessage({
tmplIds: ['kBcJv55qydGropxX-ofsdzsdvdsxcdsgM6Cwt8pgaWJ9ACM_GAztJXhA'],
complete: () => {
foo()
},
})
}
},
fail: () => {
foo()
}
})
微信小程序中跳转其他小程序:
wx.navigateToMiniProgram({
appId: 'wx1dbe5bddgxvs78247',
path: 'packages/goods/detail/index?alias=1y6v0g6wnc4ojvk&shopAutoEnter=1'
})
微信小程序跳转公众号或者其他链接:web-view
(https://mp.weixin.qq.com开头的公众号可以直接跳转,其他类型的地址都需要配置业务域等,配置业务域还要上传文件等…)
微信小程序强制更新:
// wx.getUpdateManager 在 1.9.90 才可用,请注意兼容
const updateManager = uni.getUpdateManager()
updateManager.onUpdateReady(() => {
uni.showModal({
title: '更新提示',
content: '新版本已经准备好,是否马上重启小程序?',
success: res => {
if (res.confirm) {
updateManager.applyUpdate()
}
}
})
})
微信小程序分享相关:
配置在公共文件处,根据情况判断开启场景
// 开启分享、分享到朋友圈
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline'],
})
// 关闭分享、分享到朋友圈
wx.hideShareMenu({
menus: ['shareAppMessage', 'shareTimeline']
})
微信小程序下载文件并打开:
wx.downloadFile({
url: docUrl,
success: function(res) {
wx.openDocument({
filePath: res.tempFilePath })
},
})
将canvas绘图转换成图片+保存到本地相册
<template>
<canvas
id="poster"
canvas-id="poster"
canvas-type="2d"
class="poster-box"
/>
</template>
<script>
wx.canvasToTempFilePath({
canvasId: 'poster', // 绘制的canvas id
success: (res) => {
var tempFilePath = res.tempFilePath
wx.saveImageToPhotosAlbum({
filePath: tempFilePath,
success(res) {
wx.showToast({
title: '已保存到相册',
icon: 'success',
duration: 2000
})
},
fail(res) {
that.$toast({
title: '您未开启保存到相册的权限!' })
}
})
},
fail: (res) => {
console.log(1111, res)
}
})
// 获取在线图片的路径(先保存然后获取的地址
uni.getImageInfo({
src: 'https://xxx.com/image/fitness/qrcode.png',
success: (qrcode) => {
// 可以根据图片地址绘制canvas
ctx.drawImage(qrcode.path, 231, 333, 64, 64)
}
</script>
微信复制文本:
wx.setClipboardData({
data: val,
success: () => {
wx.getClipboardData({
success: () => {
wx.showToast({
icon: 'none',
title: '已复制',
})
}
})
}
})
微信唤起电话键盘:wx.makePhoneCall({ phoneNumber: contactNo })
css粘性定位position:sticky问题采坑
uni-app支持如下页面生命周期函数:
uni-app使用button的时候设置border的问题,去border边框问题
uni-app的button想要直接使用outline: none;border:0;去掉边框线是不行的,需要设置button::after{ border: none;} 这样就可以解决这个button自带的边框问题了
# npm升级到最新版本
npm install -g npm
# 6.14就是你想要降的版本
npm install npm@6.14 -g
# 安装homebrew
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
# mac安装指定的node版本:https://www.jianshu.com/p/9ef908190ca1
# Mac 打开新的控制台总是找不到npm:https://www.cnblogs.com/juliazhang/p/14592470.html
# MAC上Git安装与GitHub基本使用:https://www.jianshu.com/p/7edb6b838a2e
Mac切换到root用户(su命令行)以及退出:sudo su
退出的话,输入exit
vim模式保存退出 => :wq
npm指令清除npm缓存
npm cache clean --force
Git提交代码规范
用于说明 commit 的类别,只允许使用下面7个标识。
- feat:新功能(feature)
- fix:修补bug
- docs:文档(documentation)
- style: 格式(不影响代码运行的变动)
- refactor:重构(即不是新增功能,也不是修改bug的代码变动)
- test:增加测试
- chore:构建过程或辅助工具的变动
来回自如的切换淘宝镜像与国外源
1.打开cmd,查看当前镜像地址:
npm get registry
**2.**切换为淘宝镜像:
npm config set registry http://registry.npm.taobao.org/
npm config set registry https://registry.npmmirror.com
3.切换为原本的npm镜像:
npm config set registry https://registry.npmjs.org/
4.同步模块
直接通过 sync
命令马上同步一个模块, 只有 cnpm
命令行才有此功能:
cnpm sync connect
面试题汇总:
一道常被人轻视的前端JS面试题:(https://www.cnblogs.com/xxcanghai/p/5189353.html)
function Foo() {
getName = function () {
alert (1); };
return this;
}
Foo.getName = function () {
alert (2);};
Foo.prototype.getName = function () {
alert (3);};
var getName = function () {
alert (4);};
function getName() {
alert (5);}
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
function Foo() {
// Foo函数
getName = function () {
alert (1); };
return this;
}
Foo.getName = function () {
alert (2);}; // 为Foo创建了一个getName的静态属性存储了一个匿名函数
Foo.prototype.getName = function () {
alert (3);}; // 为Foo的原型对象新创建了一个叫getName的匿名函数
var getName = function () {
alert (4);}; // 通过函数变量表达式创建了一个getName的函数
function getName() {
alert (5);} // 声明了一个叫getName函数
=>
①Foo.getName(); // 访问Foo函数上存储的静态属性
②getName(); // 变量提升+函数表达式 var getName 覆盖了 function getName(){}
③Foo().getName(); // 先在当前Foo函数作用域内寻找getName变量,没有。再向当前函数作用域上层,即外层作用域内寻找是否含有getName变量,找到了,也就是②中的alert(4)函数,将此变量的值赋值为 function(){alert(1)}。此处实际上是将外层作用域内的getName函数修改了
④getName(); // 直接调用getName函数,相当于 window.getName() ,因为这个变量已经被Foo函数执行时修改了,遂结果与第三问相同,为1
⑤new Foo.getName(); // js的运算符优先级问题:点(.)的优先级高于new操作,遂相当于是: new (Foo.getName)();
⑥new Foo().getName(); // 首先看运算符优先级括号高于new,实际执行为:(new Foo()).getName(),遂先执行Foo函数,而Foo此时作为构造函数却有返回值this,而this在构造函数中本来就代表当前实例化对象,遂最终Foo函数返回实例化对象。之后调用实例化对象的getName函数,因为在Foo构造函数中没有为实例化对象添加任何属性,遂到当前对象的原型对象(prototype)中寻找getName,找到了。
⑦new new Foo().getName();// 运算符优先级问题:最终实际执行为:new ((new Foo()).getName)(); 先初始化Foo的实例化对象,然后将其原型上的getName函数作为构造函数再次new。
// 2 - 4 - 1 - 1 - 2 - 3 - 3
react渲染原理分析:https://www.jianshu.com/p/8dc8e59844c9
H5、C3、es6、es7的新特性:https://www.jianshu.com/p/8f08b6938e4d
vuex常见面试题:https://zhuanlan.zhihu.com/p/163283018
详解 CSS 属性 - 伪类和伪元素的区别:https://segmentfault.com/a/1190000000484493、https://www.cnblogs.com/ihardcoder/p/5294927.html
从零开始搭建一个vue-ssr:https://segmentfault.com/a/1190000019618170
react服务器渲染(ssr):https://segmentfault.com/a/1190000018328145?utm_source=tag-newest、https://www.jianshu.com/p/2db3857272a4
堆和栈的概念和区别:https://blog.csdn.net/pt666/article/details/70876410/
CSS表达式:https://blog.csdn.net/andyyukun/article/details/1676963
V8 引擎:https://zhuanlan.zhihu.com/p/27628685
NodeJs 库:https://zhuanlan.zhihu.com/p/254660191、https://www.cnblogs.com/zhangycun/p/13570459.html
Webpack 构建流程:https://segmentfault.com/a/1190000022991056、https://www.jianshu.com/p/5ded519fc1e7、https://www.cnblogs.com/xjy20170907/p/12910280.html
webpack 持久化缓存:https://www.jianshu.com/p/f4959dab2969#comments
JavaScript异步编程:https://segmentfault.com/a/1190000015711829、https://blog.csdn.net/weixin_40851188/article/details/90648666、http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html
JavaScript 执行过程:https://blog.csdn.net/weixin_33701617/article/details/91461463、https://blog.csdn.net/wexin_37276427/article/details/105028116
JavaScript执行分为两个阶段,编译阶段和执行阶段。
编译阶段会经过词法分析、语法分析、代码生成步骤生成可执行代码;
执行阶段JS 引擎执行可执行性代码会创建执行上下文,包括绑定this、创建词法环境和变量环境;词法环境创建外部引用(作用域链)和 记录环境(变量对象,let, const, function, arguments), JS 引擎创建执行上下完成后开始单线程从上到下一行一行执行 JS 代码了。
Diff算法(React、Vue):https://zhuanlan.zhihu.com/p/149972619、区别(https://www.jianshu.com/p/fac3d2b112a6)
Redux数据流:https://www.jianshu.com/p/faee4de8e092
react-redux中的数据传递:https://www.jianshu.com/p/5726bb042bda
Nodejs 跨域解决方案:https://blog.csdn.net/boonyaxnn/article/details/91397965、https://www.cnblogs.com/zz009527/p/14741507.html?ivk_sa=1024320u
DNS查询:
DNS(Domain Name System): 负责将域名URL转化为服务器主机IP。
DNS查找流程:首先查看浏览器缓存是否存在,不存在则访问本机DNS缓存,再不存在则访问本地DNS服务器。所以DNS也是开销,通常浏览器查找一个给定URL的IP地址要花费20-120ms,在DNS查找完成前,浏览器不能从host那里下载任何东西。域名TTL值(Time-To-Live):就是一条域名解析记录在DNS服务器中的存留时间。当各地的DNS服务器接受到解析请求时,就会向域名指定的NS服务器(权威域名服务器)发出解析请求从而获得解析记录;在获得这个记录之后,记录会在DNS服务器(各地的缓存服务器,也叫递归域名服务器)中保存一段时间,这段时间内如果再接到这个域名的解析请求,DNS服务器将不再向NS服务器发出请求,而是直接返回刚才获得的记录;而这个记录在DNS服务器上保留的时间,就是TTL值。
影响DNS缓存的因素:
① 服务器可以设置TTL值表示DNS记录的存活时间。本机DNS缓存将根据这个TTL值判断DNS记录什么时候被抛弃,这个TTL值一般都不会设置很大,主要是考虑到快速故障转移的问题。
② 浏览器DNS缓存也有自己的过期时间,这个时间是独立于本机DNS缓存的,相对也比较短,例如chrome只有1分钟左右。
③ 浏览器DNS记录的数量也有限制,如果短时间内访问了大量不同域名的网站,则较早的DNS记录将被抛弃,必须重新查找。不过即使浏览器丢弃了DNS记录,操作系统的DNS缓存也有很大机率保留着该记录,这样可以避免通过网络查询而带来的延迟。最佳实践:当客户端的DNS缓存为空时,DNS查找的数量与Web页面中唯一主机名的数量相等。所以减少唯一主机名的数量就可以减少DNS查找的数量。然而减少唯一主机名的数量会潜在地减少页面中并行下载的数量,避免DNS查找降低了响应时间,但减少并行下载可能会增加响应时间。当页面的组件量比较多的时候,可以考虑将组件分别放到至少2-4个主机名 以获得最大收益。
前端应该了解的dns解析那些事:https://blog.csdn.net/xiaoluodecai/article/details/112596978
网络协议基础介绍-TCP、UDP、HTTP:https://blog.csdn.net/qq_41838901/article/details/98748353、https://blog.csdn.net/qq_31332467/article/details/79217262
webpack怎么打包css:https://www.html.cn/qa/css3/12773.html、打包js、css、图片:https://www.jianshu.com/p/52982767189b
SocketIO、Websocket断开重连问题排查方案:https://blog.csdn.net/wk19920726/article/details/109023816
重排重绘:
闭包,平时工作中的应用场景:
深浅拷贝:
防抖节流,怎么实现:
跨域,本地开发有跨域怎么处理,webpack中proxy代理:
promise,缺点,用promise封装ajax:
MVVM:
ES6新特性在浏览器打包完以后不兼容怎么处理:
Vue的生命周期,哪一阶段实例创建,哪一阶段挂载到dom上:
vue-cli搭载过项目,static和assets区别:
Vuex和Redux区别:
Store是什么:
使用Redux异步处理怎么做的:
react生命周期:
React的constructor、里面可以直接用props吗,super()传参props与不传的区别:
setState是同步还是异步的,第二个参数
虚拟Dom和diff算法:
遍历循环中key为什么最好不要用index:
React组件通信,context:
React中的高阶组件:
纯函数:
受控组件与非受控组件:
父组件怎么调用子组件的方法:
React性能优化:
怎么实现路由懒加载:
React-Router路由模式:
Hooks,为什么要使用hooks:
useEffect依赖对象可以放对象吗:
webpack打包做过什么优化:
sass-loader、style-loader、css-loader:
less里面如何封装一块代码块:
笔试题记忆点:继承的方法、继承的具体例题
Vue与React的区别与优缺点(必问!!):
浅谈懒加载技术:https://www.cnblogs.com/jsjx-xtfh/p/9587911.html
一次搞定前端“四大手写”:https://zhuanlan.zhihu.com/p/160315811
• JS类型转换之 valueOf 和 toString:
Object.prototype.valueOf():用 MDN 的话来说,valueOf() 方法返回指定对象的原始值。
Object.prototype.toString():toString() 方法返回一个表示该对象的字符串。每个对象都有一个 toString() 方法,当对象被表示为文本值时或者当以期望字符串的方式引用对象时,该方法被自动调用。
转换规律:
如果只改写 valueOf() 或是 toString() 其中一个,会优先调用被改写了的方法,而如果两个同时改写,则会像 Number 类型转换规则一样,优先查询 valueOf() 方法,在 valueOf() 方法返回的是非原始类型的情况下再查询 toString() 方法。
let x = {
toString: () => {
console.log('TpString')
return 20
},
valueOf: () => {
console.log('ValueOf')
return '30'
}
}
console.log(x == '20')
console.log(x == 30)
// => valueOf false
// => valueOf true
• JS中几种常见的高阶函数:(https://www.cnblogs.com/goloving/p/8361705.html)
高阶函数:英文叫Higher-order function。JavaScript的函数其实都指向某个变量。
高阶函数是至少满足下列一个条件的函数:
- 接受一个或多个函数作为输入
- 输出一个函数
编写高阶函数,就是让函数的参数能够接收别的函数。
一个最简单的高阶函数:
function add(x, y, f) {
return f(x) + f(y);
}
// 当调用add(-5, 6, Math.abs)时,参数x,y和f分别接收-5,6和函数Math.abs,根据函数定义,可以推导计算过程为:
// x = -5;
// y = 6;
// f = Math.abs;
// f(x) + f(y) ==> Math.abs(-5) + Math.abs(6) ==> 11;
// return 11;
//用代码验证一下:
add(-5, 6, Math.abs); // 11
常见的高阶函数:
① map/reduce:
function pow (x) {
return x * x;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
// map()传入的参数是pow,即函数对象本身。
// 不需要map(),写一个循环,也可以计算出结果:
var f = function (x) {
return x * x;
};
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var result = [];
for (var i=0; i<arr.length; i++) {
result.push(f(arr[i]));
}
// 的确可以,但是,从上面的循环代码,我们无法一眼看明白“把f(x)作用在Array的每一个元素并把结果生成一个新的Array”。
/* 所以,map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把Array的所有数字转为字符串:*/
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']
// 只需要一行代码。
// 再看reduce的用法。
// Array的reduce()把一个函数作用在这个Array的[x1, x2, x3...]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算,其效果就是:
// [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
// 比方说对一个Array求和,就可以用reduce实现:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
② filter:
filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。和map()类似,Array的filter()也接收一个函数,和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。
// 回调函数:filter()接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身:
var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
console.log(element); // 依次打印'A', 'B', 'C'
console.log(index); // 依次打印0, 1, 2
console.log(self); // self就是变量arr
return true;
});
// 利用filter,可以巧妙地去除Array的重复元素:
'use strict';
var r, arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
r = arr.filter(function (element, index, self) {
return self.indexOf(element) === index;
});
alert(r.toString());
// 去除重复元素依靠的是indexOf总是返回第一个元素的位置,后续的重复元素位置与indexOf返回的位置不相等,因此被filter滤掉了。
③ sort排序算法:因为Array的sort()方法默认把所有元素先转换为String再排序,结果’10’排在了’2’的前面,因为字符’1’比字符’2’的ASCII码小。如果不知道sort()方法的默认排序规则,直接对数字排序,绝对栽进坑里!幸运的是,sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。
// 要按数字大小排序,我们可以这么写:
var arr = [10, 20, 1, 2];
arr.sort((x, y) => x - y); // [1, 2, 10, 20]
// 如果要倒序排序,我们可以把大的数放前面:
var arr = [10, 20, 1, 2];
arr.sort((x, y) => y - x)); // [20, 10, 2, 1]
// 默认情况下,对字符串排序,是按照ASCII的大小比较的,现在,排序应该忽略大小写,按照字母序排序。
// 要实现这个算法,不必对现有代码大加改动,只要我们能定义出忽略大小写的比较算法就可以:
var arr = ['Google', 'apple', 'Microsoft'];
arr.sort(function (s1, s2)