精华内容
下载资源
问答
  • vue计算属性实现原理

    2019-05-20 14:07:00
    vue计算属性实现原理 转载于:https://www.cnblogs.com/yishenweilv/p/10893826.html

    vue计算属性实现原理

    转载于:https://www.cnblogs.com/yishenweilv/p/10893826.html

    展开全文
  • Vue中有一个计算属性,只要在它的函数里引用了 data 中的某个属性,当这个属性发生变化时,函数就可以嗅探到这个变化,并自动重新执行。 Vue 怎么知道计算属性在函数中引用了哪个 data 属性?这个函数又是怎么...

    在Vue中有一个计算属性,只要在它的函数里引用了 data 中的某个属性,当这个属性发生变化时,函数就可以嗅探到这个变化,并自动重新执行。

     Vue 怎么知道计算属性在函数中引用了哪个 data 属性?这个函数又是怎么知道 data 属性变了,而且只关心它内部引用的那个属性,别的都不管?

    以下是官方的描述:

    由于涉及 Vue 的响应式绑定的原理,如果你对此不熟,最好先看看Vue源码:双向绑定的实现原理

    那么接下来,来看看实现过程:

          1. 首先 b 属性会被处理为存取器属性,访问 b 就会触发其 get 函数。

          2. 处理计算属性 a 时,会执行 a 的函数,从而会执行 this.b,于是触发 b 的 get 函数。

          3. b 的 get 函数会添加 b 属性的依赖项,而刚才在处理计算属性过程中,a 已经作为依赖项被传给了一个全局变量,b 的 get 函数会检测到这个全局变量,并将其添加到自身的订阅者列表中。

          4. 对 b 赋予新的值时,会触发其 set 函数,set 函数中会遍历执行订阅者,a 的值就是在这个时候更新的。

    1、实现defineReactive

    它用于初始化data中的数据,转为存取器, get:该函数通过闭包,维护每个属性单独的dep,定义计算属性时,计算属性绑定的函数引用了哪些data中属性,就会触发get方法,向该属性的dep中添加响应函数设置值时,会将闭包的deps中所有函数,全部循环遍历执行一遍。

    // 定义全局属性,用于向dep传送计算属性函数
    var Dep = null
    
    function defineReactive(obj, key, val) {
          var deps = [];
          Object.defineProperty(obj, key, {
            get: function () {
              if (Dep) {
                deps.push(Dep)
              }
              return val
            },
            set: function (newVal) {
              val = newVal;
              deps.forEach(func => func())
            }
          })
        }

    2、实现defineComputed

    它用于在定义计算属性时,如果绑定函数引用了vue实例data对象中的属性,则会向该属性deps中添加绑定的函数。

    function defineComputed(obj, key, func) {
          func = func.bind(obj);
          let value;
          // 首次定义计算属性,会将第一次的函数执行结果返回给该计算属性,
          // 此后由于闭包,以后该计算属性的value值,会由deps中的函数返回值来决定。
          Dep = function () {
            value = func();
            console.log('Dep中value',value)
          };
          // 执行一次func,函数引用了哪些data中属性,就会触发get方法,向该属性的dep中添加响应函数
          // 在这又使用了闭包,保存计算结果,在get中返回出去
          value = func();
          console.log('defineComputed中value',value)
          // 销毁Dep
          Dep = null;
          // 获取计算属性时,返回函数计算结果
          Object.defineProperty(obj, key, {
            get: function () {
              // 返回函数结果
              return value
            }
          })
        }

    测试结果

    var obj = {}
    
        defineReactive(obj, 'a', 0);
        defineComputed(obj, 'b', function () {
          let storeVal = this.a;
          return storeVal + 1
        })
    
    console.log(obj.b) // 1
    obj.a += 1
    console.log(obj.b) // 2
    obj.a += 1
    console.log(obj.b) // 3

    通过对存取器属性、闭包和观察者模式的综合运用,Vue 巧妙的实现了计算属性,可以看出,Vue 响应式系统的核心理念是“依赖”,DOM 节点之所以随数据而变化,是因为节点依赖于数据,计算属性之所以随数据而变化,是因为计算属性依赖于数据。做好响应式的关键就在于处理好依赖关系。

    参考资料:Vue.js 计算属性的秘密

    展开全文
  • Vue 计算属性

    2021-03-21 22:49:18
    vue中一些数据经常依赖于别的数据做出改变,且改变的逻辑也较复杂,这个时候就需要用到计算属性computed。通俗来说就是当前数据不是确定的,要经常做出改变,而这个改变是其他数据改变导致的。 简单使用 <div ...

    前言

    人生如逆水行舟,不进则退

    简介

    在vue中一些数据经常依赖于别的数据做出改变,且改变的逻辑也较复杂,这个时候就需要用到计算属性computed。通俗来说就是当前数据不是确定的,要经常做出改变,而这个改变是其他数据改变导致的。

    简单使用

    <div id="app">
      <h2>{{firstName}} {{lastName}}</h2>
      <h2>{{firstName+" "+lastName}}</h2>
      <h2>{{getFullName()}}</h2>
      <h2>{{fullName}}</h2> 
    </div>
    <script>
      const app = new Vue({
        el:"#app",
        data:{
          firstName:'Key',
          lastName:'Ting'
        },
        computed:{
          //不加动词,这是计算属性,那么最好以属性命名,这里的写法是计算属性的简写
          fullName(){
            return this.firstName+" "+this.lastName
          }
            
        },
        methods:{
          getFullName(){
            return this.firstName+" "+this.lastName
          }
        }
      })
    </script>
    </body>
    </html>
    
    
    <div id="app">
      <h2>总价格:{{totalPrice}}</h2>
    </div>
    <script>
      const app = new Vue({
        el:"#app",
        data:{
          books:[
            {id: 1001, name: 'Unix编程艺术',price: 119},
            {id: 1002, name: '代码大全',price: 105},
            {id: 1003, name: '深入理解计算机原理',price: 99},
            {id: 1004, name: '现代操作系统',price: 109}
          ]
        },
        computed:{
          totalPrice(){
            //filter/map/reduce 高级用法
            let result = 0
            for(let i=0;i < this.books.length;i++){
              result += this.books[i].price
            }
            return result
          }
        }
      })
    </script>
    
    

    setter和getter

    • 每个计算属性都包括一个getter和一个setter
    • 语法糖情况下,表示getter,取数据
    • setter一般不用,所以我们常称计算属性为只读属性
    <div id="app">
      <h2>{{fullName}}</h2>
    </div>
    <script>
      const app = new Vue({
        el:"#app",
        data:{
          firstName:'Key',
          lastName:'Ting'
        },
        computed:{
          //不加动词,这是计算属性,那么最好以属性命名
          //语法糖,简写
          // fullName(){
              // `this` 指向 app 实例
          //   return this.firstName+" "+this.lastName
          // }
            //规范格式
          fullName:{
            //计算属性中set方法一般不使用,只是一个只读属性
            set(newValue){
              console.log('-------------',newValue);
              const names = newValue.split(' ');
              this.firstName = names[0];
              this.lastName = names[1];
            },
            get(){
              return this.firstName+" "+this.lastName
            }
          }
        }
      })
    </script>
    
    

    计算属性和methods对比

    methods和computed看起来都可以实现我们的功能,那么为什么还要多一个计算属性这个东西呢?

    官方:两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

    原因:计算属性会进行缓存,如果多次使用,计算属性只会调用一次,极大提高了性能除非原属性发生改变,才会重新调用计算属性,更改属性值

    <div id="app">
    <!--  1.直接拼接:语法过于繁琐-->
      <h2>{{firstName}} {{lastName}}</h2>
    <!--  2.通过定义methods 每一个都会调用getfullname函数,如果很复杂,性能消耗是很大的 -->
      <h2>{{getFullName()}}</h2> 
      <h2>{{getFullName()}}</h2>
      <h2>{{getFullName()}}</h2>
    <!--  3.通过computed 只会调用第一次,除非原属性发生改变,才会重新调用计算属性,更改属性值 -->
      <h2>{{fullName}}</h2>
      <h2>{{fullName}}</h2>
      <h2>{{fullName}}</h2>
    </div>
    <script>
      const app = new Vue({
        el:"#app",
        data:{
          firstName:'kebe',
          lastName:'bryant'
        },
        methods:{
          getFullName() {
            console.log('getFullName');
            return this.firstName+' '+this.lastName;
          }
        },
        computed:{
          fullName(){
            console.log('fullName');
            return this.firstName+' '+this.lastName;
          }
        }
      })
    </script>
    
    
    展开全文
  • Vue计算属性

    2021-07-20 19:59:05
    (2)计算属性是放在vue实例的computed中定义,与methods类似,都是定义函数。 (3)计算属性定义在computed中,调用时使用mustache语法调用且后面不跟() <div id="app"> <h2>{{firstName+ ' ' + lastName...

    1、计算属性的基本使用

    (1)当模板{{ }} 里面的插值比较麻烦时,可以将数据放到计算属性,然后用该计算属性。
    (2)计算属性是放在vue实例的computed中定义,与methods类似,都是定义函数。
    (3)计算属性定义在computed中,调用时使用mustache语法调用且后面不跟()

    <div id="app">
      <h2>{{firstName+ ' ' + lastName}}</h2>
      <h2>{{firstName}} {{lastName}}</h2>
      //拼接全名
      //这种拼接后看起来比较复杂,则我们可以用methods,调用方法实现
      <h2>{{getFullName()}}</h2>
      //用methods里面放的是一个方法,我们用如果直接放一个属性会更好
      //使用计算属性
      <h2>{{FullName}}</h2>
    </div>
    
    <script>
      const app = new Vue({
        el:"#app",
        data:{
          firstName:"Lebron",
          lastName:"James"
        },
        methods:{     //定义函数,以函数方式使用;
          getFullName:function () {
            return this.firstName+ ' ' +this.lastName
          }
        },
        computed:{    //计算属性,里面定义函数,将函数以属性方式使用;
          FullName:function () {
            return this.firstName+ ' ' +this.lastName
          }
        }
      })
    </script>
    

    2、计算属性的复杂操作

    <div id="app">
    	// 要实现计算书的总价格
    	// 常规方法很累赘
    	<h2>总价格:{{books[0].price + books[1].price + books[2].price + books[3].price }}</h2>
    	// 用计算属性来实现
    	<h2>总价格:{{totalPrice}}</h2>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                books: [
                    { id: 110, name: 'Unix编程艺术', price: 119 },
                    { id: 111, name: '代码大全', price: 101 },
                    { id: 112, name: '深入理解计算机原理', price: 56 },
                    { id: 113, name: '现代操作系统', price: 87 },
                ]
            },
            computed: {
                totalPrice: function () {
                    let res = 0;
                    for (let i = 0; i < this.books.length; i++) {
                        res += this.books[i].price;
                    }
                    return res;
                }
            }
        })
    </script>
    

    3、计算属性的setter和getter方法

    计算属性的标准写法为:
    computed: {
          fullName:{
          set: function () {
          },
          get: function () {
             return this.firstName + ' ' + this.lastName
          }
        }
    }
    但是一般在使用时,只需要实现get方法;set方法不用设置实现,所以一般直接不要;
    直接写为:
    computed:{
       fullName:function(){        
       	 return this.firstName + ' ' + this.lastName
       }
    }
    在ES6里面对象内函数的增强写法
    computed:{
       fullName(){        
       	 return this.firstName + ' ' + this.lastName
       }
    }
    

    4、计算属性和methods的对比(缓存)

    计算属性具有缓存机制。
    methods中的方法每使用一次就会被调用一次,不管里面的数据是否发生变化。而使用计算属性时,只要里面影响结果的变量没有发生变化,无论计算属性被使用多少次,函数都只会被调用一次。

    <div id="app">
    	<!-- 1.通过定义methods,使用了4次方法,且data中变量没有变化,函数就会被调用4次 -->
    	<!-- <h2>{{getFullName()}}</h2>
    	<h2>{{getFullName()}}</h2>
    	<h2>{{getFullName()}}</h2>
    	<h2>{{getFullName()}}</h2> -->
    	<!-- 2.通过computed,使用了4次方法,且data中变量没有变化,但函数只会被调用1次-->
    	<h2>{{fullName}}</h2>
    	<h2>{{fullName}}</h2>
    	<h2>{{fullName}}</h2>
    	<h2>{{fullName}}</h2>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                firstName: 'koby',
                lastName: 'Bryant'
         },
         methods: {
              getFullName: function () {
                  console.log('getFullName');
                  return this.firstName + ' ' + this.lastName;
              }
          },
          computed: {
              fullName: function () {
                  console.log('fullName');
                  return this.firstName + ' ' + this.lastName;
              }
          }
        })
    </script>
    
    展开全文
  • 文章目录前言实现原理分析initStateinitComputeddefineComputedWatcher对计算属性的处理总结 前言 看这篇文章之前最好先对Vue的MVVM实现原理有一定的认识,因为这是Vue的核心概念,其他的工具大部分都是在此之上...
  • 浅谈Vue计算属性computed的实现原理

    千次阅读 2018-12-18 21:11:55
    虽然目前的技术栈已由Vue转到了React,但从之前使用Vue开发的多个项目实际经历来看还是非常愉悦的,Vue文档清晰规范,api设计简洁高效,对前端开发人员友好,上手快,甚至个人认为在很多场景使用Vue比React开发效率...
  • 1、计算属性默认不执行 Object.defineProperty =>getter 只有在取值的时候才执行 多次取值如果依赖的值不变化就只执行一次,是缓存的原因 依赖的值变化了,需要重新执行 dirty 表示这个值是不是脏的,默认是...
  • 前言很多人提起 Vue 中的 computed,第一反应就是计算属性会缓存,那么它到底是怎么缓存的呢?缓存的到底是什么,什么时候缓存会失效,相信还是有很多人对此很模糊。本文以 Vue 2...
  • 四、Vue计算属性

    2021-01-03 20:34:32
    01-计算属性的基本使用 1.1 计算属性 1、在模板中可以直接通过插值语语法显示一些data中的数据 2、但是在某些情况下,我们可能需要对数据进行一些转化后在显示,或者需要将多个数据结合起来进行显示 比如我们有...
  • 计算属性默认是有缓存的,内部实现参考源码 src/core/instance/state.js 调用initComputed() 方法,创建 watcher /** * 初始化 computed * @param {*} vm * @param {*} computed */ function initComputed (vm:...
  • 计算数据属性(官网称呼),又叫动态数据绑定(相对于静态数据绑定而言).可以在dom渲染之前修改数据.按照官网的解释,计算数据属性是为了简化模板的运算逻辑.从而利于维护.把复杂的逻辑绑定在computed里.当然,利用它也...
  • Vue响应式实现原理

    2020-05-23 11:17:44
    Vue响应式原理 Vue是数据驱动视图实现双向绑定的一种前端框架,采用的是非入侵性的响应式系统,不需要采用新的语法(扩展语法或者新的数据结构)实现对象(model)和视图(view)的自动更新,数据层(Model)仅仅是...
  • <!DOCTYPE html> <html lang="en"> <head> <...组件之使用.sync修饰符与computed计算属性实现购物车原理</title> <script src="vue.js"></scri...
  • Vue源码 深入响应式原理 (四)计算属性 VS 侦听属性Vue源码 深入响应式原理 (四)计算属性 VS 侦听属性computedwatchWatcher optionsdeep watcheruser watchercomputed watchersync watcher总结Vue源码学习目录 ...
  • vue中的computed的实现原理---------需要建立数据依赖搜集,动态计算实现原理 1)问题:计算属性如何与属性建立依赖关系?属性发生变化又如何通知到计算属性重新计算? 如何建立依赖关系?----------利用 ...
  • 很多人提起 Vue 中的 computed,第一反应就是计算属性会缓存,那么它到底是怎么缓存的呢?缓存的到底是什么,什么时候缓存会失效,相信还是有很多人对此很模糊。 本文以 Vue 2.6.11 版本为基础,就深入原理,带你...
  • 最近在学习Vue计算属性的源码,发现和普通的响应式变量内部的实现还有一些不同,特地写了这篇博客,记录下自己学习的成果 文中的源码截图只保留核心逻辑 完整源码地址 可能需要了解一些Vue响应式的原理 Vue 版本:...
  • 很多人提起 Vue 中的 computed,第一反应就是计算属性会缓存,那么它到底是怎么缓存的呢?缓存的到底是什么,什么时候缓存会失效,相信还是有很多人对此很模糊。 本文以 Vue 2.6.11 版本为基础,就深入原理,带你来...
  • Hi,大家好~ 在上一篇 Vue2响应式原理解析(一):从设计出发 中我讲了一下 Vue2 是如何抽象和设计响应式的, data 是如何实现响应式的,包括依赖收集和双向依赖记录的设计思路和关键代码。在这一篇中,我们来一起...
  • 继上一篇:深入理解Vue的watch实现原理及其实现方式 继续讲解Vue的computed实现相对于watch和data来说比较难以理解,要真正的理解computed的工作方式,你需要深入理解Vue的双向数据绑定原理和实现方式。如果你还不是...
  • Vuevue计算属性

    2020-10-10 12:32:06
    计算属性基本使用2.计算属性的setter和getter3.计算属性和methods的对比(缓存) 1.计算属性基本使用 1.引入:模板内(插值数据)的表达式非常便利,设计它们的初衷是用于简单运算的。 但如果在模板中放入太多的逻辑会...
  • 在 Vuejs 中用 watch 来侦听数据变化,computed 用来监听多个属性的变化并返回计算值,那么这两个特性是如何实现的呢?本文讲一下两者实现的具体方法以及一些使用经验,介绍过程中会使用到前面【核心原理】篇中的...
  • 理解Vue中Watch的实现原理和方式之前,你需要深入的理解MVVM的实现原理,如果你还不是很理解,推荐你阅读我之前的几篇文章:彻底搞懂Vue针对数组和双向绑定(MVVM)的处理方式vue.js源码解读系列 - 双向绑定具体如何...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,975
精华内容 4,790
热门标签
关键字:

vue计算属性实现原理

vue 订阅