About the Vue 3.0

Preface:

  • The official version:VueThe team released the official version 3.0 on 2020.09.18
  • Preconditions:VueAlthough a large number of 2.0 versions remainapiBut because it is usedTypeScriptRefactoring, so I want to learn more about 3.0TSBasic use of

Six highlights of Vue3.0

The serial number features parsing
1 Performance Performance is 1.3~2 times faster than Vue2.0
2 Tree shaking support Compiled on demand, more lightweight volume
3 Composition API Combination API, refer toReact hooksunderstand
4 Better TypeScript support Better support for Ts
5 Custom Renderer API Expose the custom rendering API
6 Fragment,Teleport(Protal),Suspense More advanced components

Note: Vue3.0 in concrete can be reference for making the relevant source files, https://github.com/vuejs/vue-next/tree/master/packages


What is Vue3.0 optimized for, and how to make it lighter and faster?

  • 1. Diff algorithm optimization
    • The virtual Dom in Vue 2 is a full comparison
    • Vue 3 Added static flag (PatchFlag)
    • After data changes, only nodes with PatchFlag are compared with the last virtual DOM node
    • In addition, the specific contents to be compared can be learned from the flag information.

Static tags are incomplete comparisons, comparing only those variables that are marked, and the number of comparisons is greatly reduced and therefore performance is improved

This reminds me of the tag removal in THE JS garbage collection mechanism. ORZ feels familiar, but the collector is full of tags and only clears tag variables that have left the environment.)

The memory garbage collection mechanism was mentioned in my blog post last year 👉Click on the

Take the following example

    <div>
        <a>Wow ~ potatoes</a>
        <p>Static text</p>
        <p>{{msg}}</p>
    </div>
 //------------ The tag -------------------- can be clearly seen in the compilation below
Copy the code
export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div".null, [
    _createVNode("a".null."Potato wow!"),
    _createVNode("p".null."Static text"),
    _createVNode("p".null, _toDisplayString(_ctx.msg), 1 /* text The text is marked here as 1 */)))}// Compile the url --> https://vue-next-template-explorer.netlify.app/
Copy the code
  • It can be learned from the above:
    • In vue2.0, the DOM tree that is rerendered after data changes is compared node by node with the DOM tree that was rendered last time
    • In DIff of VUe3.0, when creating the virtual DOM, static tags will be added according to whether the DOM will change. When data update needs to generate a new virtual DOM, it will only be compared with the last rendered and marked node.
    • Different types of dynamic changes, in order to facilitate the distinction, the value of the mark is different
    • Therefore, in VUe3.0, the number of comparisons is less, the efficiency is higher, and the speed is faster.

The sample

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div".null, [
    _createVNode("a", { id: _ctx.Poo }, "Potato wow!".8 /* PROPS */["id"]),
    _createVNode("p", { class: _ctx.style }, "Static text".2 /* CLASS */),
    _createVNode("p".null, _toDisplayString(_ctx.msg), 1 /* TEXT */)))}Copy the code

Tag query list

  TEXT = 1.// -- The value is 1-- indicates an element with dynamic textContent
  CLASS = 1 << 1.// -- The value is 2-- indicates that there are dynamic Class elements
  STYLE = 1 << 2.Style ="color: pink" style="color: pink" style="color: pink"
  PROPS = 1 << 3.// -- The value is 8-- indicates an element with a non-class/style dynamic item.
  FULL_PROPS = 1 << 4.// -- the value is 16-- represents the element of an item with a dynamic key, which is opposed to the above three
  HYDRATE_EVENTS = 1 << 5.// -- The value is 32-- represents an element with an event listener
  STABLE_FRAGMENT = 1 << 6.// -- The value is 64-- indicates that the suborder is unchanged and the self-ordered fragments are not changed.
  KEYED_FRAGMENT = 1 << 7.// -- the value is 128-- represents a fragment with keyed or partially keyed children.
  UNKEYED_FRAGMENT = 1 << 8.// -- The value is 256-- child node None Fragment bound to key
  NEED_PATCH = 1 << 9.// -- the value is 512-- means that only elements that are not attribute patches, such as refs or hooks, are required
  DYNAMIC_SLOTS = 1 << 10.// -- The value is 1024-- indicates an element with a dynamic slot
