The setup function

1. Setpup is executed before beforCreate, so data and methods cannot be used in setup functions and vue changes this to undefined in setup.

2. The setup function can only be synchronous

3. Add reactive data numbers to setup functions in conjunction with ref () and Reactive () methods.

reactive

setup(){

	const state = reactive({

	count:0

	})

return { state }

}
Copy the code
<div>
    {{ state.count }}
</div>
Copy the code

1. Using Reactive alone returns an object that requires state.count to read data.

2. Reactive must receive an object (JSON /Arr)

If another object is passed in, the interface for modifying the value of the object directly does not update automatically. If you want to update it, you can reassign it.

ref

setup(){

	const count = ref(0)
    / / change the value
    count.value++

return { count }

}
Copy the code
<div>
   {{ count }} 
</div>
Copy the code

1. Refs are reactive in nature. After a value is passed to the ref function, the lower layer of the ref function will change the ref to Reactive.

ref(0)>reactive({value:0})
Copy the code

Therefore, the ref method alone is used to create a reactive object. When changing its value, count. Value is used, but in HTML, count can be used directly.

2. Vue uses the private attribute __v_ref to determine whether the data is a REF object, and provides isRef() method externally to determine whether the data is a REF object. Reactive can be determined using the isReactiv() method.

ToRef and REF

Ref -> copy the original data. Changing the reactive data does not affect the original data

ToRef -> references the original data, and changing the reactive data changes the original data

Ref -> change the responsive data, and the interface automatically updates

ToRef -> changes responsive data, the interface does not automatically update

Application scenarios of toRef: The toRef method can be used when reactive data is associated with original data and the interface does not want to be updated after updating reactive data.

ToRefs method

The toRefs method is short for toRef and can be used when an object has multiple attributes that need to be converted to a REF object.

The customRef method customizes the ref

The customRef method returns a REF object, and you can explicitly control dependency tracing and triggering

function useDebouncedRef(value, delay = 200) {
  let timeout
  return customRef((track, trigger) = > {
    return {
      get() {
        track()
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() = > {
          value = newValue
          trigger()
        }, delay)
      }
    }
  })
}
Copy the code

Ref and Reactive are used in combination

setup(){

	const state = reactive({

	count:0

	})
    
    const { count } = toRefs(state) // Convert normal data to reactive data corresponding to the ref method
    
/ / change the value
    state.count++;
    
return { count }

}
Copy the code

Ref and Reactive recursive and non-recursive listening

1. Both REF and Reactive are recursive listeners by default. However, recursive listeners have disadvantages in performance (converting objects at each layer into proxy objects consumes high performance).

2. ShallowRef and shallowReactive can be used to create non-recursive listening (generally used for large amounts of data).

Note: If shallowRef is used to create data, vue only listens for changes in the value of the first layer (e.g. State.value). Because ref is converted to Reactive, value is essentially the first layer.

Vue3 provides the triggerRef() method for manually updating ref objects, but does not triggerReactive.

ToRow method

The toRow() method retrieves raw data from ref and Reactive objects. Modifying objects obtained using the toRow method can be used to modify the raw data of ref and Reactive without triggering a listener or updating the UI.

Value (toRow(state.value));

Used to improve performance

MarkRow method

The markRow method allows an object to never be listened on. If markRow(obj) is used, it will not be listened on even if an object is created reactive or ref using obj later

Use computed in setup

    setup() {
      const state = reactive({
        count: 1.num: 0
      })

      setTimeout(() = > {
        state.count++
      }, 1000)
// Import can be used directly in setup
      state.num = computed(() = > {
        return state.count + 1
      })


      return {state}
    },
Copy the code

watchEffect

WatchEffect is used to pass in a function, execute it immediately, trace its dependencies in a responsive manner, and re-run the function if the dependencies change. The function is similar to watch.

const count = ref(0)

watchEffect(() = > console.log(count.value))
// -> print out 0

setTimeout(() = > {
  count.value++
  // -> print 1
}, 100)
Copy the code

readonly

1. Readonly Creates a read-only data that is recursively read-only

2. ShallowReadonly is used to create a non-recursive read-only read-only data

3. The difference between const and readOnly: Objects created by const can change their properties, whereas readOnly cannot.

Const is assignment protected, readonly is property protected.

Common syntax changes for VU3

Ref array in V -for

In Vue 3, the ref in V-for will no longer automatically create arrays in $ref. To get multiple Refs from a single binding, you need to bind the ref to a more flexible function

<div v-for="item in list" :ref="setItemRef"></div>
Copy the code
// option api
export default {
  data() {
    return {
      itemRefs: []}},methods: {
    setItemRef(el) {
      this.itemRefs.push(el)
    }
  },
  beforeUpdate() {
    this.itemRefs = []
  },
  updated() {
    console.log(this.itemRefs)
  }
}

