About the Vue 3.0

Cooperate with li nan Vue3.0 learning effect is better Video address: ` ` www.bilibili.com/video/BV14k…

Preface:

  • The official version:VueThe team released the official version 3.0 on 2020.09.18
  • Prerequisites:VueAlthough a large number of 2.0 versions remainapiBut as is usedTypeScriptRefactoring, so if you want to learn 3.0, you need to master itTSBasic use of

Six highlights in Vue3.0

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

What optimization is Vue3.0 based on, 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 flags (PatchFlag)
    • After data changes, only nodes with PatchFlag are compared with the last virtual DOM node
    • In addition, you can know the specific content to be compared from the Flag information.

Static markup is a quantity, all will be only those marked variables, is greatly reduced the number of thus improving performance It made me think of JS tag removal in the garbage collection mechanism, ORZ feel familiar, but recycling machine is just remove has left environment tag variables) memory garbage collection mechanism πŸ‘‰ click in my blog last year

Take this example

The < div > < a > potato wow ~ < / a > < p > static text < / p > < p > {{MSG}} < / p > < / div >Copy the code
export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div".null, [
    _createVNode("a".null."Potatoes!"),
    _createVNode("p".null."Static text"),
    _createVNode("p".null, _toDisplayString(_ctx.msg), 1 /* text The text is marked here as 1 */)))}Copy the code

The sample

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

ζ”―ι‚£

Tagged query list

ζ”―ι‚£

TEXT = 1.// -- the value is 1-- represents an element with a dynamic textContent
  CLASS = 1 << 1.// -- the value is 2-- indicates the element with dynamic Class
  STYLE = 1 << 2.Style ="color: pink"; color: pink;
  PROPS = 1 << 3.// -- the value is 8-- represents the element with non-class/style dynamic items.
  FULL_PROPS = 1 << 4.// -- the value is 16-- represents the element of the item with the dynamic key, which is incompatible with the above three types
  HYDRATE_EVENTS = 1 << 5.// -- the value is 32-- represents the element with an event listener
  STABLE_FRAGMENT = 1 << 6.// -- the value is 64-- indicates that the order of the child is unchanged.
  KEYED_FRAGMENT = 1 << 7.// -- 128-- represents a fragment with keyed or partially keyed child elements.
  UNKEYED_FRAGMENT = 1 << 8.// -- The value is 256-- Fragment without key binding
  NEED_PATCH = 1 << 9.// -- the value is 512-- only elements that are not attribute patched, such as ref or hooks, are required
  DYNAMIC_SLOTS = 1 << 10.// -- the value is 1024-- indicates an element with a dynamic slot
Copy the code
  • 2. hoistStatic static promotion
    • In Vue2.0, when updated, elements are recreated for rendering even if they remain unchanged
    • In VUe3.0, elements that do not participate in updates; Will static promotion, only create once the next rendering directly reuse.
    • As a result, vue3.0 has more reuse, fewer creation times, and faster speeds. 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