Copy the code
  • Two, hoistStatic static promotion
    • In vue2.0, elements are recreated for rendering when updated, even if they have not changed
    • In Vue3.0, elements that do not participate in updates; Will be static upgrade, only create once the next rendering directly reuse.
    • Therefore, more reuse, fewer creation times, and faster in vue3.0. See the example below:
    <div>
        <a>Wow ~ potatoes</a>
        <p>Static text</p>
        <p>{{msg}}</p>
        <a href='https://vue-next-template-explorer.netlify.app/'>Vue3.0 compilation address</a>
    </div>
Copy the code
    /** * in the bottom compilation (select hoistStatic in options) static promotion, * you can clearly see that the elements not updated are not involved in the reconstruction */
const _hoisted_1 = /*#__PURE__*/_createVNode("a".null."Potato wow!", -1 /* HOISTED */)

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div".null, [
    _hoisted_1,
    _createVNode("p", { style: _ctx.myStyle }, "Static text".4 /* STYLE */),
    _createVNode("p".null, _toDisplayString(_ctx.msg), 1 /* TEXT */),
    _createVNode("a", {
      style: _ctx.myStyle,
      href: "https://vue-next-template-explorer.netlify.app/"
    }, "Vue3.0 compilation address".4 /* STYLE */)))}}Copy the code
  • 3. Cachehandlers event listener cache
    • OnClick is considered dynamic binding by default, so its changes are tracked
    • The function bound to the event is the same, so it is not tracked and cached directly for reuse
    • Again, I’ll show you in the compilation
    <div>
        <button @click='Pooo'>button</button>
    </div>
Copy the code
    /** * Before the event listener cache is enabled: * after the regular compilation, you can see that the static flag is 8 * since there is a static flag, it will compare */
export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div".null, [
    _createVNode("button", { onClick: _ctx.Pooo }, "Button".8 /* PROPS */["onClick"]]))}Copy the code

And then I’m going to turn on the cacheHandlers in options

/** * Can be found when listening cache is turned on, there is no static flag * in diff algorithm, there is no static flag */ will not be compared and tracked
export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div".null, [
    _createVNode("button", {
      onClick: _cache[1] || (_cache[1] = (. args) = >(_ctx.Pooo(... args))) },"Button")))}Copy the code

Quickly create a project using Vite, which vue3.0 provides

  • Vite is a tool developed by the authors of Vue to replace WebPack
  • The idea is to take advantage of ES6’s import send request load file feature, intercept it, and then precompile it, eliminating the tedious packaging of WebPack
  • Using the step
    • To install Vite, run the NPM install -g create-vite-app command
    • Create a Vue3 project: create-vite-app PoooName
    • Install dependencies: CD PoooName/NPM install/NPM run dev
    • Vue3.0 compatible with 2.0 writing, the specific code in this file peer PoooName project file

Reactive in vue3.0

  • For business implementation in 2.0
  • You need to change the supplemental data in data, and then inmethodsorwatchAdds the business logic in the
  • In this way, data and logic are divided into modules, which is inconvenient to find and not conducive to business management and maintenance
  • To solve this problem, Vue3.0 has been addedreactive
  • Vue3.0 provides entry functions to the SETUP composition API to combine data and business logic
import { reactive } from "vue"; Reactive is needed in Vue3.0
export default {
  name: "App".//Vue3.0 provides entry functions for the Setup composition API
  setup() {
    / * * * ref are commonly used to monitor change simple type (can also be used to monitor the complex type change, not to discuss) * usually used to monitor complex type reactive changes (such as array, function, etc.) * the following is a regular writing * /
    let stus = reactive({ stusList: [****its data****], });
    function removeVeget(index) {
      stus.stusList.splice(index, 1);
    }
    return { stus, removeVeget };// Must be exposed before the component can be used
  },
  methods: {}};Copy the code
  • A more elegant way to write it, and a very, very recommended way to write it is
