Location>code7788 >text

This should be the most detailed explanation of Vue 3.5 on the net!

Popularity:124 ℃/2024-09-05 09:52:04

preamble

Vue3.5 official versionReleased in the past two days, there have been quite a few articles on the Internet about the interpretation of the Vue 3.5 version. But Ouyang found that all these articles introduce the new features added in 3.5It's not very complete.So it causes a lot of students to have amisperception, felt that Vue 3.5 version is nothing more than that, and chose to skip this version to wait for the next big version to update. So Ouyang wrote thisSuper DetailedThe Vue 3.5 release explains the article, you can see whether there are some features you are looking forward to added in the 3.5 version.

Follow the public number: [Front-end Ouyang], give yourself a chance to advance vue

version number

This time the version number isTian Yuan Breakthrough Red Lotus Screw Rock, which is a secondary anime that came out in '07 that Ouyang has never seen. Until then I had assumed that the version number for this one would be calledBlack Myth: Goku, maybe Goku isn't secondary enough.

responsive

Responsive-related content is divided into: refactoring responsive, responsive props support deconstruction, adding newonEffectCleanupfunctions, newbase watchfunctions, newonWatcherCleanupfunctions, newpausecap (a poem)resumeMethods.

Refactoring Responsive

This responsive refactoring is an internal optimization of Vue, which is senseless for ordinary developers. The refactoring reduces the memory footprint by 56%, and the optimizations are mainly done through theversion countcap (a poem)bidirectional linked list data structureInspired byPreact signalsThe first is a series of articles about responsive source code, which will be published in a series of articles. Followed by Ouyang will come out with a series of articles about responsive related source code, you can pay attention to a wave of Ouyang.

Responsive props support deconstruction

In 3.5 responsive props support for deconstruction has finally been officially stabilized, before this feature we had to write this if we wanted to access props in js:or elsenameResponsive will be lost.

With responsive props deconstruction, in js we can directly deconstruct thenameto use, such as the following code:

<script setup lang="ts">
const { name } = defineProps({
  name: String,
});

(name);
</script>

(coll.) fail (a student)definePropsWhen used together with deconstruction, it is possible to compile thenameprocess sth.. The simplified code after compilation is as follows:

setup(__props) {
  (__props.name);
  const __returned__ = {};
  return __returned__;
}

As you can see from the code above(name)After compilation it becomes(__props.name)After this treatment.nameOf course there would be no loss of responsiveness.

Add onEffectCleanup function.

Before the component is uninstalled or the nextwatchEffectThe callback is automatically called before it executes theonEffectCleanupfunction, with this function you don't need to add the component'sbeforeUnmountThe hook function goes and cleans up some timers in a uniform way. For example, the following scenario:

import { watchEffect, ref } from "vue";
import { onEffectCleanup } from "@vue/reactivity";

const flag = ref(true);
watchEffect(() => {
  if () {
    const timer = setInterval(() => {
      // Do something.
      ("do something");
    }, 200);
    onEffectCleanup(() => {
      clearInterval(timer);
    });
  }
});

The above example is in thewatchEffectwill go ahead and register a timer for a recurring call if you don't use theonEffectCleanupThen we'll need to add thebeforeUnmounthook function to clean up the timer.

But withonEffectCleanupafter thatclearIntervalJust put it in his callback. When the component is uninstalled it automatically executes theonEffectCleanupThe incoming callback function, that is, the callback function that will execute theclearIntervalClears the timer.

Another point worth noting is thatonEffectCleanupfunction is not currently available in thevuepackage is exposed, if you want to use it you can do as I did from the@vue/reactivityImported in the packageonEffectCleanupfunction.

New base watch function

We previously used thewatchfunctions are implemented with Vue components and lifecycles, they are deeply bound, so thewatchThe location of the function code is in the vue source code in theruntime-corein the module.

But there are scenarios where we only want to use vue's responsive functionality, namely the vue source code'sreactivityModules, such as appletsvuemini. For this reason we had to putruntime-coremodules are also imported into the project, or like thevueminiSame goes for handwriting a watch function.

In version 3.5 a refactoring of thebase watchfunction, the implementation of which has nothing to do with the vue component, so he's in thereactivitymodule. Check out my previous post for details:Vue 3.5's new baseWatch breaks up the watch function and Vue components completely