/** * Static promotion is performed in the following compilation (check hoistStatic in options), * you can clearly see that no updated elements participate in the re-creation */
const _hoisted_1 = /*#__PURE__*/_createVNode("a".null."Potatoes!", -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 compiler address".4 /* STYLE */)))}}Copy the code
  • The CacheHandlers event listens to the cache
    • OnClick is treated as dynamically bound by default, so changes are tracked
    • The function bound to the event is the same, so it does not track its changes and is directly cached and reused
    • Again, I demonstrate this in compilation
<div>
  <button @click='Pooo'>button</button>
</div>
Copy the code
/** * before the event listening cache is enabled: * After 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 cacheHandlers in options

ζ”―ι‚£

/** * You can see that when listening cache is turned on, there is no static flag ** In diff, there is no static flag */ that does not compare and trace
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 codeCopy the code

ζ”―ι‚£

Quickly create projects using Vite provided with VUe3.0

  • Vite is a tool developed by Vue authors to replace WebPack
  • The idea is to use ES6’s import feature to send requests to load files, intercept them, and then precompile them without the tedious packaging of WebPack
  • Using the step
    • Install Vite command:npm install -g create-vite-app
    • Creating a Vue3 project: create-vite-app PoooName
    • Install dependencies:cd PoooName / npm install / npm run dev
    • Vue3.0 is compatible with the 2.0 writing method. The code is in the PoooName project file of the same class as this file

ζ”―ι‚£

Usage of Reactive in VUe3.0

  • For business implementation in 2.0
  • You need to change the supplementary data in data first, and then inmethodsorwatchTo supplement the business logic
  • In this way, data and logic are divided into modules, which is inconvenient to search and is not conducive to service 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 with business logic
import { reactive } from "vue"; Reactive is required for Vue3.0
export default {
  name: "App".Vue3.0 provides entry functions to the Setup composite API
  setup() {
    /** * ref is usually used to listen for simple type changes (and can be used to listen for complex type changes, but not discussed) * reactive is usually used to listen for complex type changes (such as arrays, functions, etc.) */
    let stus = reactive({ stusList: [****its data****], });
    function removeVeget(index) {
      stus.stusList.splice(index, 1);
    }
    return { stus, removeVeget };// Must be exposed to the component before it can be used
  },
  methods: {}};Copy the code
  • Another more elegant way to write it, which is really, really recommended, is to write it
import { reactive } from "vue"; 
export default {
  name: "App".setup() {
    let {stus, removeVeget }=removeItem();// make a direct declaration
    return { stus, removeVeget };// Open to external components
  },
  methods: {}};/** * Keep the data and business not scattered to facilitate update maintenance ** also avoids the large number of data function padding in setup * and does not need to use this to point to Vue instances */
  function removeItem() {
    let stus = reactive({ stusList: [****its data****], });
    function removeVeget(index) {
      stus.stusList.splice(index, 1);
    }
    return {stus,removeVeget} // Use the composite API
  }

Copy the code
  • Functional separation:
    • At first glance the top integrates the function to the bottom, and then insetupThe reference is succinct
    • What if you need more business functions, like adding aupdateItem.addItem
    • Although the data and logical code are still in one place, the clustering of various functions is still a bloated file
    • Then continue to optimize and separate functionality
      1. Create a separate JS file, such as remove.js
      2. Import the JS file in the APP file
      3. This allows you to maintain a function 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
/* Then the main file becomes the following form (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 codeCopy the code

ζ”―ι‚£

Composition API nature 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, you need to
      1. usingOpaction API
      2. indataConfiguration data in
      3. inmethodsTo configure the corresponding function
    • In 3.0 through the topreactiveWe know that to implement this feature, you need 4Composition APIIn 4.setupDefine data, write function 4. PassReturn {data, method}Exposure to go out
    • Actually,Composition(also called the injection API) essentially injects exposed data into theopactionIn thedata7. Inject exposed functions intoopactionIn themethods

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

  • Summary:
    • Opaction APIFor example:
      • Configure data in data, write methods in methods, and monitor in watch.
      • Nanny-style allocation is clearer, but also layers of code, maintenance takes a long time to jump
    • CompositionMore freedom, such as:
      • Don’t worry about all the “this” references
      • Random module segmentation export, maintenance to find fixed module files

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 . .
  • Setup is executed whenbeforeCreateandcreatedBetween, or before beforeCreate?

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…
  • Setup must precede Creation based on the description on the website and points 2 or 3 below
    • There is also a saying that is before beforeCreate, but I can not understand
    • According to the originalbeforeCreateAny code in thesetupIn the writing
    • I prefer the relationship between the two is’ equal ‘, also welcome to help answer
  • In the Vue lifecycle we know:
    1. beforeCreate A null has just been initializedVue Instance object,data andmethods Data in theuninitialized
    2. created When executed, data and methods are alreadyInitialization complete
    3. CompositionThe data in setup 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 The sum of data inmethods The methods in
  • In 3.0,setup “This” has also been modified toundefiend
  • In 3.0,setup You can’t use asynchrony in
  • (I have also added a sidebar to the picture posted below to help you recall the life cycle.)

ζ”―ι‚£

What is a reactive

  • reactiveisVUE3.0Provides methods for implementing reactive data in
  • It is used in Vue2.0definePropertyTo implement (I myself have manually implemented πŸ‘‰Click on the)
  • whileVUE3.0Is used in ES6proxyImplementation of the
  • reactivePoints to note in:
    • The type passed to it must be an object (JSON or ARR array)
    • And it automatically assigns the condition passed in toProxyobject
    • If an object other than the above is passed
      1. Modify it directly in the method, and it doesn’t update automatically in the interface
      2. Updates can only be made by reassigning
/* An example of this 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
  • As shown in the following figure, parameters that match the pass criteria are reassigned to the Proxy, and modifying it directly affects the view

What is the ref

  • It is also a way to implement responsive data
  • reactivcePassing objects has always been the way to go, and changing a simple variable is overkill in real development
  • So VUe3 provides the ref method to listen on simple values
  • refThe essence is to usereactiveTo giverefValue of, which is automatically converted at the bottom
/ reactive({value:'its a string')==>reactive({value:'its a string'}) Vue automatically adds) */
  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

  • Known through the above, userefIt’s actually usingreactive, only omitting the manual object creation step
  • refThe middle and bottom will add onevalueKey, and the call can be omitted in the viewvalue
    • I tested it myself
      1. usereactive, create a key value ofvaluetheJsonObject that verifies whether it can be omittedvalueCall (Can not be)
      2. Learned that only userefViews are allowed to be omitted only when arguments are passedvaluecall
/** * Vue will automatically add value */ to the current argument when calling __v_isRef
      __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,isReactiveandisRefTo determine the source of the 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 if it is Ref',isRef(testReactive));// false
      console.log('Check if it is Ref',isRef(testRef));// true
    }
    return { testRef,testReactive, showProxyPar };
  }