import { reactive } from "vue"; 
export default {
  name: "App".setup() {
    let {stus, removeVeget }=removeItem();// 3
    return { stus, removeVeget };// 4. Expose to external components
  },
  methods: {}};/** * Ensuring that data and business are not scattered is good for update maintenance * it also avoids a lot of data function padding in setup * it is not necessary to use this to point to a Vue instance */
  function removeItem() {
    let stus = reactive({ stusList: [****its data****], });
    function removeVeget(index) {
      stus.stusList.splice(index, 1);
    }
    return {stus,removeVeget} // 2. Expose to composite API usage
  }
Copy the code
  • Functional separation:
    • So at first glance the top is going to integrate the function into the bottom, and then in thesetupThe reference is very concise
    • What if you need more business functions, such as addingupdateItem.addItem
    • Although the data and logic code are still in the same area, all the functions are clustered together and the file is bloated
    • So continue to optimize, separate each function
      1. Create a separate JS file, such as remove.js
      2. Introduce the JS file in the APP file
      3. This allows you to maintain a feature in a separate JS file
import { reactive } from "vue"; // Introduce dependencies
function removeItem() {// Define the function to implement the function
  let stus = reactive({
    stusList: [{id: 1.Name: "potato".price: "2.5" },
      { id: 2.Name: "tomato".price: "3.5" },
      { id: 3.Name: "cucumber".price: "4.5"},]});function removeVeget(index) {
    stus.stusList.splice(index, 1);
  }
  return {stus,removeVeget} 
}
export  {removeItem};// Expose to external use
Copy the code
/* The main file becomes the following (reactive is already in the separate JS file) */
import { removeItem } from "./remove"; // Import the deleted service logic module
export default {
name: "App".setup() {
  let { stus, removeVeget } = removeItem();
  return { stus, removeVeget };
},
methods: {}};Copy the code

Composition API in Vue3.0

  • Option API: Configuration in the APP to implement business logic
    • In 2.0, for example, if you want to implement a button click, pop-up message function, you need
      1. usingOpaction API
      2. indataConfigure data in
      3. inmethodsTo configure the corresponding function
    • Pass the top in 3.0reactiveWe know that to implement this function, you need
      1. usingComposition API
      2. insetupTo define data and write functions
      3. throughReturn {data, method}Exposure to go out
    • Actually,Composition(also known as injection API) is essentially at run time
      1. To inject the exposed data intoopactionIn thedata
      2. Inject the exposed function intoopactionIn themethods

Note: I don’t know exactly how it differentiates data or functions to be injected into the corresponding configuration.

  • Summary:
    • Opaction APIFor example:
      • Configure data in data, write methods in Methods, and listen in Watch.
      • Nanny-style assignments are clear, but they also layer the code and make maintenance a bit of a jump
    • CompositionFor example:
      • Don’t worry about all the “this” points
      • Export modules separately at will, and find fixed module files during maintenance

Setup in the life cycle

The sequence Option type API Hook inside setup
1 beforeCreate Not needed*
2 created Not needed*
3 Composition API onBeforeMount
4 mounted onMounted
5 . .
  • The execution time for setup isbeforeCreateandcreatedBetween, or beforeCreate before?

    Because setup runs around beforeCreate and Created Lifecycle hooks, there is no need to explicitly define them. In other words, any code written in these hooks should be written directly in the setup function.

    • Website address: v3.cn.vuejs.org/guide/compo…
    • According to the official website description and the following 2 and 3 points, setup must be created before
      • There is also a statement before beforeCreate, but I can not understand it very well
      • According to the originalbeforeCreateAny code can be directly insetupIn the writing
      • I prefer a ‘horizontal’ relationship and welcome your help
    • In the Vue lifecycle we know:
      1. beforeCreate When a null has just been initializedVue Instance object,data andmethods Data in theuninitialized
      2. created When executed, data and Methods are alreadyInitialization completed
      3. CompositionThe setup data needs to be injected intodata andmethods in

      4. Obviously setup must be increated Before performing

    • Therefore, if you are doing mixed development in Vue3.0, you cannotsetup The use ofdata Data inmethods The methods in
    • In 3.0,setup “This” has also been changed toundefiend
    • In 3.0,setup You can’t use asynchrony
    • (I have added a sidebar to the image below to help you recall the life cycle.)

