Vue3 study notes

Posted by foochuck on Tue, 08 Mar 2022 00:03:26 +0100

Vue3 study notes

  1. setup = data + methods + computeds

  2. Report component: transfer its internal content to the target element

  3. Suspend component: load asynchronous component

  4. createApp(): create a new instance

  5. Do not use the arrow function on the option property or callback, because it does not have this, resulting in an error

  6. v-once: when the data changes, the content at the interpolation will not be updated

    1. <span v-once>This will not change: {{ msg }}</span>
      
  7. V-html: Double curly braces interpret data as plain text rather than HTML code. In order to output real HTML, you need to use the v-html instruction:

    1. const RenderHtmlApp = {
        data() {
          return {
            rawHtml: '<span style="color: red">This should be red.</span>'
          }
        }
      }
      
      Vue.createApp(RenderHtmlApp).mount('#example1')
      
    2. <div id="example1" class="demo">
          <p>Using mustaches: {{ rawHtml }}</p>
          <p>Using v-html directive: <span v-html="rawHtml"></span></p>
      </div>
      
    3. Dynamically rendering arbitrary HTML on your site is very dangerous because it can easily lead to XSS attack . Please use HTML interpolation only for trusted content, and never use user provided content as interpolation.

    4. The contents of this span will be replaced with the property value rawHtml, which will be directly used as HTML -- ignoring the data binding in parsing the property value. Note that you cannot use v-html to compound local templates because Vue is not a string based template engine. On the contrary, for user interface (UI), components are more suitable as reusable and composable basic units.

  8. Dynamic parameters:

    1. <a v-bind:[attributeName]="url"> ... </a>
      
      <a v-on:[eventName]="doSomething"> ... </a>
      
    2. The dynamic parameter is expected to find a string, and the value is null in case of exception. This special null value can be explicitly used to remove the binding. Any other value of non string type will trigger a warning.

    3. Dynamic parameter expressions have some syntactic constraints because some characters, such as spaces and quotation marks, are invalid in HTML attribute names.

      1. <!-- This triggers a compilation warning -->
        <a v-bind:['foo' + bar]="value"> ... </a>
        
    4. When using a template in DOM (writing a template directly in an HTML file), you also need to avoid using uppercase characters to name the key name, because the browser will force all attribute names to lowercase:

      1. <!--
        stay DOM When using the template in, this code will be converted to `v-bind:[someattr]`. 
        Unless there is an instance named“ someattr"of property,Otherwise, the code will not work.
        -->
        <a v-bind:[someAttr]="value"> ... </a>
        
  9. Modifier:

    1. . prevent: event is called by event preventDefault();
  10. data:

    1. const app = Vue.createApp({
        data() {
          return { count: 4 }
        }
      })
      
      const vm = app.mount('#app')
      
      console.log(vm.$data.count) // => 4
      console.log(vm.count)       // => 4
      
      // Modify VM The value of count will also update $data count
      vm.count = 5
      console.log(vm.$data.count) // => 5
      
      // vice versa
      vm.$data.count = 6
      console.log(vm.count) // => 6
      
    2. It is feasible to directly add new properties that are not included in data to the component instance. However, since the property is not in the behind responsive $data object, so Vue's responsive system It won't be tracked automatically.

  11. Avoid using arrow functions when defining methods, as this prevents Vue from binding the appropriate this point.

  12. Anti shake and throttling: Lodash

    1. In order to make the component instances independent of each other, you can add the anti shake function in the created of the life cycle hook:

    2. app.component('save-button', {
        created() {
          // Using Lodash's anti shake function
          this.debouncedClick = _.debounce(this.click, 500)
        },
        unmounted() {
          // Cancel the timer when the component is removed
          this.debouncedClick.cancel()
        },
        methods: {
          click() {
            // ...  Response click
          }
        },
        template: `
          <button @click="debouncedClick">
            Save
          </button>
        `
      })
      
  13. Calculate attributes: expressions in the template are very convenient, but they are designed for simple operations. Putting too much logic in the template will make the template too heavy and difficult to maintain.

    Computational properties should be used for any complex logic that contains responsive data.

    Basic examples:

    <div id="computed-basics">
      <p>Has published books:</p>
      <span>{{ publishedBooksMessage }}</span>
    </div>
    
    <script>
    Vue.createApp({
      data() {
        return {
          author: {
            name: 'John Doe',
            books: [
              'Vue 2 - Advanced Guide',
              'Vue 3 - Basic Guide',
              'Vue 4 - The Mystery'
            ]
          }
        }
      },
      computed: {
        // Calculate the getter of the property
        publishedBooksMessage() {
          // `this` points to the vm instance
          return this.author.books.length > 0 ? 'Yes' : 'No'
        }
      }
    }).mount('#computed-basics')
    </script>
    

    You can bind data to the calculated properties in the template like normal properties.

    Vue knows VM Publishedbookmessage depends on VM author. Books, so when VM author. When books changes, all rely on VM The publishedbookmessage binding will also be updated.

    And the best thing is that we have created this dependency in a declarative way: the getter function that calculates the attribute has no side effects, which makes it easier to test and understand.

    Computed attributes are cached based on their response dependencies

    Computed properties are re evaluated only when the relevant responsive dependency changes. This means that as long as the author Books hasn't changed yet. Accessing the publishedBookMessage calculation property multiple times will immediately return the previous calculation results without executing the function again.

    By default, there is only getter for calculating properties, but you can also provide a setter when necessary:

    // ...
    computed: {
      fullName: {
        // getter
        get() {
          return this.firstName + ' ' + this.lastName
        },
        // setter
        set(newValue) {
          const names = newValue.split(' ')
          this.firstName = names[0]
          this.lastName = names[names.length - 1]
        }
      }
    }
    // ...
    
  14. Listener: This is most useful when you need to perform asynchronous or expensive operations when data changes.

    1. <div id="watch-example">
        <p>
          Ask a yes/no question:
          <input v-model="question" />
        </p>
        <p>{{ answer }}</p>
      </div>
      
      <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
      <script>
        const watchExampleVM = Vue.createApp({
          data() {
            return {
              question: '',
              answer: 'Questions usually contain a question mark. ;-)'
            }
          },
          watch: {
            // whenever question changes, this function will run
            question(newQuestion, oldQuestion) {
              if (newQuestion.indexOf('?') > -1) {
                this.getAnswer()
              }
            }
          },
          methods: {
            getAnswer() {
              this.answer = 'Thinking...'
              axios
                .get('https://yesno.wtf/api')
                .then(response => {
                  this.answer = response.data.answer
                })
                .catch(error => {
                  this.answer = 'Error! Could not reach the API. ' + error
                })
            }
          }
        }).mount('#watch-example')
      </script>
      
    2. In this example, using the watch option allows us to perform an asynchronous operation (access an API), limits how often we perform the operation, and sets the intermediate state before we get the final result. These are things that computational properties cannot do.

  15. class binds the calculation property of a return object:

    1. <div :class="classObject"></div>
      
      <script>
      data() {
        return {
          isActive: true,
          error: null
        }
      },
      computed: {
        classObject() {
          return {
            active: this.isActive && !this.error,
            'text-danger': this.error && this.error.type === 'fatal'
          }
        }
      }
      </script>
      
    2. Pass array to: class:

    3. <div :class="[activeClass, errorClass]"></div>
      
      <div :class="[{ active: isActive }, errorClass]"></div>
      
      <script>
      data() {
        return {
          activeClass: 'active',
          errorClass: 'text-danger'
        }
      }
      </script>
      
    4. Ternary expression:

    5. <div :class="[isActive ? activeClass : '', errorClass]"></div>
      
  16. If your component has multiple root elements, you need to define which parts will receive this class. You can do this using the $attrs component attribute:

    1. <div id="app">
        <my-component class="baz"></my-component>
      </div>
      
      const app = Vue.createApp({})
      
      app.component('my-component', {
        template: `
          <p :class="$attrs.class">Hi!</p>
          <span>This is a child component</span>
        `
      })
      
  17. : style

    1. <div :style="styleObject"></div>
      
      data() {
        return {
          styleObject: {
            color: 'red',
            fontSize: '13px'
          }
        }
      }
      

      Object syntax is often used in conjunction with the calculated properties of the returned object.

      Vue will automatically detect and add the corresponding browser prefix

  18. v-if

    1. <div v-if="type === 'A'">
        A
      </div>
      <div v-else-if="type === 'B'">
        B
      </div>
      <div v-else-if="type === 'C'">
        C
      </div>
      <div v-else>
        Not A/B/C
      </div>
      
  19. v-show does not support elements or v-else

  20. v-if VS v-show

    1. v-if is a "real" conditional rendering because it ensures that event listeners and subcomponents within the conditional block are properly destroyed and rebuilt during switching.

      v-if is also lazy: if the condition is false at the initial rendering, nothing is done -- the conditional block does not start rendering until the condition first becomes true.

      In contrast, v-show is much simpler -- no matter what the initial conditions are, elements are always rendered and simply switched based on CSS.

      Generally speaking, v-if has higher switching overhead, while v-show has higher initial rendering overhead.

      Therefore, if you need to switch very frequently, it is better to use v-show; If-v is rarely used when the operating conditions are changed.

  21. Using both v-if and v-for is not recommended. When v-if is used with v-for, v-if has a higher priority than v-for.

  22. You can also use of instead of in as the separator for v-for, because it is closer to the syntax of JavaScript iterators

  23. When Vue is updating the list of elements rendered using v-for, it defaults to the update in place policy. If the order of data items is changed, Vue will not move DOM elements to match the order of data items, but update each element in place and ensure that they are rendered correctly at each index position.

    This default mode is efficient, but only applies to list rendered output that does not depend on subcomponent state or temporary DOM state (e.g. form input value).

  24. Vue wraps the change method of the array being listened on, so they will also trigger view updates.

  25. Vue implements some intelligent heuristic methods to maximize the reuse of DOM elements, so it is very efficient to replace the original array with an array containing the same elements.

    example1.items = example1.items.filter(item => item.message.match(/Foo/))
    
  26. Sometimes we want to display the filtered or sorted version of an array without actually changing or resetting the original data. In this case, you can create a calculated property to return the filtered or sorted array.

    For example:

    <li v-for="n in evenNumbers">{{ n }}</li>
    
    data() {
      return {
        numbers: [ 1, 2, 3, 4, 5 ]
      }
    },
    computed: {
      evenNumbers() {
        return this.numbers.filter(number => number % 2 === 0)
      }
    }
    
  27. v-for can also accept integers. In this case, it repeats the template the corresponding number of times.

    <div id="range" class="demo">
      <span v-for="n in 10">{{ n }} </span>
    </div>
    
  28. Any data will not be automatically transferred to the component, because the component has its own independent scope. In order to transfer iterative data to components, we need to use props;

    The reason why item s are not automatically injected into components is that this makes components closely coupled with the operation of v-for. Clarifying the source of component data can enable components to be reused in other occasions.

  29. Access the original DOM event in methods. You can pass it into the method with the special variable $event:

    <button @click="warn('Form cannot be submitted yet.', $event)">
      Submit
    </button>
    
    // ...
    methods: {
      warn(message, event) {
        // now we have access to the native event
        if (event) {
          event.preventDefault()
        }
        alert(message)
      }
    }
    
  30. There can be multiple methods in the event handler, which are separated by comma operators:

    <!-- these two items. one() and two() The button click event will be executed -->
    <button @click="one($event), two($event)">
      Submit
    </button>
    
    // ...
    methods: {
      one(event) {
        // first handler logic...
      },
      two(event) {
        // second handler logic...
      }
    }
    
  31. Methods only have pure data logic, rather than dealing with DOM event details.

  32. Event modifier:

    1. <!-- Stop bubbling -->
      <a @click.stop="doThis"></a>
      
      <!-- Submitting an event no longer reloads the page -->
      <form @submit.prevent="onSubmit"></form>
      
      <!-- Modifiers can be concatenated -->
      <a @click.stop.prevent="doThat"></a>
      
      <!-- Only modifiers -->
      <form @submit.prevent></form>
      
      <!-- Use event capture mode when adding event listeners -->
      <!-- That is, events triggered by internal elements are processed here first, and then handed over to internal elements for processing -->
      <div @click.capture="doThis">...</div>
      
      <!-- Only when event.target Is the handler function triggered when the current element itself -->
      <!-- That is, the event is not triggered from an internal element -->
      <div @click.self="doThat">...</div>
      
      <!-- The click event will only be triggered once -->
      <a @click.once="doThis"></a>
      
      <!-- Default behavior for scrolling events (Rolling behavior) Will be triggered immediately   -->
      <!-- Without waiting `onScroll` complete                   -->
      <!-- This includes `event.preventDefault()` Situation   -->
      <div @scroll.passive="onScroll">...</div>
      

      When using modifiers, order is important; The corresponding code will be generated in the same order. Therefore, use v-on: click prevent. Self will block all clicks, while v-on: click self. Prevent only blocks clicks on the element itself.

      Don't take it passive and Use with prevent because Prevent will be ignored and the browser may show you a warning. Remember passive will tell the browser that you don't want to block the default behavior of the event.

  33. Key modifier:

    1. <!-- Only in `key` yes `Enter` Time call `vm.submit()` -->
      <input @keyup.enter="submit" />
      
      <!-- The handler will only $event.key be equal to 'PageDown' Called when.-->
      <input @keyup.page-down="onPageDown" />
      
      <!-- Alt + Enter -->
      <input @keyup.alt.enter="clear" />
      
      <!-- Ctrl + Click -->
      <div @click.ctrl="doSomething">Do something</div>
      
      <!-- even if Alt or Shift It is also triggered when pressed together -->
      <button @click.ctrl="onClick">A</button>
      
      <!-- Yes and only Ctrl Triggered when pressed -->
      <button @click.ctrl.exact="onCtrlClick">A</button>
      
      <!-- Triggered when no system modifier is pressed -->
      <button @click.exact="onClick">A</button>
      
    2. .enter

    3. .tab

    4. . delete (capture delete and backspace keys)

    5. .esc

    6. .space

    7. .up

    8. .down

    9. .left

    10. .right

    11. .ctrl

    12. .alt

    13. .shift

    14. .meta

    15. On the Mac keyboard, meta corresponds to the command key (⌘). On the Windows system keyboard, meta corresponds to the Windows logo key (⊞). On the Sun operating system keyboard, meta corresponds to the solid gem key (◆). On other specific keyboards, especially those of MIT and Lisp machines, and their successor products, such as Knight keyboard and space cadet keyboard, meta is marked as "meta". On the symbols keyboard, meta is marked as "meta" or "meta".

    16. The. exact modifier allows you to control events triggered by a precise combination of system modifiers.

    17. Mouse modifier:

      1. .left
      2. .right
      3. .middle
  34. Because all Vue JS event handling methods and expressions are strictly bound to the ViewModel of the current view, so it will not lead to any maintenance difficulties.

  35. v-model will ignore the initial values of value, checked and selected attribute s of all form elements, and always take the data of the current active instance as the data source. You should declare the initial value in the data option of the component through JavaScript.

  36. v-model will automatically select the correct method to update the element according to the space type.

    v-model internally uses different properties for different input elements and throws different events:

    • text and textarea elements use value property and input events;
    • checkbox and radio use checked property and change events;
    • The select field takes value as a prop and change as an event.

    For the need to use typewriting (such as Chinese, Japanese, Korean, etc.), you will find that v-model will not be updated in the process of organizing text in the input method. If you also want to handle this process, use the input event.

  37. Modifier:

    1. .lazy:

      1. <!-- In“ change"Sometimes not“ input"Update when -->
        <input v-model.lazy="msg" />
        
    2. . number: automatically convert the user's input value to numeric type

      1. <input v-model.number="age" type="number" />
        
    3. . trim: automatically filter the first and last blank characters entered by the user

      1. <input v-model.trim="msg" />
        
  38. app.component('blog-post', {
      props: ['title'],
      emits: ['enlarge-text']
    })
    
  39. $event

  40. Dynamic components:

    1. <!-- The component will be `currentTabComponent` Change when you change -->
      <component :is="currentTabComponent"></component>
      
      <scirpt>
      computed: {
          currentTabComponent() {
            return 'tab-' + this.currentTab.toLowerCase()
          }
        }
      </scirpt>
      
  41. HTML attribute names are not case sensitive, so the browser will interpret all uppercase characters as lowercase.

  42. v-is

    1. Some HTML elements, such as < UL >, < ol >, < Table > and < Select >, have strict restrictions on which elements can appear inside them. Some elements, such as < li >, < tr > and < option >, can only appear inside some other specific elements.

      This leads to some problems when we use these constrained elements. For example:

      <table>
        <blog-post-row></blog-post-row>
      </table>
      

      This custom component < blog post row > will be promoted to the outside as invalid content, resulting in an error in the final rendering result. Fortunately, this special v-is attribute gives us an alternative:

      <table>
        <tr v-is="'blog-post-row'"></tr>
      </table>
      
      <!-- Wrong, it won't render anything v-is Value should be JavaScript String text -->
      <tr v-is="blog-post-row"></tr>
      
      <!-- correct -->
      <tr v-is="'blog-post-row'"></tr>
      
  43. Putting a variable name similar to ComponentA in the object is actually ComponentA: the abbreviation of ComponentA:

    1. import ComponentA from './ComponentA.vue'
      
      export default {
        components: {
          ComponentA
        }
        // ...
      }
      
  44. props:

    1. props: {
          // Basic type check (` null 'and ` undefined' will pass any type verification)
          propA: Number,
          // Multiple possible types
          propB: [String, Number],
          // Required string
          propC: {
            type: String,
            required: true
          },
          // Number with default value
          propD: {
            type: Number,
            default: 100
          },
          // Objects with default values
          propE: {
            type: Object,
            // The default value of an object or array must be obtained from a factory function
            default: function() {
              return { message: 'hello' }
            }
          },
          // Custom validation function
          propF: {
            validator: function(value) {
              // This value must match one of the following strings
              return ['success', 'warning', 'danger'].indexOf(value) !== -1
            }
          },
          // Functions with default values
          propG: {
            type: Function,
            // Unlike the default value of an object or array, this is not a factory function -- it is a function used as the default value
            default: function() {
              return 'Default function'
            }
          }
        }
      
      // When the prop verification fails, Vue will generate a console warning.
      
  45. Every time the parent component changes, all props in the child component will be refreshed to the latest value. This means that you should not change prop within a sub component. If you do, Vue will issue a warning in the browser's console.

    If the subcomponent next wants to use it as a local prop data, then

    props: ['initialCounter'],
    data() {
      return {
        counter: this.initialCounter
      }
    }
    
    //This conversion takes place with the original value of prop
    props: ['size'],
    computed: {
      normalizedSize: function () {
        return this.size.trim().toLowerCase()
      }
    }
    

    Note that in JavaScript, objects and arrays are passed in by reference, so for an array or object type prop, changing the object or array itself in the child component will affect the state of the parent component.

    Note that those props will be verified before a component instance is created, so the property of the instance (such as data, computed, etc.) is not available in the default or validator function.

  46. – > non Prop attributes

  47. Add TS support: vue add typescript

  48. For TypeScript to correctly infer types in Vue component options, you need to define components using the defineComponent global method:

    import { defineComponent } from 'vue'
    
    const Component = defineComponent({
      // Type inference enabled
    })
    
  49. If you have a complex type or interface, you can use type assertion Cast it:

    interface Book {
      title: string
      author: string
      year: number
    }
    
    const Component = defineComponent({
      data() {
        return {
          book: {
            title: 'Vue 3 Guide',
            author: 'Vue Team',
            year: 2020
          } as Book
        }
      }
    })
    
  50. Due to the circular nature of Vue declaration files, TypeScript may have difficulty inferring the type of computed. You may need to calculate the type of property you return.

    import { defineComponent } from 'vue'
    
    const Component = defineComponent({
      data() {
        return {
          message: 'Hello!'
        }
      },
      computed: {
        // Comments required
        greeting(): string {
          return this.message + '!'
        }
    
        // When using setter for calculation, you need to annotate the getter
        greetingUppercased: {
          get(): string {
            return this.greeting.toUpperCase();
          },
          set(newValue: string) {
            this.message = newValue.toUpperCase();
          },
        },
      }
    })
    
  51. Vue performs run-time validation on prop with type defined. To provide these types to TypeScript, we need to use the PropType cast constructor:

    import { defineComponent, PropType } from 'vue'
    
    interface ComplexMessage {
      title: string
      okMessage: string
      cancelMessage: string
    }
    const Component = defineComponent({
      props: {
        name: String,
        success: { type: String },
        callback: {
          type: Function as PropType<() => void>
        },
        message: {
          type: Object as PropType<ComplexMessage>,
          required: true,
          validator(message: ComplexMessage) {
            return !!message.title
          }
        }
      }
    })
    

    If you find that the validator does not get type inference or member completion does not work, annotating parameters with the expected type may help solve these problems.

  52. Refs infers the type based on the initial value:

    import { defineComponent, ref } from 'vue'
    
    const Component = defineComponent({
      setup() {
        const year = ref(2020)
    
        const result = year.value.split('') // => Property 'split' does not exist on type 'number'
      }
    })
    

    Sometimes we may need to specify a complex type for the internal value of Ref. We can simply pass a generic parameter when calling ref to override the default reasoning:

    const year = ref<string | number>('2020') // year's type: Ref<string | number>
    
    year.value = 2020 // ok!
    
  53. When declaring the type reactive property, we can use the interface:

    import { defineComponent, reactive } from 'vue'
    
    interface Book {
      title: string
      year?: number
    }
    
    export default defineComponent({
      name: 'HelloWorld',
      setup() {
        const book = reactive<Book>({ title: 'Vue 3 Guide' })
        // or
        const book: Book = reactive({ title: 'Vue 3 Guide' })
        // or
        const book = reactive({ title: 'Vue 3 Guide' }) as Book
      }
    })
    
  54. If the type of generic type is unknown, it is recommended to convert ref to ref < T >.

  55. The calculated value will automatically infer the type based on the return value

    import { defineComponent, ref, computed } from 'vue'
    
    export default defineComponent({
      name: 'CounterButton',
      setup() {
        let count = ref(0)
    
        // read-only
        const doubleCount = computed(() => count.value * 2)
    
        const result = doubleCount.value.split('') // => Property 'split' does not exist on type 'number'
      }
    })
    
  56. setup

    1. Two parameters:

      1. props

        1. To deconstruct prop, you can do it through toRefs:

          1. import { toRefs } from 'vue'
            
            setup(props) {
            	const { title } = toRefs(props)
            
            	console.log(title.value)
            }
            
      2. context: context

        1. export default {
            setup(props, context) {
              // Attribute (non responsive object)
              console.log(context.attrs)
          
              // Slot (non responsive object)
              console.log(context.slots)
          
              // Trigger event (method)
              console.log(context.emit)
            }
          }
          
        2. It is not responsive, which means you can safely use ES6 Deconstruction on context.

          // MyBook.vue
          export default {
            setup(props, { attrs, slots, emit }) {
              ...
            }
          }
          
        3. Attrs and slots are stateful objects, which are always updated with the update of the component itself. This means that you should avoid deconstructing them and always use attrs X or slots X refers to property. Note that unlike props, attrs and slots are non responsive. If you plan to apply side effects based on attrs or slots changes, you should do so in the onUpdated lifecycle hook.

      3. The component instance was not created when setup was executed. Therefore, you can only access the following properties:

        • props
        • attrs
        • slots
        • emit

        In other words, you will not be able to access the following component options:

        • data
        • computed
        • methods
      4. Inside setup(), this will not be a reference to the active instance. Because setup() is called before parsing other component options, the behavior of this inside setup() is completely different from that in other options. This can cause confusion when using setup() with other optional API s.

      5. The setup function is running around the beforeCreate and created lifecycle hooks

      6. The setup function is the entry to the Composition API

      7. The variables and methods defined in the setup function finally need to be return ed, otherwise they can no longer be used in the template

      8. Since we cannot use data and methods in the setup function, Vue directly changed this in the setup function to undefined in order to avoid our wrong use

      9. The setup function can only be synchronous, not asynchronous

  57. Research:

    1. <script lang="ts">
      import { Options, Vue } from 'vue-class-component';
      import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src
      
      @Options({
        components: {
          HelloWorld,
        },
      })
      export default class Home extends Vue {}
      </script>
      
  58. h

    1. Returns a "virtual node", usually abbreviated as VNode: a common object that contains information describing to Vue which node it should render on the page, including the description of all child nodes. It is intended for manual writing Rendering function:

      render() {
        return Vue.h('h1', {}, 'Some title')//Three parameters (type, props, children)
      }
      

      The descendant VNode is generated using h(), or a string is used to obtain the "text VNode", or an object with a slot. Optional.

      h('div', {}, [
        'Some text comes first.',
        h('h1', 'A headline'),
        h(MyComponent, {
          someProp: 'foobar'
        })
      ])
      
  59. nextTick

    1. Postpone the callback until after the next DOM update cycle. Use the DOM immediately after you change some data to wait for it to update.

      import { createApp, nextTick } from 'vue'
      
      const app = createApp({
        setup() {
          const message = ref('Hello!')
          const changeMessage = async newMessage => {
            message.value = newMessage
            await nextTick()
            console.log('Now DOM is updated')
          }
        }
      })
      
  60. In the setup function, you can use the ref function to create a responsive data. When the data changes, Vue will automatically update the UI

    1. The ref function can only monitor the changes of basic types, not complex types (such as objects and arrays)
  61. Role of name in component:

    1. When the project uses keep alive, it can be matched with the component name for cache filtering
    2. Convenient recursive calling component
    3. Vue tools plug-in debugging requires name

Topics: Javascript Vue