Copy the code

ζ”―ι‚£

Recursive listening

  • In generalrefandreactiveAll listen for data changes

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

Parse.value. type='fruit';
  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
  • Large data volumes can be very performance consuming
    • In the previous <What is thereactive> we know:
      • reactiveandrefBy recursively fetching all the values in the parameters, wrapped asproxyobject
      • I have summarized the advantages and disadvantages of recursion, which involves pushing and popping, etc., and I strongly recommend reviewing πŸ‘‰ click

ζ”―ι‚£

Non-recursive listening

  • They know all the disadvantages of recursive listening, andVue3.0It also offers solutions
    • Non-recursive listening: only the first layer 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. Observation shows that only the first layer of the console is convertedproxyobject
    • And forrefThe correspondingshallowRefNon-recursive listening is special. 4. Try to introduce firstVue3.0Provided by the Chinese governmentshallowRef4. In principlereactiveSame thing, except it doesn’t listenJSONThe first layer of data 4. But to modify directlyvalueSo that the view is updated synchronously
function recursion() {
  /** * shallowRef does not listen for layer 1 changes, so the view remains the same */
  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 is to modify the entire value */
    parse.value = {
    type: "fruit".suchAS: {
      name: "cucumber".info: {
        price: "0.8 yuan/kg".size: {
          big: "70g".small: "90g",,}}}}; }Copy the code

Note: shallowReactive or shallowRef has the same effect as reactive and Ref, although they are only listening on the first layer. If they happen to change the data on the first layer each time, shallowReactive and shallowRef will also be synchronized to the view below.

ζ”―ι‚£

Data monitoring supplement

  • From the above knowledge points, we can know:
    • refandreactiveMonitoring each layer of data, good response but poor recursive value performance.
    • shallowReactiveandshallowRefListen on the first layer (or value), which performs well but is more cumbersome to update the value
    • shallowRefTo keep the data consistent with the view, update the value to update the wholeparse.valueToo complicated
    • Scenario: If I update the third layer of data, not the whole onevalueLine not line?
      1. That’s itVue3.0forrefTo prepare thetriggerRef(No need to check just one)
      2. Action: Actively updates views based on incoming data
        • As usual,import {shallowRef, triggerRef } from "vue"
        • Change the data that is not the first layer, and you are usingshallowRefDon’t want to update the whole thing yetvalue
        • usetriggerRefBig method, pass in the whole object, and you’re done
        • (using thereactiveIncoming data cannot be firedtriggerRef)
function recursion() {
      Value = {type: "fruit", suchAS: {name: "cucumber", info: {price: "0.8ε…ƒ/kg", size: {big: "70g", small: "90g", },},},}; * /
      /** * triggerRef */
      parse.value.suchAS.info.price='0.8 yuan/kg;
      triggerRef(parse)
    }
Copy the code

Select data monitoring mode

  • This parameter is used when the data volume is normalrefandreactive(Recursive listening) can meet business needs
  • Consider this when there is a large amount of data and performance is importantshallowReactiveandshallowRef(non-recursive listening)

ShallowRef underlying principle **

  • Looking at therefWe know what it isreactive({value:XX})
  • thenshallowRefIs actuallyshallowReactive({value:XX})
    • Because byshallowRefThe data that was created, and it’s listening for.valueThe change of the
let state1=shallowRef({
    a:'a'.b: {b_1:'b_1'.b_2:'b_2'}})//-- actually, it looks like this
  let state2=shallowReactive({
    value: {a:'a'.b: {b_1:'b_1'.b_2:'b_2'}}})Copy the code

ζ”―ι‚£

toRaw

  • We know from the previous system of knowledge
    • setupTo define the parameter object, in the function directly modify the page is not synchronous update.
    • Need to useReforreactiveWrap it so that the modification takes effect
