开始

一种经验记录,以提升效率,可能不会深入了解(如果深入了解了就会在此文档中删掉对应内容,而去新写一篇详细文档),长期更新,经常看看

1.此处的tagName是大写的标签名,如LI, DIV。

1
2
3
4
function clickFunc(e) {
e = e || event // 这里不主动传参数的话其实并没有参数,event是在事件函数中就存在的
console.error(event.target.tagName)
}

2.一个拼音字典,js获取汉字拼音https://blog.csdn.net/m0_51479322/article/details/113073493

1
2
3
4
5
6
7
8
9
10
11
// npm地址
https://www.npmjs.com/package/pinyin-pro
// github
https://github.com/zh-lx/pinyin-pro
// 安装
yarn add pinyin-pro
// 使用
import { pinyin } from 'pinyin-pro';

// 获取声调转换为数字后缀的拼音
pinyin('汉语拼音', { toneType: 'num', type: 'array' }); // ["han4", "yu3", "pin1", "yin1"]

3.路由导航守卫对子组件(设置了路由的组件中的子组件)无效

4.attribute:setAttribute(‘value’,’1’)改的属性,可以说是dom元素的属性,

​ Property: input.value = ‘2’,改的属性是dom节点对象的属性,这个dom对象的value属性就是展示的输入框的值

https://blog.csdn.net/u013362969/article/details/88410381?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.base

5.background-image的url中最好加引号

6.data中的变量直接用data中的变量判断的问题,不知道原因,不要这么做

1
2
3
4
5
6
7
8
// a=1, b=3
// 另外,b:this.a,这个b是打印不出来的,也不报错
data() {
return {
a: 1,
b: this.a>0?2:3
}
},

7.循环执行a标签的下载,只下载最后一个文件的问题

1
2
3
4
5
6
7
arr.forEach((item, index) => {
setTimeout(() => {
// 创建a标签并点击触发下载的方法
download(url, filename)
// 查到的有效方法:经测试在每个下载之间间隔500ms时,a标签触发的下载不会清除上一次的下载动作(但没有明确的文档标明过)
}, 500*index);
})

2021年8月9号更新:近期有个批量下载音频的需求(50条音频),自测时使用文件大小为300k,此方法没有问题。线上的音频是16m甚至更大,发现最终只会下载10条左右(一般都少于10条)。复现后发现浏览器会同时执行6个下载任务,一个结束后会新增一个任务,新增几次后就会不再新增 - 下载任务丢失。

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
// a标签默认的target是_self,所有的下载都在同一个标签下,不会出现弹出一堆空白标签,体验更好,但是文件大了之后其中一个下载任务等待时会导致有些下载任务被清除(机制不清楚)。
// 而target为_blank时,弹出空白标签来排队保证下载任务不会丢失,只是体验不好。
// iframe隐藏下载,如下修改后代码,能够不弹空白标签下载不丢失文件,有个缺点就是无法监听到下载完成而清除iframe,只能在某个操作点去清除一下iframe

// 问题代码
function download(url, filename) {
var a = document.createElement('a')
a.href = url
a.download = filename || true
a.click()
}

// 修改后代码
function download(url, filename) {
var elIf = document.createElement("iframe");
elIf.src = url;
elIf.style.display = "none";
document.body.appendChild(elIf);
}
// 清除iframe
beforeRouteLeve(to, from, next) {
let arr = document.body.querySelectorAll('iframe')
arr.forEach(item => {
document.body.removeChild(item)
})
next()
}

8.过滤器到处变化:页面数据变化重新渲染会重新触发过滤器

9.vscode 的live server扩展

10.字符串中换行符 /n 在vue的template中是否奏效。给父级加white-space:pre-wrap;规定段落中的文本换行

vue模板中的多个 &nbsp 最后却只有一个空格显示出来

​ vue 在 compile 的过程中会将这些   转换成一个空格(‘ ‘)。

v-html 指令里面的多个 &nbsp 最后全部空格都可以显示出来