What is a reactive

  • reactiveisVUE3.0Provides a way to implement responsive data
  • In Vue2.0, it isdefinePropertyTo achieve (I also manually implemented 👉Click on the)
  • whileVUE3.0ES6 is used in ES6proxyImplementation of the
  • reactivePoints to note in:
    • The type passed to it must be an object (JSON or arR array)
    • And it will automatically reassign the condition passed in toProxyobject
    • If the object passed is not the above
      1. You modify it directly in the method, and it doesn’t update automatically on the interface
      2. If you want to update, you can only do it by reassigning
  /* The following example is */
  setup() {
    let testJson=reactive({
      tip:'its a Json! '
    })
    let testArray=reactive(['first'.'second'.'third'])
    let testString=reactive('Just a string')
    function showProxyPar(){
      testJson.tip='changed';
      testArray[2] ='selected';
      testString='hengxipeng';
      console.log(testJson);// Proxy {tip: "changed"}
      console.log(testArray);// Proxy {0: "first", 1: "second", 2: "selected"}
      console.log(testString);// hengxipeng
    }
    return { testJson,testArray,testString,showProxyPar };
  },
Copy the code
  • The effect is as shown in the figure below, with parameters that fit the passing criteria being assigned to the Proxy, and modifying it directly affecting the view

What is the ref

  • It’s also a way to implement responsive data
  • reactivceYou are always passing objects, and in real development you would be overqualified if you only wanted to change a simple variable
  • So vue3 provides the ref method to listen for simple values
  • refThe essence is also usereactiveTo giverefThe value of which is automatically converted
  Reactive ({value:'its a string'}) ==>reactive({value:'its a string'}) Vue will automatically add) */
  setup() {
    let testRef = ref('its a string');
    function showProxyPar() {
      testRef.value='ref_string'
      console.log(testRef);
    }
    return { testRef, showProxyPar };
  },
Copy the code
  • The following figure

The difference between ref and reactive

  • Through the above, userefIt’s equivalent to usingreactive, except that the step of manually creating the object is omitted
  • refThe middle layer will add onevalueAnd the call can be omitted from the viewvalue
    • I tested it myself
      1. usereactive, create a key value ofvaluetheJsonObject to verify that it can be omittedvalueCall (Can not be)
      2. Learned that only userefThe view is allowed to omit only when the parameter is passedvaluecall
/** * Vue will automatically add value to the current argument */ __v_isRef: true _rawValue: "its a string" _shallow: false _value: "its a string" value: "its a string"Copy the code
  • Vue3.0 provides two methods,isReactiveandisRefUsed to determine the source of data
import {isRef,isReactive } from "vue";
  setup() {
    let testReactive = reactive({value:'its a string'});
    let testRef = ref('its a string');
    function showProxyPar() {
      console.log('Check for Ref',isRef(testReactive));// false
      console.log('Check for Ref',isRef(testRef));// true
    }
    return { testRef,testReactive, showProxyPar };
  }
Copy the code

Recursive listening

  • In generalrefandreactiveWill listen for data changes

Verify that clicking the button to trigger recursion changes the page display

Parse.value. Type ='fruit'; parse.value.
  setup() {
    let parse = reactive({
      type: "vegetables".suchAS: {
        name: "tomato".info: {
          price: "0.4 yuan/kg".size: {
            big: "50g".small: "20g",},},},});function recursion() {
      parse.type='fruit';
      parse.suchAS.name='cucumber';
      parse.suchAS.info.price='0.8 yuan/kg;
      parse.suchAS.info.size.small='70g'; 
      parse.suchAS.info.size.big='90g';
    }
    return { parse,recursion };
  },
Copy the code
  • A large amount of data consumes performance
    • In the previous <What is thereactive> < p style = “text-align: center;
      • reactiveandrefBy recursively fetching all the values in the parameter, wrapped asproxyobject
      • I have summarized the pros and cons of recursion, including pressing and pop-ups, and strongly recommend a review of 👉

