zoukankan      html  css  js  c++  java
  • 项目优化之v-if

    前言:

      在vue项目中,由于功能比较多,需要各种条件控制某个功能、某个标签、表格中的某一行是否显示等,需要使用大量的v-if来判断条件。

      例如:

    <div v-if="isShow(a, b)">this is a tag</div>
    <input v-model="c"></input>
    <script>
      new Vue({
        data () {
          return {
            a: 1,
            b: 2,
            c: ''
          }
        }
        methods: {
          isShow(a, b) {
            console.log('执行ing')
            return +a + +b === 3 ? true : false
          }
        }
      })
    </script>

    例如上述代码:

    我们在输入框中数据数据,每次数据的变化,isShow方法都会执行一遍,如果项目中含有大量这样的代码,那js的执行就很耗费资源,所以我们需要做一个优化,那就是较少这种类似的计算,并且不影响代码的执行,当然存在函数中的条件变化的之后,才会重新执行,这样就大大减少了代码的执行。

    废话不多说开始:

    思路:使用闭包的方式,将数据结果进行缓存,如果参数数据发生了变化才会执行,否则直接返回数据的结果,那样就减少了很多逻辑的执行。

    但是前提条件是:

      类似isShow这个方法,要是纯函数(方法的返回值,只和传入的参数有关)。ps:如果isShow的方法是下面这种是不行的,虽然传入的参数是一样的,但是返回结果可能会受到c值得影响

    isShow (a, b) {
      console.log('执行ing')
      return +this.c + +a + +b === 3 ? true : false
    }

    所以,isShow方法必须是纯函数。

    下面我们需要借用闭包得方式,缓存计算得结果,代码如下:

    function single () {
        const cache = {} // 缓存使用得对象
        return function (fn, args) { // 三个参数分别为函数名称,参数
         let flagName = `${fn.name}${args.length}`
            if (cache[flagName]) { // 查找是否存在这个标记
                var cacheFn = cache[flagName] // 如果存在,就取出这个对象
                if (JSON.stringify(cacheFn.args) == JSON.stringify(args)) { // 判断两次传入得参数是否相同,如果不相同就重新计算,如果相同就直接返回缓存得结果,下面说明为什么使用JSON.stringify
                    return cacheFn.result
                } else {
                    cacheFn.args = args
                    cacheFn.result = cacheFn.fn.apply(null, args)
                    return cacheFn.result
                }
            } else {
                cache[flagName] = { // 增加这个对象
                    fn,
                    args,
                    result: fn.apply(null, args) // 执行这个方法
                }
                return cache[flagName].result // 执行返回这个结果
            }
        }
    }

     借助上述得方法,我们对开始得代码进行改造:

    <div v-if="single(isShow, [a, b]))">this is a tag</div>
    <input v-model="c"></input>
    <script>
      new Vue({
        data () {
          return {
            a: 1,
            b: 2,
            c: ''
          }
        }
        methods: {
          isShow(a, b) {
            console.log('执行ing')
            return +a + +b === 3 ? true : false
          }
        }
      })
    </script>

      经过这样得改造,每次输入框中得值发生变化,会执行single方法,在single中,缓存了isShow方法执行得结果,只要a,b两个值发生变化就不会重新执行isShow方法,这样就做到了节省了很多代码得执行

    ps:为什么使用JSON.stringify(args)?

      例如:

    function func (a, b) {}
    要判断参数的内容和上次是否一样,使用toString方法可以判断和上次缓存的是否一样
    但是如果传入的参数是引用复杂类型('a', {b: 1, c: {d: 2}}),使用JSON.stringify将参数格式化,哪怕是引用类型的一个值或者属性发生变化,都可以对比出不同,至于复杂类型中存在函数、正则,由参数的对象返回结果,不考虑,因为项目中没用到。也没遇到过这么变态的。

      

  • 相关阅读:
    关于工作习惯的一点思考
    BulkSqlCopy 批量导入数据(Ef支持)
    记录下最近项目中常用到的SQL语句
    对象化前端表单(Form)提交
    Python描述符 (descriptor) 详解
    Python装饰器之 property()
    Python魔法方法之属性访问 ( __getattr__, __getattribute__, __setattr__, __delattr__ )
    Python魔法方法总结及注意事项
    面向对象编程(二)
    面向对象编程(一)
  • 原文地址:https://www.cnblogs.com/yaxinwang/p/14136026.html
Copyright © 2011-2022 走看看