​ vue在compile过程中不做处理,运行时使用 dom.innerHTML = ‘xxx’ 的方式来插入到节点中

  1. img标签的底部空隙解决:最简单的办法就是display:block; 具体分析见另一篇文章

  2. 对sessionStorage来说,一个标签就是一个会话,与域名无关;不同标签中的sessionStorage互不影响。

  3. sass中的/deep/,给一个父级加了/deep/后,他内部的元素都无需也不能再加/deep/。

  4. 回车键提交input框内的数据,会多提交一个换行符\n,想把\n去掉就在keydown的时候阻止默认事件,keyup的时候再提交

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    mounted() {
    this.$nextTick(() => {
    window.addEventListener('keyup', this.enterClick)
    window.addEventListener('keydown', this.enterClick0)
    })
    },
    beforeDestroy() {
    window.removeEventListener('keyup', this.enterClick)
    window.removeEventListener('keydown', this.enterClick0)
    },
    // methods
    enterClick0(event) {
    if(event.keyCode === 13) {
    event.preventDefault()
    }
    },
    enterClick(event) {}
  5. 使用a标签下载文件时自定义文件名,给标签加download属性即可下载(若下载地址与网站地址不同源,对于txt,pdf文件会新开浏览器标签打开文件。),download=”自定义下载文件名”(同样只对同源的时候生效,在本地调试的时候发现不管用不要慌,更到线上就好了)

  6. (blocked:mixed-content)

    是浏览器不允许在https页面里嵌入http的请求
    最简单的办法就是升级成https请求
    也可以

    页面的head中加入(未尝试过):

    1
    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

    意思是自动将http的不安全请求升级为https

  7. element.classList.includes()不是一个方法。

    Element.classList返回的是一个DOMTokenList对象,它是一个类数组对象。includes是Array而不是DOMTokenList的方法。

    1
    2
    3
    4
    // 1.用es6的方法强制转为数组
    [...element.classList].includes()
    // 2.用DOMTokenList.contains方法
    element.classList.contains()
  8. await的异步失败后,会抛出 Uncaught (in promise) err 错误,并且不会执行await这一行下面的代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    let a = () => {
    return new Promise((resolve, reject) => {
    setTimeout(() => {
    reject('error')
    }, 500);
    })
    }
    // 1
    // Uncaught (in promise) err
    let c = async() => {
    console.error(1)
    await a()
    console.error(2)
    }
    c()

    用try catch捕获await异步的错误后,则会继续执行下面的代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 1
    // error
    // 2
    let c = async() => {
    console.error(1)
    try{
    await a()
    }catch(err) {
    console.error(err)
    }
    console.error(2)
    }
    c()

    用try catch捕获await异步的错误后,在catch中return,则不会执行await这一行下面的代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 1
    // error
    let c = async() => {
    console.error(1)
    try{
    await a()
    }catch(err) {
    console.error(err)
    return
    }
    console.error(2)
    }
    c()
  9. this.$router.push(“/home”)报错跳转不了的时候,考虑下this.$router.push(“/home”).catch(()=>{})捕获一下错误,让路由跳转继续

    1
    Uncaught (in promise) Error: Redirected when going from “/login“ to “/home“ via a nvigation guard

    转载

    原因:

    vue-router路由版本更新产生的问题,导致路由跳转失败抛出该错误,但并不影响程序功能

    解决方法1:

    使用编程式导航跳转时,每次使用,后面都跟上.catch方法,捕获错误信息

    this.$router.push(‘/location’).catch(err => ())

    解决方法2(没试过,仅做记录):

    全局解决,替换路由的Push和replace方法,放在src/router/index.js中:

    1
    2
    3
    4
    5
    6
    import Router from 'vue-router'
    const originalPush = Router.prototype.push
    Router.prototype.push = function push(location, onResolve, onReject) {
    if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
    return originalPush.call(this, location).catch(err => err)
    }
    *重复点击当前路由出现报错解决(没试过,仅做记录)
    1
    2
    3
    4
    5
    6
    // 把这段代码直接粘贴到router/index.js中的Vue.use(VueRouter)之前
    const originalPush = VueRouter.prototype.push;
    VueRouter.prototype.push = function(location) {
    return originalPush.call(this, location).catch(err => {})
    };
    Vue.use(VueRouter)