[Vue] Starting from actual development, talk about the best practice of vue

foreword

It has been 4 years since I contacted the Vueframework , developed the actual combat, and further studied the source code idea. Today, we mainly start from the actual development, and talk about Vuethe !

Reference official website: cn.vuejs.org/v2/style-gu…

image.png

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:

  1. Use multiple words when naming components to avoid conflicts with existing and future HTMLelements
  2. propAttribute 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
    }
  }
}
复制代码
  1. Component datamust be a function to avoid multiple component data affecting each other
// 好例子
export default {
  data () {
    return {
      foo: 'bar'
    }
  }
}
复制代码
  1. v-forBe sure to add keyand avoid v-ifwriting it together with
// 好例子
<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>
复制代码
  1. Scope the component styles
  • use scopedproperties
<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>
复制代码

image.png

The class name can JavaScriptalso 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>
复制代码
  1. Private propertyname , 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 vuecoding 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 打包后的体积,优化措施可参考之前整理的技术博文:

做webpack性能优化的一段经历|项目复盘

可改造成SSR,减少首屏加载时间

使用SSR服务端渲染,将组件或是页面通过服务器生成html字符串,再发送到浏览器,这样可以加快首屏加载渲染的速度,提前显示文档内容。

可参考:SSR-完全指南

3. 不需要更新的内容静态化

利用 vuev-once 指令一次性插值的功能,可以将不需要更新的节点内容静态化,这样可以优化更新性能。

4. 尽量减少DOM层级嵌套

DOM 渲染需要的性能开销比较大,我们在开发过程中尽量简化 div 结构,可以减少不必要的 DOM 层级嵌套。对于组件来说,我们应该尽量减少不必要的组件抽象,不必要的组件抽象无疑会增加 DOM 层级嵌套。

5. 大数据量的渲染优化

长列表采用虚拟滚动加载

长列表的数量一般在几百条范围内不会出现意外的效果,浏览器本身足以支撑。可一旦数量级达到上千,页面渲染过程会出现明显的卡顿。数量突破上万甚至十几万时,网页可能直接崩溃了。

为了解决长列表造成的浏览器渲染压力,出现了相应的应对技术——虚拟滚动

实现原理:

虚拟滚动的实现,实际上就是在首屏加载时,只加载可视区域的列表项,当滚动发生时,动态计算获取可视区域内的列表项,并将非可视区域的列表项删除。

image.png

可参考:「前端进阶」高性能渲染十万条数据(虚拟列表)

不活动的组件,可用<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等,避免 htmlurl样式等发生 xss 注入。对于后端返回的数据可进行转义解析,校验不配对的 DOM 标签。
  • 等等......

CSRF防御

  • token验证
    • 第一步:后端随机生成一个 token 值,把这个 token 保存到 session 状态中;同时后端把这个 token 传给前端页面;
    • Step 2: When the front-end page submits the request, add tokento request input parameters or header information, and pass it to the back-end together;
    • The last step: the back-end verifies whether the tokenand sessionin 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 refererrequest , this method has the lowest cost, but it cannot guarantee 100% effectiveness, because the server is not always available referer, and there is referera .

  • 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 vueactual development experience from the three aspects of "coding style, performance, and security", hoping to be helpful to the development partners~~

Guess you like

Origin juejin.im/post/7080096273956601864