Vue进阶:分享在Vue开发的6个技巧
Vue.js是我比较喜欢的前端开发框架,这有很多原因。我喜欢它提供的简单性,强大的功能以及出色的性能。
我开始使用Vue是因为一开始觉得它很容易。一直用它,一直在提高,越来越执着去追求最佳的实践。本文分享在vue进阶过程中的6个技巧。
1. 完全理解响应式
响应式如何运作
在前端开发库和框架中,响应式是一个简单的概念。但是,要深入了解它的工作原理可能很困难。但这很值得你花时间。
这是一个小例子:
<h1>{{ name }}</h1>
当name
的值更改时,UI将相应更新。这是解释响应式的非常基本的方法,但是有许多更高级的示例可以帮助您了解其工作原理。
响应式出问题的地方
如果您要访问对象中的属性,则可能会出错,如以下示例中所述:
<template>
<div>
<p>{{ myObject.message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
myObject: {},
};
},
mounted() {
this.myObject.message = "Hello";
},
};
</script>
在上面的示例中,在data()
中将myObject
定义为空对象 {}
。在后面给myObject.message
一个赋值:Hello。
这可能会导致{{myObject.message}}
在收到值的变更的时候也从不显示任何内容。这是为什么?
这是因为Vue开始不知道myObject.message
属性的存在,因此无法对其值的变化做出相应的UI响应。
如何解决呢?
有两种方法可以确保Vue对myObject.message
属性中的更改做出UI响应。最简单的方法是在定义的时候就赋予相应的结构,如下:
myObject: {
message: ""
}
如果data()
中存在myObject.message
,则Vue将侦听并对其值的更改做出UI响应。
另一种方法是完整的对整个对象进行重新赋值,如下:
this.myObject = {message: "Hello"}
简而言之,要让VUE监听对象的属性值的变更并做出相应的响应,需要在
data()
方法中定义好属性,或者每次更新的时候对整个对象进行更新,而不是对象某个属性。
通过很好地了解反应性,您可以:
- 调试UI不按预期更新的场景。
- 确定何时更新和重新渲染视图。
- 了解如何计算计算出的属性。
- 测量需要一些CPU工作量才能进行计算的无功值的成本(例如,表格条件)。
2.父子组件通讯的最佳实践
Vue最吸引我的是灵活的组件设计,组件之间如何互相通信共享数据呢?常见的问题是如何将数据从子级传递到父级组件?或者,当父组件发生更改时,如何确保子组件得到相应更新?
解决组件之间通讯的最佳方式是使用props
。props
将数据从父级传递给子级组件。它们是不可变的,可以有许多类型,例如字符串、布尔值、数组、对象等。
<component :message="myObject.message" />
props
形成单向数据流,这意味着只要myObject.message
在父组件中发生更改,消息props
就会相应地更新。
在子组件定义的props
属性是不可变的,不能去更改它们的值,并且这样不会导致父组件触发更新,只会导致vue警告。
那么如果将子组件的数据传递到父组件呢?这个时候就需要用到事件。
<!-- 父级组件代码 -->
<template>
<div>
<child-component @button-clicked="processUpdate" />
</div>
</template>
<script>
export default {
methods: {
processUpdate(value) {
console.log(value);
}
}
}
</script>
<!-- 子级组件代码 -->
<template>
<button @click="notify">Notify Parent</button>
</template>
<script>
export default {
methods: {
notify() {
this.$emit('button-clicked', true);
}
}
}
</script>
可以使用$emit
将值通过事件从子组件传递到父组件。可以使用v-on:
或@
以及事件的名称(在本例中是@button-clicked
)来侦听来自父组件的事件。使用$emit
,可以传递一个或多个值,它们可以是任何类型的值。
3.性能瓶颈优化
缓慢的应用程序让人头疼,作为软件开发人员,我们的工作是确保我们的应用程序运行平稳。在编写Vue应用程序时,很容易陷入某些陷阱,所以要从初学者到高级,需要很好地理解它们并能够处理它们。
内存泄漏
内存泄漏是Web应用程序中常见的性能问题。即使Vue本身不会无故导致内存泄漏,也可以通过合并第三方库或编写错误的代码来实现。在创建单页应用程序(SPA)时避免内存泄漏尤为重要,因为从设计上讲,用户不会刷新浏览器,因此该应用程序必须执行所有垃圾回收。
在这方面Vue还是做得不错,官方有如何避免内存泄漏的指南,强烈建议从事vue相关的开发人员阅读。
渲染成本
诸如React和Vue之类的前端库和框架使我们变得“懒惰”,看不到渲染时到底发生了什么。只使用v-for
并期望一切正常。
问题在于很难理解渲染的“成本”是多少。Vue应用程序可能有很多出乎意料的方式来带来高昂的渲染成本:
- 产生了太多的DOM元素。
- 页面更新太频繁。
- 使用了需要大量时间进行渲染的第三方组件。
在许多可能的情况下,应用都会产生高昂的渲染成本,结果,用户将遇到延迟带来的等待。
优化事件处理
与严格的Vue相比,这与JavaScript的关系更大,但无论如何都要注意。有些事件可能触发得太频繁了。如果添加scroll
侦听器或@mouseover
事件,则事件处理程序可能会被调用多次。
如果事件处理程序执行的不多,则可能不是问题。但是,如果事件处理程序执行大量计算并花费时间来运行,则可能会导致应用程序严重延迟。发生这种情况的原因是滚动、鼠标悬停和其他事件每秒可以触发事件处理程序数十次。
解决方案是在事件处理程序中使用throttle
(节流)或debounce
(防抖)函数,以限制事件处理程序执行实际计算的次数。Lodash包含这两个功能,并提供了使用它们的简便方法。强烈建议尝试一下,同时也强烈建议使用这个脚本库。
4.了解Vue生态系统
要想在Vue开发方面取得进展,必须了解组成Vue生态系统的包和组件。大多数应用程序至少需要以下一种,但要掌握这个框架,至少应该熟悉以下三种。
Vuex
大多数现代前端应用程序,尤其是单页面应用SPA,都依赖于某种状态管理。Vuex是Vue应用程序的官方状态管理库,与官方的Vue开发工具集成得很好。
它充当一个集中式存储区,所有组件都可以访问该存储区,以获取或更改全局应用程序数据。组件可以并且应该拥有本地数据,但是对于应用程序来说,使用状态管理是必须的,因为它们变得更加复杂,而且多个组件依赖于相同的全局数据。
Vue Router
使用Vue而不使用Vue路由器的情况可能很少,但在某些项目中看到过这种情况。对于熟悉Vue的大多数人都已经熟悉Vue路由器了,所以在这就不讲细节。学习vue-router是创建SPA应用程序的必要条件,而SPA应用是大多数现代前端应用程序的必经之路。
Vue SSR
要真正让自己脱颖而出,应该通过使用官方的Vue库或学习Nuxt.js来学习SSR。当浏览器应用程序的性能开始下降,或者当你不能依赖用户的设备来处理渲染,最好在服务器端进行渲染时,服务器端渲染的需求就会出现。它有助于优化时间到内容-特别是在缓慢的设备或缓慢的互联网-它对SEO也比较友好。
5.正确使用组件
对于缺乏经验的Vue开发人员,容易犯的错误是他们构造大型组件。很多时候,Vue应用程序仅包含一个或几个大型组件即可完成所有工作。我觉得这不是构造组件的好习惯。
项目做多了就越会意识到将应用程序结构化为更小的组件的重要性,每个组件都可以很好地完成一件(或几件)事情。使用较小的组件有利于应用程序的原因有很多:
- 可以在整个应用程序中重用小型组件。
- 代码更简洁,更有条理。
- Vue可以在
v-for
循环中更有效地渲染子组件。
6.学习高级指令
除了v-for
、v-if
以及其他常用的指令,Vue还有有一些指令是不常见的,但仍然是非常有用的,需要去了解学习。
v-once
使用v-once
一次输出一个值并将其设为非活动状态。这意味着在随后的更改中,该值将不会再次呈现。
<span v-once> {{name}} </ span>
事件修饰符
对于v-on
事件,可以使用一些非常方便的修饰符。经常使用的一个是@click.prevent
,它会自动调用click事件的preventDefault()
。
<a href="#" @click.prevent="processClick">点击我</a>
自定义指令
Vue允许注册自己的自定义指令,如果发现自己在整个应用程序中一次又一次地复制相同的行为,那么创建一个可重用的自定义指令是很有意义的。
保持练习
阅读、学习并确保做好笔记,在项目中实践,即使今天对Vue的掌握只迈出了一小步,但也比昨天有进步。