// composition api
import { ref, onBeforeUpdate, onUpdated } from 'vue'

export default {
  setup() {
    let itemRefs = []
    const setItemRef = el= > {
      itemRefs.push(el)
    }
    onBeforeUpdate(() = > {
      itemRefs = []
    })
    onUpdated(() = > {
      console.log(itemRefs)
    })
    return {
      itemRefs,
      setItemRef
    }
  }
}
Copy the code

V – model change

1. Vue3 can now use multiple V-Models on the same component for bidirectional binding;

2. You can now customize v-Model modifiers

3. V-bind’s.sync modifier and model option for the component have been removed and v-model can be used instead

In VUe2, v-Models on components are hard-bound value prop and input events, and modifying properties or event names requires adding model options to child components.

In VUE3, the custom component V-Model is equivalent to passing a ModelValue prop and receiving an Update: ModelValue event thrown

<ChildComponent v-model:title="pageTitle" />
    / / equivalent to
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />
Copy the code

This can also be used as an alternative to the.sync modifier, and multiple V-models can be used on custom components.

4. Vue3 custom modifiers

Modifiers added to the component’s V-model are provided to the component through the modelModifiers Prop

<my-component v-model.capitalize="myText"></my-component>
Copy the code
app.component('my-component', {
  props: {
    modelValue: String.modelModifiers: {
      default: () = >({})}},emits: ['update:modelValue'].template: `  `.created() {
    console.log(this.modelModifiers) // { capitalize: true }}})Copy the code

For V-Model bindings with parameters, the generated prop names will be arG + “Modifiers”

<my-component v-model:description.capitalize="myText"></my-component>
Copy the code
app.component('my-component', {
  props: ['description'.'descriptionModifiers'].emits: ['update:description'].template: `  `.created() {
    console.log(this.descriptionModifiers) // { capitalize: true }}})Copy the code

V-bind merge behavior

In VUe2 if an element defines both v-bind= “object” and an identical separate property, that separate property will always override object.

<! -- template -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<! -- result -->
<div id="red"></div>
Copy the code

The order of declarations in VUE3 determines what merges are

<! -- template -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<! -- result -->
<div id="blue"></div>

<! -- template -->
<div v-bind="{ id: 'blue' }" id="red"></div>
<! -- result -->
<div id="red"></div>
Copy the code

The v-IF and V-for priorities change

In VUe2, v-if and V-for are used together, because v-for takes precedence over each other. In VUe3, v-IF always takes precedence over V-for. Now they can be used together.

Remove the V-on. native modifier

The event listener passed to a component with V-ON in VUe2 can only be emitted via this.$emit. To add native DOM event listeners to the group component root element, use the. Native decorator.

The v-on. Native modifier in VUe3 has been removed and the emits option has been added to allow child components to define events that are actually fired. For all event listeners in a child component that are not defined to be triggered by the component, Vue adds them to the child component root element as native event listeners (unless inheritAttrs: False is set in the child component’s options).

$children removed

Vue3 can no longer use this. children to directly access the children of the current instance. It is recommended that children directly access the child components of the current instance. It is recommended that children directly access the child components of the current instance. Refs is recommended.

$attrs including

class & style

There are special treatments for class and style attributes in Vue 2’s virtual DOM implementation. Therefore, they are not included in $attrs, but are still applied to the root element of the component.

MyComponent:

<template>
  <label>
    <input type="text" v-bind="$attrs" />
  </label>
</template>
<script>
export default {
  inheritAttrs: false
}
</script>
Copy the code
<my-component id="my-id" class="my-class"></my-component>
Copy the code

The HTML generated when used in VUe2 is:

<label class="my-class">
  <input type="text" id="my-id" />
</label>
Copy the code

Class is automatically applied to label, and the HTML generated in VUe3 is:

<label>
  <input type="text" id="my-id" class="my-class" />
</label>
Copy the code

Remove $listeners

Listeners have been removed from vue3, and now listeners are part of attrs. Listeners have been removed from VUe3.

<template>
  <label>
    <input type="text" v-bind="$attrs" />
  </label>
</template>
<script>
export default {
  inheritAttrs: false
}
</script>
Copy the code

If this component received an ID attribute and a V-ON :close listener, the $attrs object would now look like this:

{
  id: 'my-input'.onClose: () = > console.log('close Event triggered')}Copy the code

Factory functions that generate prop defaults can no longer access this

Alternatives:

1. Pass the original prop received by the component as an argument to the default function;

2. The injection API can be used in default functions.

import { inject } from 'vue'

export default {
  props: {
    theme: {
      default (props) {
        // 'props' is the raw value passed to the component.
        // Before any type/default cast
        // The injected property can also be accessed using 'inject'
        return inject('theme'.'default-theme')}}}}Copy the code