• 技术文章 >web前端 >js教程

    Vue.js中computed使用详解

    php中世界最好的语言php中世界最好的语言2018-05-03 15:43:28原创2276
    这次给大家带来Vue.js中computed使用详解,Vue.js中computed使用的注意事项有哪些,下面就是实战案例,一起来看一下。

    JS属性:

    JavaScript有一个特性是 Object.defineProperty ,它能做很多事,但我在这篇文章只专注于这个方法中的一个:

    var person = {};
    Object.defineProperty (person, 'age', {
     get: function () {
      console.log ("Getting the age");
      return 25;
     }
    });
    console.log ("The age is ", person.age);
    // Prints:
    //
    // Getting the age
    // The age is 25

    (Obeject.defineProperty是Object的一个方法,第一个参数是对象名称,第二个参数是要设置的属性名,第三个参数是一个对象,它可以设置这个属性是否可修改、可写等,而这篇文章主要使用的是Obeject.defineProperty的访问器属性,感兴趣的朋友可以自行google或者查看Js高及程序设计)

    尽管 person.age 看起来像是访问了对象的一个属性,但其实在内部我们是运行了一个函数。

    一个基本可响应的Vue.js

    Vue.js内部构建了一个可以将普通的对象转化为可以被观察的值( 响应属性 ),下面为大家展示一个简化版的如何添加响应属性的案例:

    function defineReactive (obj, key, val) {
     Object.defineProperty (obj, key, {
      get: function () {
       return val;
      },
      set: function (newValue) {
       val = newValue;
      }
     })
    };
    // 创建一个对象
    var person = {};
    // 添加可响应的属性"age"和"country"
    defineReactive (person, 'age', 25);
    defineReactive (person, 'country', 'Brazil');
    // 现在你可以随意使用person.age了
    if (person.age < 18) {
     return 'minor';
    }
    else {
     return 'adult';
    }
    // 设置person.country的值
    person.country = 'Russia';

    有趣的是, 25 和 ‘Brazil' 还是一个闭包内部的变量,只有当赋给它们新值的时候 val 才会改变。 person.country 并不拥有 'Brazil' 这个值,而是getter这个函数拥有 'Brazil' 这个值。

    声明一个计算属性

    让我们创建一个定义计算属性的函数 defineComputed 。这个函数就跟大家平时使用computed时的一样。

    defineComputed (
     person, // 计算属性就声明在这个对象上
     'status', // 计算属性的名称
     function () { // 实际返回计算属性值的函数
      console.log ("status getter called")
      if (person.age < 18) {
       return 'minor';
      }
      else {
       return 'adult';
      }
     },
     function (newValue) {
      // 当计算属性值更新时调用的函数
      console.log ("status has changed to", newValue)
     }
    });
    // 我们可以像使用一般的属性一样使用计算属性
    console.log ("The person's status is: ", person.status);

    让我们写一个简单的 defineComputed 函数,它支持调用计算方法,但目前不需要它支持 updateCallback 。

    function defineComputed (obj, key, computeFunc, updateCallback) {
     Object.defineProperty (obj, key, {
      get: function () {
       // 执行计算函数并且返回值
       return computeFunc ();
      },
      set: function () {
       // 什么也不做,不需要设定计算属性的值
      }
     })
    }

    这个函数有两个问题:

    每次访问计算属性时都会执行一次计算函数 computeFunc ()

    它不知道什么时候更新 (即当我们更新某个data中的属性,计算属性中也会更新这个data属性)

    // 我希望最终函数执行后是这个效果:每当person.age更新值的时候,person.status也同步更新
    person.age = 17;
    // console: status 的值为 minor
    person.age = 22;
    // console: status 的值为 adult

    增加一个依赖项

    让我们增加一个全局变量 Dep :

    var Dep = {
     target: null
    };

    这是一个依赖项,接着我们用一个骚操作来更新 defineComputed 函数:

    function defineComputed (obj, key, computeFunc, updateCallback) {
     var onDependencyUpdated = function () {
      // TODO
     }
     Object.defineProperty (obj, key, {
      get: function () {
       // 将onDependencyUpdated 这个函数传给Dep.target
       Dep.target = onDependencyUpdated;
       var value = computeFunc ();
       Dep.target = null;
      },
      set: function () {
       // 什么也不做,不需要设定计算属性的值
      }
     })
    }

    现在让我们回到之前设置的响应属性上:

    function defineReactive (obj, key, val) {
     // 所有的计算属性都依赖这个数组
     var deps = [];
     Object.defineProperty (obj, key, {
      get: function () {
       // 检查是否调用了计算属性,如果调用了,Department.target将等于一个onDependencyUpdated函数
       if (Dep.target) {
        // 把onDependencyUpdated函数push到deos中
        deps.push (target);
       }
       return val;
      },
      set: function (newValue) {
       val = newValue;
       // 通知所有的计算属性,告诉它们有个响应属性更新了
       deps.forEach ((changeFunction) => {
        changeFunction ();
       });
      }
     })
    };

    我们可以在计算属性定义的函数触发更新回调后更新 onDependencyUpdated 函数。

    var onDependencyUpdated = function () {
     // 再次计算 计算属性的值
     var value = computeFunc ();
     updateCallback (value);
    }

    把它们整合到一起:

    让我们重新访问我们的计算属性 person.status :

    person.age = 22;
    defineComputed (
     person,
     'status',
     function () {
      if (person.age > 18) {
       return 'adult';
      }
     },
     function (newValue) {
      console.log ("status has changed to", newValue)
     }
    });
    console.log ("Status is ", person.status);

    相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

    推荐阅读:

    Vue.js中computed与methods使用与区别

    beforeEach实现路由跳转验证功能

    以上就是Vue.js中computed使用详解的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    自己动手写 PHP MVC 框架:点击学习

    快速了解MVC架构、了解框架底层运行原理

    专题推荐:javascript computed Vue.js
    上一篇:vuex使用步骤剖析 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• 浅析Angular中的Change Detection机制• 浅析Angular变更检测中的订阅异步事件• Angular学习之聊聊Http ( 错误处理 / 请求拦截 )• 一文聊聊node中的path模块• 一文详解多版本node的安装和管理
    1/1

    PHP中文网