let obj={ name:'flower'.age:'3'}
let test=reactive(obj);
function myFun() {test.name='dudu'; }Copy the code
  • obj ε’Œ testIt’s a reference relationship
  • reactiveWraps the parameter passed in as a single parameterporxyObject and return
  • In the exampletestIs essentially aporxyObject, which is also referencedobj
    • Then please note:
      • Directly modifyingobjOr referencetestAll cause data in memory to change
      • But changeobjBecause there is noproxyListen, so the view doesn’t update
  • After all that, come back to metoRaw
    • Function: Returns the value ofreactive ζˆ– readonlyAnd other methods are converted into ordinary objects for reactive proxies
    • Features:toRawThe data obtained will not be monitored to change, saving performance
    • Scenario: Data changes do not need to update the view. To improve performance, passtoRawGet data to modify
    • Note: It is generally not recommended to use, because it is raw data and has high risk.
    • Note: if you want to get isRefCreate the object, 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 system of knowledge
  • What it does: Fixes data, does not track changes in its value, and the view does not update
  • View through the console, usingmarkRawThe object argument is givenv_skipListen to skip identifiers
let obj={
       name:'poo'.age:'3'
   }
   console.log(obj);//{name: "poo", age: "3"}
    obj=markRaw(obj)// So that its value changes, not listening, the view does not change
   let testReactive=reactive(obj);
   function myFun() {
     testReactive.name='sweet potato';
     console.log(obj);//{name: "sweet potato ", age: "3", __v_skip: true}
   }
Copy the code

ζ”―ι‚£

toRef

  • toRefandrefAgain, reactive data is created
  • First the conclusion:
    • refTo change an attribute 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 associate the metadata with the reactive data you create
    • After updating reactive data, you don’t want to update the UI
setup() {
      /** * toRef */
      let obj={ name:'poo' }
      let obj2={name:'boo'}
      //- toRef = 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

  • toRefOnly two parameters can be accepted, which can be cumbersome when passing multiple attribute values for an object
  • Conclusion:
    • toRefsIs to avoidtoRefManipulating multiple attributes is cumbersome
    • toRefsThe underlying principle is 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 by ref in Vue3.0?

  • In Vue2.0, it is commonly usedthis.$refs.XXAccess to elements
  • In Vue3.0, the analogy was abolished$How do I get the specified element?
  • As you can see from the Vue lifecycle diagram, the earliest you can manipulate the DOM is inmountedIn the
  • Conclusion:
    • 1.setupIs in thebeforeCreateBefore performing
    • 2. In the life cycleonMountedBe ready firstDOMThe element
    • 3.setupTo manipulateDOMJust reference it in the functiononMounted
    • 4.Vue3.0Life cycle function is extracted from, and corresponding cycle function can be introduced according to needs
setup() {
  let btn=ref(null);
  console.log(btn.value);
  // Callback functions are executed in Vue lifecycle order regardless of their order in the function
  onMounted(() = >{
    console.log(btn.value);//- 
  })
  return {btn};
},
Copy the code

ζ”―ι‚£

readonly

  • This API, provided in Vue3.0, makes data protected, read-only and unmodifiable
  • By default, all layers are read-only. If only layer 1 is read-only, this parameter is availableshallowReadonly
  • isReadonlyUsed to check whether the data creation source isreadonly
  • If you modify it, 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

ζ”―ι‚£

The responsive data nature of Vue3.0

  • 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 listening data is modified
    set(obj,key,value){
    // The object of the operation, the property of the operation, the new value assigned
    obj[key]=value // Update the object with the new value assigned by the outside world
    console.log('Do things like UI.');
    //- Returns true to ensure that the next operation is not affected
    return true;
    }
  })
 objProxy.name;
Copy the code

ζ”―ι‚£

Implement shallowReactive and shallowRef

  • Both of them are also wrapped by parameter passingproxyObject to listen
  • inProxy ηš„ setIn the listener, again only the first layer is listened on
  • shallowRefOnly in theshallowReactiveBased on the 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 layer 1 will be listened on
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

  • They differ from the above in recursive listening
  • Because the parameter object is passed directly above, only the first layer is listened on
  • To recursively listen, wrap each layer of data intoProxyobject
function reactive(obj) {
  if (typeof obj === "object") {
    if (obj instanceof Array) {
      // If the current parameter is an array type, loop through each item
      obj.forEach((item, index) = > {
        if (typeof item === "object") {
          // Parses each item of the arrayobj[index] = reactive(item); }}); }else {
      // The current argument is an object, not an array
      for (let key in obj) {
        if (typeof obj[key] === "object") { obj[key] = reactive(item); }}}}else {
    console.log("Currently passed as a non-object parameter");
  }
  //- Proxy object wrapping is normal
  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 the first layer listening, read-only reject modification and data full layer modification
  • The bottom implementation 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 line is removed, it is readonly}}); }let parse = {
  type: "fruit".suchAS: {
    name: "cucumber",}};let fakeShowRe=shallowReadonly(parse);
fakeShowRe.type='HAHA';// The change does not take effect
fakeShowRe.suchAS.name='HAHA';// Non-level changes will take effect
Copy the code