Another thing is this.base watchfunction has little effect on the average developer, but for some downstream projects such as thevueminiIt was and is beneficial.

Add onWatcherCleanup function

and the precedingonEffectCleanupfunction is similar, either before the component is unloaded or the next time thewatchThe callback is automatically called before it executes theonWatcherCleanupfunction, again with this function you don't need to add the component'sbeforeUnmountThe hook function goes and cleans up some timers in a uniform way. For example, the following scenario:

import { watch, ref, onWatcherCleanup } from "vue";

watch(flag, () => {
  const timer = setInterval(() => {
    // Do something.
    ("do something");
  }, 200);
  onWatcherCleanup(() => {
    ("Clear Timer");
    clearInterval(timer);
  });
});

cap (a poem)onEffectCleanupfunction is different because we can import it from vue.onWatcherCleanupfunction.

New pause and resume methods

There are scenarios where we might want to "pause for a while" and not execute thewatchorwatchEffectin the callback. Wait for the business conditions to be met before resuming execution of thewatchorwatchEffectin the callback. In this scenariopausecap (a poem)resumeThe method will come in handy.

Here's one.watchEffectexample, the code is as follows:

<template>
  <button @click="count++">count++</button>
  <button @click="()">pause (media player)</button>
  <button @click="()">resumption</button>
</template>

<script setup lang="ts">
import { watchEffect } from "vue";

const count = ref(0);
const runner = watchEffect(() => {
  if ( > 0) {
    ();
  }
});
</script>

In the demo above, click on thecount++button will theoretically be executed once perwatchEffectThe pullback.

But when we click the pause button it executes thepausemethod performs a pause, during which thewatchEffectcallback would not be executed.

Once we have clicked on the restore button again it will execute theresumemethod for recovery, at which point thewatchEffectcallback is then re-executed.

The results are shown below:
console

As you can see from the chart abovecountIt didn't continue after printing to 4 because we executed thepausemethod was suspended. When the re-execution of theresumeAfter the method is restored you can seecountIt's back to printing again, and at this point it's printing from 8.

not the only onewatchEffectexecutablepausecap (a poem)resumeMethods.watchThe same can be donepausecap (a poem)resumemethod. The code is as follows:

const runner = watch(count, () => {
  if ( > 0) {
    (); }
  }
});

() // Pause method
() // Resume method

The watch's deep option supports passing in numbers

beforedeepThe value of the option is eitherfalseEithertruethat indicates whether to listen deeply to an object. In 3.5deepoption supports passing in numbers now, indicating the depth of the monitored object.

For example, this demo below:

const obj1 = ref({
  a: {
    b: 1,
    c: {
      d: 2,
      e: {
        f: 3,
      },
    },
  },
});

watch(
  obj1,
  () => {
    ("I'm listening in.obj1variations");
  },
  {
    deep: 3,
  }
);

function changeDeep3Obj() {
   = 20;
}

function changeDeep4Obj() {
   = 30;
}

In the example abovewatch(used form a nominal expression)deepAn option value of 3 indicates listening to layer 3 of the object.

changeDeep3Objfunction is to modify the object's 3rd level of thedattribute, so it can trigger thewatchThe pullback.

(indicates contrast)changeDeep4Objfunction is to modify the object's level 4fattribute, so it can't trigger thewatchThe pullback.

SSR server-side rendering

The server-side rendering of the SSR has these main parts: adding theuseIdFunction, Lazy Hydration Lazy loading hydration,data-allow-mismatch

additionaluseIdfunction (math.)

Sometimes we need to generate a random number to stuff onto a DOM element, like in the following scenario:

<template>
  <label :htmlFor="id">Do you like Vue3.5?</label>
  <input type="checkbox" name="vue3.5" : />
</template>

<script setup lang="ts">
const id = ();
</script>

In this scenario we need to generate a random numberid, this code is fine in normal client-side rendering.

But if this code is in SSR server-side rendering then it will report a warning as shown below:
useId

The error reported above means that the server-side and client-side generatedidis not the same, because both the server and the client execute a()generatingid. As a result of()The result is different for each execution, and naturally the server-side and client-side generatedidAlso different.

useIdThe function is there to solve this problem.