Non-recursive listening

  • The disadvantages of recursive listening are known above, andVue3.0Solutions are also provided
    • Non-recursive listening: only the first level of data can be listened on. The scheme is as follows:
      1. The introduction ofVue3.0Provided in theshallowReactive
      2. To switch toshallowReactive({})Passing parameters
      3. It was observed that only the first layer of the console was convertedproxyobject

    • And forrefThe correspondingshallowRefNon-recursive listening is special
      1. First try to introduceVue3.0In the officialshallowRef
      2. In principle andreactiveSame thing, except it doesn’t listenJSONLayer 1 data
      3. You have to change it directlyvalueSo that the view is updated synchronously
    function recursion() {
      /** * shallowRef will not listen for layer 1 changes, so views will not */
      parse.value.type='fruit';
      parse.value.suchAS.name='cucumber';
      parse.value.suchAS.info.price='0.8 yuan/kg;
      parse.value.suchAS.info.size.small='70g'; 
      parse.value.suchAS.info.size.big='90g';
      /** * The correct way to do this is to change the whole value */
        parse.value = {
        type: "fruit".suchAS: {
          name: "cucumber".info: {
            price: "0.8 yuan/kg".size: {
              big: "70g".small: "90g",,}}}}; }Copy the code

Note: although they are only listening on the first layer, if they happen to change the first layer every time, the data below will be updated synchronously with the view. In this case, shallowReactive or shallowRef will have the same effect as reactive or Ref!

Data monitoring supplement

  • From the above knowledge points, we can know:
    • refandreactiveListen for each layer of data, good response but poor recursive value performance.
    • shallowReactiveandshallowRefListening for the first layer (or value) performs well but updating values is cumbersome
    • shallowRefIn order for the data to be consistent with the view, the updated value is updated as a wholeparse.valueToo complicated
    • Scenario: If I update the third layer of data, not the entire updatevalueLine not line?
      1. That’s where it comes inVue3.0forrefTo prepare thetriggerRef(No need to check, just one)
      2. Function: Proactively updates views based on incoming data
        • As usual,import {shallowRef, triggerRef } from "vue"
        • Change the data that’s not in the first layer, and you’re usingshallowRefDon’t want to update the whole thing yetvalue
        • usetriggerRefDafa, pass in the whole object, and there you go
        • (using thereactiveIncoming data, unable to triggertriggerRef)
    function recursion() {
      Parse. value = {type: "fruit", suchAS: {name: "cucumber", info: {price: "0.8 yuan /kg", size: {big: "70g", small: "90g", },},},}; * /
      TriggerRef */
      parse.value.suchAS.info.price='0.8 yuan/kg;
      triggerRef(parse)
    }
Copy the code

Select a data listening mode

  • Usually used for normal data volumerefandreactive(recursive listening) can satisfy the business needs
  • When the data volume is large and performance is important, considershallowReactiveandshallowRef(non-recursive listening)

shallowRefThe underlying principle

  • Looking at therefWe know that the essence of it isreactive({value:XX})
  • thenshallowRefIs actuallyshallowReactive({value:XX})
    • Because byshallowRefThe data that was created, it was listening to.valueThe change of the
  let state1=shallowRef({
    a:'a'.b: {b_1:'b_1'.b_2:'b_2'}})//-- The following is true
  let state2=shallowReactive({
    value: {a:'a'.b: {b_1:'b_1'.b_2:'b_2'}}})Copy the code

