Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the way to avoid misusing this in Vue to read data in data?

2025-03-13 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "what is the way to avoid abuse of this in Vue to read data in data". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's way of thinking to study and learn "what is the way to avoid abuse of this in Vue to read data in data".

1. The process of reading data in data with this

In the Vue source code, the data in data will be added to the getter function and setter function to convert it into a responsive one. The code for the getter function is as follows:

Function reactiveGetter () {var value = getter? Getter.call (obj): val; if (Dep.target) {dep.depend (); if (childOb) {childOb.dep.depend (); if (Array.isArray (value)) {dependArray (value);} return value}

When reading data in data with this, the getter function is triggered, in which var value = getter? Getter.call (obj): the val; obtains the value and executes return value to achieve the purpose of reading the data.

But there is also a piece of code in which dependencies are collected through a series of complex logical operations. It is only known here that dependencies will be collected when Dep.target exists.

A conclusion can be drawn here that when this is used to read data in data when Dep.target exists, dependencies are collected. If this is misused to read data in data, dependencies will be collected repeatedly, resulting in performance problems.

2. When does Dep.target exist

Dep.target is assigned by dependencies. Dependency is also known as Watcher (listener) or subscriber. There are three kinds of dependencies in Vue, two of which are very common, namely watch (listener) and computed (computational property). There is also a hidden dependency-rendering Watcher, which is created during the first rendering of the template.

Dep.target is assigned when the dependency is created, and the dependency is created with the constructor Watcher.

Lue = this.lazy? Undefined: this.get ();}; Watcher.prototype.get = function get () {pushTarget (this); try {value = this.getter.call (vm, vm);} catch (e) {} function Watcher (vm, expOrFn, cb, options, isRenderWatcher) {/ / If (typeof expOrFn = = 'function') {this.getter = expOrFn;} else {this.getter = parsePath (expOrFn);} this.va return value}; Dep.target = null; var targetStack = []; function pushTarget (target) {targetStack.push (target); Dep.target = target;}

The instance method get is executed at the end of the constructor Watcher, and the pushTarget (this) assignment to Dep.target is performed in the instance method get.

Dependencies are created when Vue pages or components are rendered for the first time, so the performance problem should be slow rendering for the first time.

Where to misuse this to read data in data

Executing code that misuses this to read data in data when Dep.target exists can cause performance problems, so you need to figure out where the code is written to be executed, in other words, where misuse of this to read data in data can cause performance problems.

In the second section, it is introduced that value = this.getter.call (vm, vm) will be executed after Dep.target is assigned, where this.getter is a function, so if you use this to read data data, you will collect dependencies. If you abuse it, it will cause performance problems.

This.getter is assigned during the process of creating dependencies, and the this.getter for each dependency is different. Let's introduce them one by one.

The this.getter that the watch (listener) depends on is the parsePath function, whose function argument is the listening object.

Var bailRE = new RegExp (("[^" + (unicodeRegExp.source) + ". $_\\ d])); function parsePath (path) {if (bailRE.test (path)) {return} var segments = path.split ('.'); return function (obj) {for (var I = 0; I)

< segments.length; i++) { if (!obj) { return } objobj = obj[segments[i]]; } return obj } } 如下所示的代码中的 a 和 a.b.c作为参数传入parsePath函数会返回一个函数赋值给this.getter,执行this.getter.call(vm, vm)会得到this.a和this.a.b.c的值。在这个过程中不会存在滥用this去读取data中数据的场景。 watch:{ a:function(newVal, oldVal){ //做点什么 } } vm.$watch('a.b.c', function (newVal, oldVal) { // 做点什么 }) computed(计算属性)依赖的this.getter有两种,如果计算属性的值是个函数,那么this.getter就是这个函数。如果计算属性的值是个对象,那么this.getter就是这个对象的get属性值,get属性值也是个函数。在这个函数可能会存在滥用this去读取data中数据的场景,举个例子,代码如下所示。 computed:{ d:function(){ let result = 0; for(let key in this.a){ if(this.a[key].num >

20) {result + = this.a [key] .num + this.b + this.c;} else {result + = this.a [key] .num + this.e + this.f;}} return result;}}

In the calculation attribute d, there is abuse of this to read data data. Where this.an is an array, at this time the value of Dep.target is the dependency of computational attribute d. In the loop this.a, this is used to obtain the data of a, b, c, e, f, so that these data carry out a series of complex logical operations to repeatedly collect the dependency of computational attribute d. Causes the speed of getting the value of the calculated attribute d to become slower, resulting in performance problems.

The this.getter that renders Watcher is a function as follows:

UpdateComponent = function () {vm._update (vm._render (), hydrating);}

Where vm._render () converts the rendering function render generated by the template template into a virtual DOM (VNode): vnode = render.call (vm._renderProxy, vm.$createElement);, give an example to illustrate what the rendering function render is.

For example, template template:

{{a}} {{b}}

The rendering function render is generated through vue-loader, as follows:

(function anonymous () {with (this) {return _ c ('div', {attrs: {"class": "wrap"}}, [_ c (' pause, [_ v (_ s (a)), _ c ('span', [_ v (_ s (b)])}}))

The function of the with statement is to specify the default object for a statement or a group of statements. For example, with (this) {a + b} is equivalent to this.a + this.b, so using {{a}} in the template template is equivalent to using this to read a data in data. Therefore, there may also be scenarios where this is abused to read data in data in the rendering function render generated by template template. For example, the code is as follows:

{{arr [item.index] ['name']}} {{obj [item.id] [' age']}}

In the process of cycling the list array with v-for, we constantly use this to read the data of arr and obj in data, and make these data carry out a series of complex logical operations to collect this dependency repeatedly, resulting in slower rendering for the first time, resulting in performance problems.

4. How to avoid abusing this to read data in data

To sum up, misusing this to read data in data in computational properties and template templates can lead to repeated collection of dependencies, resulting in performance problems, so how to avoid this situation.

How to avoid in calculating attributes

To avoid using the ES6 object to deconstruct the assignment, the value of the computed property is a function whose argument is the instantiated this object of Vue, which can be optimized in the example of abusing this in the above computed attribute.

Before optimization:

Computed: {d:function () {let result = 0; for (let key in this.a) {if (this.a [key] .num > 20) {result + = this.a [key] .num + this.b + this.c;} else {result + = this.a [key] .num + this.e + this.f }} return result;}}

After optimization:

Computed: {d ({a, b, c, e, f}) {let result = 0; for (let key in a) {if (a [key] .num > 20) {result + = a [key] .num + b + c;} else {result + = a [key] .num + e + f;}} return result;}}

The above uses deconstruction assignment to assign a, b, c, e, f in data data to the corresponding variables a, b, c, e, f in advance, and then accesses data data through these variables in the calculation attribute, and does not trigger the dependency collection of the corresponding data in data. This only uses this to read the data in data once, triggers dependency collection only once, and avoids the performance problems caused by repeated dependency collection.

How to avoid in template template

Deal with the data used in the v-for loop in advance, do not read array, object type data in the v-for loop. This can be optimized in the example of misuse of this in the above template template.

Assuming that list, arr and obj are all data returned by the server, and arr and obj are not used in any module rendering, you can optimize them in this way.

Before optimization:

{{arr [item.index] ['name']}} {{obj [item.id] [' age']}}

After optimization:

{item.name = this.arr [item.index] .name; item.age = this.obj [item.id] .age;}) return list }},} Thank you for your reading, the above is the content of "what is the method of avoiding abuse of this in Vue to read data in data". After the study of this article, I believe you have a deeper understanding of what is the method of avoiding abuse of this in Vue to read data in data, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report