Let's talk about how $set is implemented in Vue?
In daily development,
$set
is also a very practical API, because the core of Vue2's responsiveness is to use ES5'sObject.defineProperty
, when we change the array or add new properties to the object by directly modifying the array subscript, Object.defineproperty cannot monitor the changes in the data. At this time, everyone will use$set
allows the modified operation to also respond. We know it but also why. Next, let’s take a look at how $set in Vue is implemented. [Related recommendations: vuejs video tutorial, web front-end development]
Application scenario
let dataArr = ["item1"]; let dataObject = { name: "ccs" }; dataArr[2] = "item2"; dataObject.age = 22; 响应失败,页面没有显示更新新增的数据 this.$set(this.dataArr,2,'item2') this.$set(this.dataObject,'age',22) 响应成功,页面显示更新新增的数据
set implementation
Next, let’s take a look at the definition of $set in Vue
function set(target: Array<any> | Object, key: any, val: any): any { if ( process.env.NODE_ENV !== "production" && (isUndef(target) || isPrimitive(target)) ) { warn( `Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}` ); } if (Array.isArray(target) && isValidArrayIndex(key)) { target.length = Math.max(target.length, key); target.splice(key, 1, val); return val; } if (key in target && !(key in Object.prototype)) { target[key] = val; return val; } const ob = (target: any).__ob__; if (target._isVue || (ob && ob.vmCount)) { process.env.NODE_ENV !== "production" && warn( "Avoid adding reactive properties to a Vue instance or its root $data " + "at runtime - declare it upfront in the data option." ); return val; } if (!ob) { target[key] = val; return val; } defineReactive(ob.value, key, val); ob.dep.notify(); return val; }
In the source code, first determine whether the target of set is undefined
and basic type
if it is If undefined
or basic type
reports an error,
because the user should not set things to undefined and basic types,
then determines whether the target is an array or not. Is the key a legal index? A legal index refers to an integer with a value greater than or equal to 0.
If both conditions are true, call the splice method on the target array to insert or modify the array
,
The splice
here is not the ordinary splice
, is the splice in Wang Wei’s poem, which is the splice
Array implementation response
$set implements array modification response as part of the array method rewritten by the agent. Next, let’s take a look at the specific implementation
const arrayProto = Array.prototype export const arrayMethods = Object.create(arrayProto) const methodsToPatch = [ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ] function def(obj, key, val, enumerable) { Object.defineProperty(obj, key, { value: val, enumerable: !!enumerable, writable: true, configurable: true }); } methodsToPatch.forEach(function (method) { const original = arrayProto[method] def(arrayMethods, method, function mutator (...args) { const result = original.apply(this, args) const ob = this.__ob__ let inserted switch (method) { case 'push': case 'unshift': inserted = args break case 'splice': inserted = args.slice(2) break } if (inserted) ob.observeArray(inserted) ob.dep.notify() return result }) })
The agent in vue rewrites not only splice
, but also has seven methods: push, pop, shift, unshift, splice, sort, reverse
.
First, const result = original.apply(this, args)
executes the method of the original array and obtains its value, and then determines whether to add a value to the array The newly added value will also be implemented Responsiveness
,
The last stepGet the _ob_object of this array
Pair _ob_ The dep in
is distributed and updated.
If you want to learn more about vue's responsiveness, you can check out previous articles
The interviewer asked you about the responsiveness principle of Vue2. How did you answer? - Nuggets (juejin.cn)
Object implementation response
$set
The logic in the lower half is used to process the object response , let’s look down.
if (key in target && !(key in Object.prototype)) { target[key] = val; return val; } const ob = (target: any).__ob__; if (!ob) { target[key] = val; return val; } defineReactive(ob.value, key, val); ob.dep.notify(); return val;
Firstly, we judged the properties. If we directly return in the target object to end the logic,
because vue will only add properties that are not originally in the target object. Loss of response , For example, let obj={} obj.name='ccs'
,
vue will make all attributes in data responsive during initialization. If the value is an object or array, a new Observer
instance will be stored in __ob__. If you want to learn more about vue’s responsiveness, you can check out previous articles
Interviewer I asked you about the responsiveness principle of Vue2. How would you answer? - Nuggets (juejin.cn)
Get the _ob_ of this object for judgment. If it does not exist, it means that it is a ordinary object that has not been initialized by vue instead of a response Formula object Otherwise, manually add the get method and set method to the attribute through
defineReactive to implement the response,
then manually call ## in dep
#notify()Publish updates.
vuejs introductory tutorial, Basic programming video)
The above is the detailed content of Let's talk about how $set is implemented in Vue?. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



When using the Vue framework to develop front-end projects, we will deploy multiple environments when deploying. Often the interface domain names called by development, testing and online environments are different. How can we make the distinction? That is using environment variables and patterns.

The difference between componentization and modularization: Modularization is divided from the perspective of code logic; it facilitates code layered development and ensures that the functions of each functional module are consistent. Componentization is planning from the perspective of UI interface; componentization of the front end facilitates the reuse of UI components.

Ace is an embeddable code editor written in JavaScript. It matches the functionality and performance of native editors like Sublime, Vim, and TextMate. It can be easily embedded into any web page and JavaScript application. Ace is maintained as the main editor for the Cloud9 IDE and is the successor to the Mozilla Skywriter (Bespin) project.

Foreword: In the development of vue3, reactive provides a method to implement responsive data. This is a frequently used API in daily development. In this article, the author will explore its internal operating mechanism.

Vue.js has become a very popular framework in front-end development today. As Vue.js continues to evolve, unit testing is becoming more and more important. Today we’ll explore how to write unit tests in Vue.js 3 and provide some best practices and common problems and solutions.

How to handle exceptions in Vue3 dynamic components? The following article will talk about Vue3 dynamic component exception handling methods. I hope it will be helpful to everyone!

In Vue.js, developers can use two different syntaxes to create user interfaces: JSX syntax and template syntax. Both syntaxes have their own advantages and disadvantages. Let’s discuss their differences, advantages and disadvantages.

In the actual development project process, sometimes it is necessary to upload relatively large files, and then the upload will be relatively slow, so the background may require the front-end to upload file slices. It is very simple. For example, 1 A gigabyte file stream is cut into several small file streams, and then the interface is requested to deliver the small file streams respectively.
