技巧 / 坑点
1.setTimeout/ setInterval
场景一 :this 指向改变无法用 this 访问 vue 实例
- mounted(){
- setTimeout( function () {
- //setInterval 同理
- console.log(this); // 此时 this 指向 Windows 对象
- },1000) ;
- }
解决方法 : 使用箭头函数或者缓存 this
- // 箭头函数访问 this 实例因为箭头函数本身没有绑定 this
- setTimeout(() => {
- console. log(this);}, 500) ;
- // 使用变量访问 this 实例 let self=this;
- },1000);
- setTimeout (function () {
- console. log(self);// 使用 self 变量访问 this 实例
- }, 1000) ;
setInterval 路由跳转继续运行并没有销毁
场景一 : 比如一些弹幕, 走马灯文字, 这类需要定时调用的, 路由跳转之后, 因为组件已经销毁了, 但是 setlnterval 还没有销毁, 还在继续后台调用, 控制台会不断报错, 如果运算量大的话, 无法及时清除, 会导致严重的页面卡顿.
解决方法 : 在组件生命周期 beforeDestroy 停止 setInterval
- created() {
- this.intervalid = setInterval(() => {
- this.layerError = "";
- this.Timer = null;
- }, 100000);
- }
- beforeDestroy( ){
- // 我通常是把 setInterval( ) 定时器赋值给 this 实例, 然后就可以像下面这么暂停.
- clearInterval(this.intervalid);
- }
2.Vue 路由拦截浏览器后退实现草稿保存类似需求
场景一 : 为了防止用户突然离开, 没有保存已输入的信息.
解决方法 :
- // 在路由组件中: mounted(){
- },
- beforeRouteLeave (to, from, next) {
- if(用户已经输入信息){
- // 出现弹窗提醒保存草稿, 或者自动后台为其保存
- }else{
- next(true);// 用户离开
- }
- }
3. 自定义组件添加 click 等事件不生效
场景一 : 一些自定义组件, 需要额外添加一些事件来实现一些特定需求
- <template>
- <el-progress type="circle" :percentage="0" @click="stopProgress"></elprogress>
- </template>
- <script>
- export default {
- methods:{
- stopProgress() {
- console.log('停止')
- }
- }
- }
- </script>
解决方法 : 使用. native 修饰符
- <template>
- <el-progress type="circle" :percentage="0" @click.native="stopProgress"></el-progress>
- </template>
- <script>
export default { 前端交流; 582735936
- methods:{
- stopProgress() {
- console.log('停止')
- }
- }
- }
- </script>
4. 手动操控自定义组件
场景一 : 一些自定义组件, 需要去获取组件对象进行一些其他的 Dom 操作
解决方法 : 使用 ref 属性暴露组件获取句柄
- <template>
- <el-progress type="circle" :percentage="O" ref="progress"></el-progress></template>
- <script>
- this.$refs.progress // 组件对象实例, 可以手动调用组件的内置方法和属性
- this.$refs.progress.$el // 组件 对象的最外层 dom 元素
- </script>
5. 深度作用选择器
场景一 : scoped 的样式, 希望影响到子组件的默认样式
在样式中设置完 scoped 在浏览器解析为如下图这样, a 是个 div,a div 里面包含一个组件里面解析完了 div 的样式名字为 b, 想在父组件影响到子组件的默认样式. 解决方法:
- <style scoped>
- .a>>> .b { /.../ }
- </style>
- // 有些像 Sass 之类的预处理器无法正确解析 >>>. 这种情况下你可以使用 / deep / 操作符取而代之 - - - - 这是一个
- >>> 的别名, 同样可以正常工作.
- <style scoped lang="sCSS">
- .a /deep/ .b { /.../ }
- </style>
6.Vue 数组 / 对象更新视图不更新
场景一 : 很多时候我们习惯于这样操作数组和对象
- data() {
- return {
- arr: [1,2,3],
- obj:{
- a: 1,
- b: 2
- }
}; 前端交流; 582735936
- },
- // 数组更新视图不更新
- this.arr[0] = 'OBKoro1';
- this.arr.length = 1;
- console.log(arr);// ['OBKoro1'];
- // 数据更新, 对象视图不更新
- this.obj.c = 'OBKoro1';
- delete this.obj.a;
- console.log(obj); // {b:2,c:'OBKoro1'}
解决方法 :
this. $set(你要改变的数组 / 对象, 你要改变的位置 / key, 你要改成什么 value)
数组原生方法触发视图更新 ( vue 官网可查):
整体替换数组 / 对象
7.Vue Filters 过滤器的使用
场景一 : 常见的数据文本的格式化
- <!-- 在双花括号中 -->
- <div>
- {{ message | DateFormat }}
- </div>
- // 展示正确时间
- <!-- 在'v-bind'中 -->
- <div v-bind:id="rawId | formatId">
- </div>
Demo: 一个日期过滤器返回 yyyy- MM-ddhh:mm:ss 的样式
引入一个提前写好日期格式化的 JS import dayjs from 'dayjs';
- export default {
- data() {
- return {
- // 时间毫秒
- message:18324798324789
- }
- },
- filters: {
- // 传入进行日期格式化
- DateFormat(value) {
- return dayjs(value).format("YYYY-MM-DD HH:mm:ss")
- }
- }
- }
8.Vue 深度 watch 与 watch 立即触发回调
场景一 : 在 watch 里面监测对象里面对应的值是监测不到的, 可以用如下方法.
选项: deep
在选项参数中指定 deep:true, 可以监听对象中子属性的变化.
选项: immediate
在选项参数中指定 immediate:true, 将立即以表达式的当前值触发回调, 也就是默认触发一次.
- watch: {
- obj: {
- handler(val, oldVal) {
- console.log('属性变化触发这个回调',val, oldVal);
- },
- deep: true // 监测这个对象中每一个属性的变化
- },
- step: { // 属性 //watch
- handler(val, oldVal) {
- console.log("默认触发一次", val, oldVal);
- },
- immediate: true // 默认触发一次
来源: http://www.qdfuns.com/article/51116/65693aa2b33fbc241d42299599aeca62.html