toRaw

  • We know from the previous body of knowledge
    • setupIf you modify the page in the function, it will not be updated synchronously.
    • Need to useReforreactiveSo that the change takes effect
    let obj={ name:'flower'.age:'3'}
    let test=reactive(obj);
    function myFun() {test.name='dudu'; }Copy the code
    • obj å’Œ testYes reference
    • reactiveWill wrap the arguments passed in as oneporxyObject and return
    • In the exampletestThe essence is aporxyObject, and this object also refers toobj
      • Then please note:
        • Directly modifyingobjOr referencetestWill cause changes in the data in memory
        • But changeobjBecause there is noproxyListen, so the view doesn’t update
  • Say so much, then circle back to saytoRaw
    • Function: Returns the function ofreactive 或 readonlyTo a generic object for a responsive proxy
    • Features:toRawThe obtained data will not be monitored for changes, saving performance
    • Scenario: Data changes do not need to update the view. To improve performance, passtoRawGet data modification
    • Tip: It is not recommended to use because it is raw data with high risk.
    • Note: If you want to getRefThe object that you created, remember to addvalue
      let obj={
        name:'flower'.age:'3'
      }
      let testReactive=reactive(obj);
      let testRef=ref(obj);
      let rawReac=toRaw(testReactive);
      let rawRef=toRaw(testRef.value);
      console.log(rawReac===obj); //true
      console.log(rawRef===obj); //true
Copy the code

markRaw

  • We know from the previous body of knowledge
  • Function: Fixes data without tracking changes in its value, and views are not updated
  • View and use through the consolemarkRawThe object parameter is given tov_skipListen for skip identifiers
   let obj={
       name:'poo'.age:'3'
   }
   console.log(obj);//{name: "poo", age: "3"}
    obj=markRaw(obj)// Make the value change not heard, and the view does not change

   let testReactive=reactive(obj);
   function myFun() {
     testReactive.name='sweet potato';
     console.log(obj);//{name: "", age: "3", __v_skip: true}
   }
Copy the code

toRef

  • toRefandrefAgain, reactive data is created
  • First the conclusion:
    • refTo change a property of an object to responsive, the original data is not affected
    • toRefIt changes the original data
    • andtoRefThe interface does not automatically update the created data when it changes
  • Application scenario: Performance optimization
    • You want to create responsive data associated with metadata
    • After updating responsive data, you do not want to update the UI
  setup() {
      /** * toRef */
      let obj={ name:'poo' }
      let obj2={name:'boo'}
      // obj = obj; // obj = obj; // obj = obj
    let test_toRef=toRef(obj,'name');
    let test_ref=ref(obj2.name);
    console.log(test_toRef);
    function myFun() {
      test_toRef.value="Potato";
      test_ref.value='sweet potato';
      console.log(obj,);// {name: "potato "}
      console.log(obj2);// {name: "boo"}
    }
    return {obj,obj2, myFun };
  }
Copy the code

toRefs

  • toRefYou can only accept two parameters, which can be cumbersome when passing multiple property values for an object
  • Conclusion:
    • toRefsIs to avoidtoRefOperations on multiple attributes are cumbersome
    • toRefsThe underlying principle is to usetoRefMethod to iterate over object property values
  setup() {
      let obj={
        name:'poo'.age:'3'
      }
    let test_toRefs=toRefs(obj);
    * let par1=toRef(obj,'name') * let par2=toRef(obj,'age') */
    function myFun() {
      test_toRefs.name.value='HAHA';
      test_toRefs.age.value='13';
    }
    return {test_toRefs, myFun };
  }
Copy the code

How do I get elements from ref in VU 3.0?

  • In Vue2.0, it is commonly usedthis.$refs.XXAccess to elements
  • In Vue3.0, similar was abolished$How to get the specified element?
  • According to the Vue lifecycle diagram, to operate the DOM, at the earliestmountedIn the
  • Conclusion:
    • 1.setupIs in thebeforeCreateBefore performing
    • 2. In the lifecycleonMountedGet ready firstDOMThe element
    • 3.setupTo manipulateDOMJust refer to it in the functiononMounted
    • 4.Vue3.0The life cycle function is removed and the corresponding periodic function can be introduced according to the need
  setup() {
    let btn=ref(null);
    console.log(btn.value);
    // The callback function is executed in the Vue lifecycle order regardless of its order in the function
    onMounted(() = >{
      console.log(btn.value);//- 
    })
    return {btn};
  },
Copy the code

