foreword
It has been 4 years since I contacted the Vue
framework , developed the actual combat, and further studied the source code idea. Today, we mainly start from the actual development, and talk about Vue
the !
Reference official website: cn.vuejs.org/v2/style-gu…
coding style
When developing code, we need to pay more attention to improving code readability. Because the same project may have multiple development children's shoes under maintenance, digging too many pits will be complained~
Below I summarize several good coding styles based on the official website combined with actual combat development:
- Use multiple words when naming components to avoid conflicts with existing and future
HTML
elements prop
Attribute definitions should be as detailed as possible, at least specifying the type
// 好例子
props: {
status: String
}
// 更好的做法!
props: {
status: {
type: String,
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
}
复制代码
- Component
data
must be a function to avoid multiple component data affecting each other
// 好例子
export default {
data () {
return {
foo: 'bar'
}
}
}
复制代码
v-for
Be sure to addkey
and avoidv-if
writing it together with
// 好例子
<ul v-if="shouldShowUsers">
<li
v-for="user in users"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
复制代码
- Scope the component styles
- use
scoped
properties
<template>
<button class="button button-close">X</button>
</template>
<!-- 使用 `scoped` attribute -->
<style scoped>
.button {
border: none;
border-radius: 2px;
}
.button-close {
background-color: red;
}
</style>
复制代码
<template>
<button :class="[$style.button, $style.buttonClose]">X</button>
</template>
<!-- 使用 CSS Modules -->
<style module>
.button {
border: none;
border-radius: 2px;
}
.buttonClose {
background-color: red;
}
</style>
复制代码
The class name can JavaScript
also be accessed in :
<script>
export default {
created () {
// 获取button编译后的类名:
// _1mB1nfbAEqzAETAbkaBZDV_0
console.log(this.$style.button)
}
}
</script>
复制代码
- BEM 's strategy: Component libraries are recommended
<template>
<button class="c-Button c-Button--close">X</button>
</template>
<!-- 使用 BEM 约定(Block独立的页面、Element元素标签、Modifier修饰符:元素处于的一种状态 -->
<style>
.c-Button {
border: none;
border-radius: 2px;
}
.c-Button--close {
background-color: red;
}
</style>
复制代码
- Private
property
name , use$_
prefix to avoid conflicts
// 好例子
var myGreatMixin = {
// ...
methods: {
$_myGreatMixin_update: function () {
// ...
}
}
}
复制代码
For more good coding style guides, please refer to the official website
performance
When the business code of the project continues to increase sharply, the running cost of the project becomes larger and the construction speed becomes slower, so we need to consider performance optimization. From a vue
coding point of view, we can optimize from the following aspects:
1. Components are loaded on demand
Route lazy loading (using import)
当打包构建时,JavaScript
包变得非常大,影响页面加载,我们可以把不同路由对应的组件分割成不同的代码块,当路由被访问的时候才加载对应组件。使用 import
动态导入,配合 webpack
tree-shaking
摇树功能,没有用到的组件就不会打包到 chunk
,从而提升加载性能。
const Home = () => import('@/components/home')
const Index = () => import('@/components/index')
const About = () => import('@/components/about')
复制代码
2. 提升首屏加载速度
webpack体积优化
如今商业化前端项目大多都是工程化应用,vue
/react
/angular
等框架编码,webpack
打包构建编译,页面首屏加载慢,主要原因是打包构建的 chunk
体积过大。要提升首屏加载速度,首先需要优化 webpack
打包后的体积,优化措施可参考之前整理的技术博文:
可改造成SSR,减少首屏加载时间
使用SSR
服务端渲染,将组件或是页面通过服务器生成html
字符串,再发送到浏览器,这样可以加快首屏加载渲染的速度,提前显示文档内容。
可参考:SSR-完全指南
3. 不需要更新的内容静态化
利用 vue
的 v-once
指令一次性插值的功能,可以将不需要更新的节点内容静态化,这样可以优化更新性能。
4. 尽量减少DOM层级嵌套
DOM
渲染需要的性能开销比较大,我们在开发过程中尽量简化 div
结构,可以减少不必要的 DOM
层级嵌套。对于组件来说,我们应该尽量减少不必要的组件抽象,不必要的组件抽象无疑会增加 DOM
层级嵌套。
5. 大数据量的渲染优化
长列表采用虚拟滚动加载
长列表的数量一般在几百条范围内不会出现意外的效果,浏览器本身足以支撑。可一旦数量级达到上千,页面渲染过程会出现明显的卡顿。数量突破上万甚至十几万时,网页可能直接崩溃了。
为了解决长列表造成的浏览器渲染压力,出现了相应的应对技术——虚拟滚动。
实现原理:
虚拟滚动的实现,实际上就是在首屏加载时,只加载可视区域的列表项,当滚动发生时,动态计算获取可视区域内的列表项,并将非可视区域的列表项删除。
不活动的组件,可用<keep-alive>
缓存
<keep-alive>
是 Vue 的内置组件,用它来包裹动态组件时,会缓存不活动的组件实例。和 <transition>
相似,<keep-alive>
是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中。
// 基本使用
<keep-alive>
<component :is="view"></component>
</keep-alive>
复制代码
<keep-alive>
主要用于保留组件状态或是避免重新渲染。
安全
XSS防御
- 不使用不可信的模板直接渲染,可用变量动态拼接模板再渲染
<template>
<div>{{ msg }}</div>
</template>
复制代码
- 小心使用
v-html
,:url
,:style
等,避免html
、url
、样式
等发生xss
注入。对于后端返回的数据可进行转义解析,校验不配对的DOM
标签。 - 等等......
CSRF防御
- token验证
- 第一步:后端随机生成一个
token
值,把这个token
保存到session
状态中;同时后端把这个token
传给前端页面; - Step 2: When the front-end page submits the request, add
token
to request input parameters or header information, and pass it to the back-end together; - The last step: the back-end verifies whether the
token
andsession
in the front-end are consistent, if they are consistent, it is legal, otherwise it is an illegal request.
- 第一步:后端随机生成一个
- referer verification
Verifying the source of the referer
request , this method has the lowest cost, but it cannot guarantee 100% effectiveness, because the server is not always available referer
, and there is referer
a .
- verification code
Force the user to interact with the page application to successfully verify the captcha to complete the final request. This method is good for containment csrf
, but the user experience is relatively poor.
Summarize
The above mainly summarizes some vue
actual development experience from the three aspects of "coding style, performance, and security", hoping to be helpful to the development partners~~