Vue 进阶系列丨最佳实践

本文深入讲解Vue 2.0的高级特性,如key优化性能、避免v-if-v-for结合、组件复用策略,以及如何设置组件样式和路由组件不变时的处理。掌握这些技巧,提升前端开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ff925ef5127e4de33c265db3819c1947.png

Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!


2013年7月28日,尤雨溪第一次在 GItHub 上为 Vue.js 提交代码;2015年10月26日,Vue.js 1.0.0版本发布;2016年10月1日,Vue.js 2.0发布。

最早的 Vue.js 只做视图层,没有路由, 没有状态管理,也没有官方的构建工具,只有一个库,放到网页里就可以直接用了。

后来,Vue.js 慢慢开始加入了一些官方的辅助工具,比如路由(Router)、状态管理方案(Vuex)和构建工具(Vue-cli)等。此时,Vue.js 的定位是:The Progressive Framework。翻译成中文,就是渐进式框架。

Vue.js2.0 引入了很多特性,比如虚拟 DOM,支持 JSX 和 TypeScript,支持流式服务端渲染,提供了跨平台的能力等。Vue.js 在国内的用户有阿里巴巴、百度、腾讯、新浪、网易、滴滴出行、360、美团等等。

Vue 已是一名前端工程师必备的技能,现在就让我们开始深入学习 Vue.js 内部的核心技术原理吧!


为列表渲染设置属性 key

在我们使用 v-for 遍历列表时,添加属性 key 可以获得性能上的提升。key 主要使用在新旧虚拟 DOM 节点进行对比的时候,当然属性 key 最好使用元素的唯一属性,比如 id,而不是列表的索引值。示例如下:

<div v-for="item in list" :key="item.id">
  // 内容
</div>

在 v-if、v-if-else、v-else 中使用 key

当我们使用 v-if、v-if-else、v-else 作用在元素类型相同的元素节点上时,最好使用 key 属性,可以避免判断重新渲染出现意想不到的副作用。

由于当状态发生变化的时候,生成的虚拟节点即有可能是 v-if 上的虚拟节点,也可能是 v-else 上的。默认情况下,当两个相同类型的元素直接切换的时候,Vue 会修补已存在的元素,而不是将旧的元素移除,然后再添加新元素。

这时候,如果本来不相同的元素被识别为相同了,那么可能会出现意想不到的场景。

这时候我们通过在元素上添加 key 属性,可以明确的告诉 Vue.js,这两个相同类型的元素并不一样,此时就会移除旧元素,添加新元素了。示例如下:

<div v-if :key="key001">
  // 内容
</div>
<div v-else :key="key002">
  // 内容
</div>

路由地址切换,但是组件不变化

const routes = {
  path:'/hello/:id',
  name:'hello',
  component:Hello
}

如上代码所示,在 /hello/1 切换到 /hello/2 的时候,Hello 组件是不会变化的,Hello 组件的生命周期钩子也不会重新触发。

这是因为 Vue.js 会识别出两个路由使用的是同一个组件,从而进行复用,不会创建新的组件,所以生命周期钩子也不会被触发。对于这种情况,这里提供三种方法来解决。

  • 方法一:观察 $route 对象的变化

通过 watch 观察路由对象的变化,从而做出响应。示例如下:

watch:{
  $route(to,from){
    // 做出响应
  }
}

当然,想上面这样可以监听到页面的变化,但是直接对 $route 进行监听不太好,这样会造成一定程度的性能浪费。当我们页面间跳转时,如果只改变的是 id,那么就只监听 id 即可,比如:

watch:{
  $route.params.id(){下一个错别字
    // 做出响应
  }
}
  • 方法二:为 router-view 添加属性 key

这个方法就是直接在 router-view 标签上添加属性 key,并将属性值和页面做唯一绑定。这样每当页面切换的时候,Vue 都会通过key来判断是不是同一个页面,这样就会让 Vue 认为 router-view 组件是一个新节点,从而销毁组件,创建新的组件。即使是相同组件,url 变了,key 也就变了,组件就会被重新创建。示例如下:

<router-view :key="$route.fullPath"></router-view>
  • 方法三:路由导航守卫 beforeRouteUpdate

beforeRouteUpdate 导航守卫是在组件改变且组件被复用的时候后被调用的,所以可以在路由导航中解决这个问题。

我们只需要把切换页面后想要执行的逻辑放到beforeRouteUpdate 导航守卫钩子函数中执行就可以了。


避免 v-if 和 v-for 一起使用

Vue 官方强烈建议不要把 v-if 和 v-for 同时用在同一个元素上。

通常有两种状态,第一种是 v-if 绑定的值是和遍历的列表项有关的,那么此时就将列表项替换为一个计算属性,让它返回过滤后的列表。比如:

// 修改前
<div v-for="item in list" v-if="item.isShow">
  // 内容
</div>


// 修改后
<div v-for="item in isShowList">
  // 内容
</div>
computed:{
  isShowList(){
    return this.list.filter((item)=>{
        return item.isShow
    })
  }
}

以为 v-for 比 v-if 具有更高的优先级,即使我们想渲染列表中符合要求的一小部分元素,也需要把整个列表都遍历完毕。我们通过计算属性可以提前过滤掉一部分元素。

第二种是 v-if 绑定的值和遍历的列表项无关。此时我们就需要将 v-if 提取到外层容器盒子上。比如:

// 修改前
<div v-for="item in list" v-if="isShowList">
  // 内容
</div>


// 修改后
<div v-if="isShowList">
  <div v-for="item in isShowList">
    // 内容
  </div>
</div>

这样我们不会再检查每一个列表项的 isShowList 属性多次,只需要检查它一次,并且不会在 isShowList 为 false 时运行 v-for 指令。


组件样式设置 scope 作用域

CSS 样式都是全局的,任何一个组件的样式都对整个页面有效。

如果在开发过程中,你A页面的样式是正常的,当跳转到 B 页面后,再次回到 A 页面时,此时 A页面样式出现异常,那么很可能是由于 B 页面的全局样式导致的。

在 Vue 中,我们通过 scope 特性来设置组件的样式作用域。示例如下:

// 修改前
<template>
  <div class="main">
     hello
  </div>
</template>
<style>
  .main{
    background:#f00
  }
<style>


// 修改后
<template>
  <div class="main">
     hello
  </div>
</template>
<style scoped>
  .main{
     background:#f00
  }
<style>

也可以使用 CSS的module,在 react 中使用较多。示例如下:

// 修改前
<template>
  <div class="main outer">
     hello
  </div>
</template>
<style>
  .main{
    background:#f00
  }
<style>


// 修改后
<template>
  <div :class="[$style.main,$style.outer]">
     hello
  </div>
</template>
<style module>
  .main{
    background:#f00
  }
  .outer{
    background:#00f
  }
<style>

避免隐藏的父子组件通信

优先通过props和事件进行父子组件通信,而不是使用 this.$parent 或者改变 prop。遵循 “prop 向下传递,事件向上传递” 原则,这样代码更简洁,更易于理解。


Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!

8ec6eae432e735bc48cbdd17007359b6.png

叶阳辉

HFun 前端攻城狮

往期精彩:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值