Tricks
# Tricks
[TOC]
# 一、效果实现
# 1.1 懒加载
<ul class="msg-list" @scroll="scrollEvent"></ul>
1
function scrollEvent (e) {
if (
e.srcElement.scrollHeight - e.srcElement.scrollTop <=
e.srcElement.offsetHeight
) {
//加载更多
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 1.2 禁止输入空格
- .trim修饰符实现
<el-input placeholder="请输入名称" v-model.trim="title" maxlength=30></el-input>
1
# 二、用法进阶
# 2.1 emit传递多个参数
//子组件
this.$emit('refrehData',false,true);
//父组件
<child @refrehData="refrehData(arguments)"></child>
refrehData(data) {
this.data1= data[0];
this.data2= data[1];
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 2.2 打开新窗口
let routeData = this.$router.resolve({
path: "/about",
query: {
name:'lei',
age: 18,
phoneNum:12345678901
}
});
window.open(routeData.href, '_blank');
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 2.3 计算属性传参
:data="closure(a,b)"
computed: {
closure() {
return (a1, b1) => a1+b1
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 2.4 自定义指令
# 2.4.1 仿element-ui的v-loading指令
Vue.directive('myLoad', {
// 当被绑定的元素插入到 DOM 中时……
inserted(el, binding) {
if (binding.value) {
//始终设置只有一个加载中弹窗
let myLoadBg = document.getElementById("yiyu-loading-mark");
if (myLoadBg) {
myLoadBg.parentNode.removeChild(myLoadBg)
}
let div = document.createElement("div");
div.setAttribute("id", "yiyu-loading-mark");
div.innerHTML = `<div class="van-loading van-loading--circular"><span class="van-loading__spinner van-loading__spinner--circular" style="color: rgb(25, 137, 250);"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>`; //你也可以去网上找一些酷炫的加载效果放进去,哈哈哈
// document.body.appendChild(div);
el.appendChild(div);
} else {
let myLoadBg = document.getElementById("yiyu-loading-mark");
if (myLoadBg) myLoadBg.parentNode.removeChild(myLoadBg)
}
},
componentUpdated(el, binding) {
if (binding.value) {
//始终设置只有一个加载中弹窗
let myLoadBg = document.getElementById("yiyu-loading-mark");
if (myLoadBg) {
myLoadBg.parentNode.removeChild(myLoadBg)
}
let div = document.createElement("div");
div.setAttribute("id", "yiyu-loading-mark");
div.innerHTML = `<div class="van-loading van-loading--circular"><span class="van-loading__spinner van-loading__spinner--circular" style="color: rgb(25, 137, 250);"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>`;
el.appendChild(div);
} else {
let myLoadBg = document.getElementById("yiyu-loading-mark");
if (myLoadBg) myLoadBg.parentNode.removeChild(myLoadBg)
}
}
})
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
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
# 2.4.2 动态修改meta.title
//1.在main.js 页面里添加自定义指令
Vue.directive('title', {//单个修改标题
inserted: function (el, binding) {
document.title = el.dataset.title
}
})
//2.在需要修改的页面里添加v-title 指令
<div v-title data-title="我是新的标题"></div>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2.5 重置表单
this.form = this.$options.data.call(this).form;
1
# 三、性能优化
# 3.1 computed接收this参数
- 在组件刷新时重复获取
getter
computed: {
a () { return 1 },
b ({ a }) {
return a + 10
}
}
1
2
3
4
5
6
2
3
4
5
6
# 3.2 Object.freeze()
冻结对象
Vue 会通过 Object.defineProperty 对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要 Vue 来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止 Vue 劫持我们的数据呢?可以通过 Object.freeze 方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。
export default {
data: () => ({
users: {}
}),
async created() {
const users = await axios.get("/api/users");
this.users = Object.freeze(users);
}
};
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 3.3 第三方插件的按需引入
在项目中经常会需要引入第三方插件,如果我们直接引入整个插件,会导致项目的体积太大,我们可以借助 babel-plugin-component
,然后可以只引入需要的组件,以达到减小项目体积的目的。以下为项目中引入 element-ui 组件库为例:
(1)首先,安装 babel-plugin-component
:
npm install babel-plugin-component -D
1
(2)然后,将 .babelrc 修改为:
{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
(3)在 main.js 中引入部分组件:
import Vue from 'vue';
import { Button, Select } from 'element-ui';
Vue.use(Button)
Vue.use(Select)
1
2
3
4
2
3
4
# 3.4 阻止冒泡事件(点击子级的时候,不触发父级事件)
<van-collapse-item>
<template #title>
<van-checkbox @click.stop.native="() => {}"></van-checkbox>
</template>
</van-collapse-item>
1
2
3
4
5
2
3
4
5