readonly

  • This API, provided in Vue3.0, makes the data protected, read-only and unmodifiable
  • By default, data at all layers is read-only. If only the first layer is read-only, use this commandshallowReadonly
  • isReadonlyUsed to check whether the data was created fromreadonly
  • If you modify the password, the browser displays a message indicating that the operation fails and the target is read-only
  setup() {
    let obj={
      name:'poo'.age:'13'
    }
    let only=readonly(obj)
    function myFun() {
      only.name='HAHA';// failed: target is readonly
    }
    return {only, myFun };
  }
Copy the code

Vue3.0 Responsive data nature

  • Used in 2.0Object.definePropertyImplement responsive data
  • Used in 3.0ProxyTo implement, as follows
    let obj={
      name:'poo'.age:'13'
    }
    let objProxy=new Proxy(obj,{
      // Data reads are triggered
      get(obj,key){
        console.log(obj);//{name: "poo", age: "13"}
        return obj[key]
      },
      // Triggered when the listening data is modified
      set(obj,key,value){
      // The object of the operation, the properties of the operation, and the new value assigned to it
      obj[key]=value // Update the object with a new value from the outside
      console.log('Do things like UI.');
      // return true if you want to do this again
      return true;
      }
    })
   objProxy.name;
Copy the code

Implement shallowReactive and shallowRef

  • Both of them are also passed as arguments, wrapped inproxyObject to listen on
  • inProxy çš„ setListen, again, only listen on the first layer
  • shallowRefOnly in theshallowReactiveIs added by defaultvalueKey name
function shallowReactive(obj){
  return new Proxy(obj,{
    get(obj,key){
      return obj[key]
    },
    set(obj,key,value){
      obj[key]=value
      console.log('update');
      return true; }})}let obj={
  A:'A'.B: {b1:'b1'.b2:'b2'.b3: {b3_1:'b3-1'.b3_2:'b3-2'}}}let test=shallowReactive(obj)
//- Only the first layer will be monitored
test.A='apple';
test.B.b2='banana';
function shallowRef(obj){
  return shallowReactive(obj,{value:vl})
}
let state=shallowRef(obj);
Copy the code

Implement reactive and REF

  • The difference between them and the above is recursive listening
  • The upper layer only listens for the first layer because the argument object is passed directly
  • To recursively listen, wrap each layer of data asProxyobject
function reactive(obj) {
  if (typeof obj === "object") {
    if (obj instanceof Array) {
      // If the current argument is an array type, loop out each item
      obj.forEach((item, index) = > {
        if (typeof item === "object") {
          // Parse each item in the array, recursively if it is an objectobj[index] = reactive(item); }}); }else {
      // If the current parameter is an object and not an array, take the attribute value and analyze whether it is a multi-layer object
      for (let key in obj) {
        if (typeof obj[key] === "object") { obj[key] = reactive(item); }}}}else {
    console.log("Currently passed as a non-object parameter");
  }
  //- The Proxy object is normally wrapped
  return new Proxy(obj, {
    get(obj, key) {
      return obj[key];
    },
    set(obj, key, value) {
      obj[key] = value;
      console.log("Update");
      return true; }}); }Copy the code

Implement shallowReadonly and readonly

  • The only difference between the two is that the first layer listens, read-only rejects modification and data full layer modification
  • So what I’m going to do down here isshallowReadonly
  • readonlyImplementation is inshallowReadonlyBase removalsetIn thereturn true
function shallowReadonly(obj) {
  return new Proxy(obj, {
    get(obj, key) {
      return obj[key];
    },
    set(obj, key, value) {
      // obj[key] = value;
      console.error(`${key}Is read-only and cannot be modified - ');
      return true;// If this row is removed, readonly indicates that full-layer data is read-only}}); }let parse = {
  type: "fruit".suchAS: {
    name: "cucumber",}};let fakeShowRe=shallowReadonly(parse);
fakeShowRe.type='HAHA';// The changes will not take effect
fakeShowRe.suchAS.name='HAHA';// Non-first layer changes will take effect
Copy the code

END

You may also be interested in the following

  • JavaScript reads local file configuration (compatible with lower IE versions)
  • # What do you ask about the front end of one year’s work experience?
  • # JavaScript Language Essence
  • # Diagram HTTP series

Feel content is ok, might as well give encouragement, thank you ~~