without doubtuseIdIt can also be used in some scenarios for client-side rendering, such as when we need a unique key in a list but the server doesn't give it to us, then we can use theuseIdGenerate a unique key for each item in the list.

Lazy Hydration

Asynchronous components can now control when to hydrate via the hydrate option of the defineAsyncComponent() API. (Ouyang doesn't think this is useful for normal developers, so he won't go into details)

data-allow-mismatch

There are times when SSR does not generate the same html on the server side as on the client side, such as rendering the current time on top of the DOM with the following code:

<template>
  <div> The current time is: {{ new Date() }}</div>
</template>

This is a situation that can't be avoided up frontuseIdexample, at which point we can use thedata-allow-mismatchattribute to take out the warning, the code is as follows:

<template>
  <div data-allow-mismatch> The current time is: {{ new Date() }}</div>
</template>

Custom Element Custom Element Improvements

This Ouyang also thinks that usually people can't use it, so I won't go into details.

New defer delay attribute for the Teleport component

TeleportThe role of the component is to deliver the contents of the children to the specified location, as in the following code:

<div ></div>
<Teleport to="#target"> what is being transmitted </Teleport>

copywritertransmitted contentIt will eventually be rendered in thein the div element of the

There was a restriction in the previous that you couldn't set the<div >put togetherTeleportbehind the component.

It's also easy to understand that the DOM starts rendering from the top down, and if it first renders to theTeleportcomponent. It then goes to the value of the id for thetargetelement, if it can't be found of course it won't succeed in putting theTeleportThe child nodes of the component are transferred to thetargetThe location.

In 3.5 in order to address this issue, theTeleportcomponent has a newdeferDelay properties.

addeddeferThe delay attribute will then be able to set thetargetput down inTeleportbehind the component with the following code:

<Teleport defer to="#target"> what is being transmitted </Teleport>
<div ></div>

deferThe delay attribute is also simple to implement by waiting until the end of this rendering cycle to render theTeleportcomponent. So even if thetargetput down inTeleportcomponent, wait until the renderingTeleportcomponent at the time oftargetIt has also been rendered to the page.

useTemplateReffunction (math.)

To access the DOM and subcomponents in vue3 you can use a ref for template references, but there is something confusing about this ref.

For example, is the defined ref variable a responsive data or a DOM element?

There are also templates where the value of the ref attribute is clearly a string, for exampleref="inputEl"Why does it have the same name as in the script?inputElWhat about variables tied together?

in 3.5useTemplateReffunction solves these problems perfectly.

This is an example of using ref to access an input field before 3.5:

<input type="text" ref="inputEl" />

const inputEl = ref<HTMLInputElement>();

This is a very unintuitive way of writing programming, and I wonder how many of you, like Ouyang, started using vue3 when you would give therefproperty binds a responsive variable. Like this::ref="inputEl"

What's even worse is that writing it this way doesn't report an error, it's theinputElThe value inundefined

It was only after a last-minute search that we realizedrefattribute should be the name of the bound variable:ref="inputEl"

utilizationuseTemplateReffunction is much better, the code is as follows:

<input type="text" ref="inputRef" />

const inputEl = useTemplateRef<HTMLInputElement>("inputRef");

utilizationuseTemplateReffunction returns a ref variable.useTemplateRefThe parameters passed to the function are strings"inputRef"

In templaterefThe value of the property is also a string"inputRef"So.useTemplateRefThe return value of the function points to the input box of the DOM element. This is a much better experience than before 3.5, check out my previous post for more details:Vue 3.5's useTemplateRef makes ref manipulation of the DOM even silkier!

summarize

There are still many interesting features added to Vue 3.5 for developers, such as:onEffectCleanupfunction,onWatcherCleanupfunction,pausecap (a poem)resumeMethods,watch(used form a nominal expression)deepoption supports passing in numbers,useIdfunction,TeleportComponent AdditionsdeferDelay properties,useTemplateReffunction.

These features are still useful in some special scenarios, and Ouyang's personal opinion is that you still have to upgrade Vue to 3.5.

Follow the public number: [Front-end Ouyang], give yourself a chance to advance vue

Also Ouyang wrote an open source ebookvue3 Compilation Principles Revealed, reading this book can give you a qualitative improvement in your knowledge of vue compilation. This book is accessible to beginner and intermediate front-ends and is completely free, just asking for a STAR.