前端项目难点和性能优化

  • 项目难点
  • ElementUI表格中图片懒加载
  • 设置定时器防止频繁点击按钮
  • vue2数据更新,页面不刷新
  • i18n中英文翻译
  • canvas签字板
  • 二次封装UI组件
  • 列表下拉刷新、上拉加载
  • 重复ID数据合并为一条
  • keep-alive多级路由缓存
  • 性能优化
  • echarts多图表绘制卡顿
  • 多级菜单转树形结构、懒加载
  • 打包优化


项目难点

ElementUI表格中图片懒加载

需求:要求在table表格中渲染图片

利用 slot 插槽引入图片

<el-table-column
        prop="img"
        label="图片"
      >
        <template v-slot="scope">
          <img
            :src="scope.row.img"
            alt=""
            width="40"
            height="40"
          >
        </template>
      </el-table-column>

通过 require 懒加载图片

img: require("@/assets/logo.png")

效果图:

前端项目 nginx dockerfile_vue.js

设置定时器防止频繁点击按钮

需求:定义相同按钮点击5s之后才能再次点击,避免频繁点击按钮

<el-button @click="handleClick('up')">上</el-button>
    <el-button @click="handleClick('down')">下</el-button>
    <el-button @click="handleClick('left')">左</el-button>
    <el-button @click="handleClick('right')">右</el-button>

初始化按钮状态为 true

mounted() {
    ["up", "down", "left", "right"].forEach((item) => {
      this[`${item}Status`] = true
    })
  }

按钮状态为 true 时点击成功,并将状态改为 false ,利用 setTimeout 设置定时器间隔5s,按钮状态更新为 true ,并利用clearTimeout 销毁定时器

handleClick(val) {
      let buttonStatus= `${val}Status`
      if (this[buttonStatus]) {
        this.$message({
          message: val,
          type: "success"
        })
        this[buttonStatus] = false
        const timer = setTimeout(() => {
          this[buttonStatus] = true
          clearTimeout(timer)
        }, 5000)
      }
    }

效果图:

前端项目 nginx dockerfile_删除元素_02

vue2数据更新,页面不刷新

vue2双向绑定原理:vue2采用数据劫持结合发布订阅模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter、getter,在数据变动时发布消息给订阅者,触发相应的监听回调,从而使关联的组件重新渲染。

缺点:

  1. 对象直接添加或删除属性,页面不会刷新
    解决办法:
    $forceUpdate() :强行刷新组件
    $set:给对象动态添加属性并赋值
    $delete :删除对象的属性
对象:{{obj}}
      <el-button @click="addObj">添加</el-button>
      <el-button @click="delObj">删除</el-button>
data() {
    return {
      obj: {
        name: "coco"
      }
    }
  }

添加:

addObj() {
      // 1. $forceUpdate() 强行刷新组件
      // this.obj["age"] = 18
      // this.$forceUpdate()

      // 2. $set 给对象动态添加属性并赋值
      // this.$set(this.obj, "age", 18)
    }

删除:

delObj() {
      // $delete 删除对象的属性
      // this.$delete(this.obj, "name")
    }
  1. 数组通过下标修改元素,页面不会刷新
    解决办法:
    $forceUpdate() :强行刷新组件
    unshift() :数组头部添加元素
    push():数组尾部添加元素
    shift() :数组头部删除元素
    pop():数组尾部删除元素
    splice():数组指定索引插入删除替换元素,参数1:索引开始位置、参数2:修改元素个数、参数3:修改后的值
    sort():数组按升序或降序排序
    reverse():颠倒数组顺序
数组:{{arr}}
      <el-button @click="addArr">添加</el-button>
      <el-button @click="delArr">删除</el-button>
      <el-button @click="sortArr">排序</el-button>
data() {
    return {
      arr: [100, 123]
    }
  }

添加:

addArr() {
      // $forceUpdate() 强行刷新组件
      // this.arr[0] = 'hello'
      // this.$forceUpdate()

      // unshift() 数组头部添加元素
      // this.arr.unshift("hello")

      // push() 数组尾部添加元素
      // this.arr.push("hi")

      // splice() 数组指定索引插入替换元素
      // this.arr.splice(0, 2, "hhh", "hihi")
    },

删除:

delArr() {
      // shift() 数组头部删除元素
      // this.arr.shift()

      // pop() 数组尾部删除元素
      // this.arr.pop()
      
      // splice() 数组指定索引删除元素
      // this.arr.splice(1, 1)
    }

排序:

sortArr() {
      // sort() 数组按降序排序
      // this.arr.sort((a, b) => b - a)

      // reverse() 颠倒数组顺序
      // this.arr.reverse()
    }

i18n中英文翻译

  1. 安装插件
    安装Vue国际化插件 vue-i18n ,执行如下命令:
npm install vue-i18n --save
  1. 引入语言包
    在src目录下,添加 i18n 文件夹,添加中文语言包(zh_CN.js)和英文语言包(en_US.js)

    zh_CN.js:
export default {
  '男': '男',
  '女': '女'
}

en_US.js:

export default {
  '男': 'Male',
  '女': 'Female'
}
  1. main.js引入i18n
import Vue from 'vue'
import App from './App.vue'
import VueI18n from 'vue-i18n'
import zh from '@/i18n/zh_CN'
import en from '@/i18n/en_US'

Vue.use(VueI18n)
const i18n = new VueI18n({
  locale: localStorage.getItem('locale') | 'zh', // 语言标识
  messages: {
    'zh': zh, // 中文语言包
    'en': en  // 英文语言包
  }
})

new Vue({
  render: h => h(App),
  i18n  // 在Vue中挂载i18n
}).$mount('#app')
  1. 语言切换

使用方式

  1. 在template模板中,使用$t() 语法翻译
  2. 通过 localStorage.setItem() 本地存储语言类型
  3. 通过 this.$i18n.locale 修改语言类型
<template>
  <div>
    <el-button @click="changeLang">{{lang==='zh'?'中文':'English'}}</el-button>
    <p>{{this.$t("男")}}</p>
    <p>{{this.$t("女")}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      lang: "zh"
    }
  },
  mounted() {
    this.$i18n.locale = this.lang
  },
  methods: {
    changeLang() {
      this.lang = this.lang === "zh" ? "en" : "zh"
      localStorage.setItem("locale", this.lang)
      this.$i18n.locale = this.lang
    }
  }
}
</script>

前端项目 nginx dockerfile_javascript_03

前端项目 nginx dockerfile_删除元素_04

canvas签字板

二次封装UI组件

列表下拉刷新、上拉加载

重复ID数据合并为一条

keep-alive多级路由缓存


性能优化

echarts多图表绘制卡顿

多级菜单转树形结构、懒加载

打包优化