1. What is Setup?

Created and beforeCreate are Created hook functions, so data and methods cannot be used in the setup function

The setup function is an entry point to the Composition API

3. Use with templates: You need to return an object. Variables and methods defined in the setup function need to return or they cannot be used in templates

The setup function accepts two parameters: props, context(including attrs, slots, emit).

Setup (), this is not a reference to the active instance, that is, it does not refer to the vue instance, vue just changed this to undefined to avoid us using it incorrectly.

Use render functions: You can return a render function that uses the reactive state declared in the same scope directly

2. The setup function uses points of caution

Created lifecycle methods are not executed at setup time, so data and methods variables and methods cannot be used in setup functions

2. Since we cannot use data and methods in setup functions, Vue directly changes this to undefined in order to avoid our incorrect use

The setup function must be synchronous, not asynchronous. The props in the setup function are reactive and will be updated when a new prop is passed in. However, because props are reactive, you can’t use ES6 deconstruction because it eliminates the responsiveness of prop.

How to use setup

The setup option should be a function that accepts props and context. In addition, everything we return from Setup is exposed to the rest of the component (computed properties, methods, lifecycle hooks, and so on) as well as the component’s template.

Personally, I think it can be interpreted as:

  1. setupThe option should be a function
  2. setupThe option function takes two arguments:propscontext
  3. setupThe option function needs to return what is exposed to the component

3.1 Parameters in the setup function –props

As expected in a standard component, the props in the setup function are reactive and will be updated when a new prop is passed in.

export default {
  props: {
    title: String
  },
  setup(props) {
    console.log(props.title)
  }
}
Copy the code

If you need to deconstruct a prop, you can do so by using toRefs in the setup function:

import { toRefs } from 'vue'

setup(props) {
    const { title } = toRefs(props)

    console.log(title.value)
}
Copy the code

3.2 Context, an argument in the setup function

Context context is a plain JavaScript object that exposes the properties of three components:

export default { setup(props, Log (context.attrs) // slot (context.slots) console.log(context.slots) // Trigger events (methods) console.log(context.emit) } }Copy the code

Context is a normal JavaScript object, that is, it is not reactive, which means you can safely use ES6 deconstruction of the context.

export default { setup(props, { attrs, slots, emit }) { ... }}Copy the code

Attrs and slots are stateful objects that are always updated as the component itself is updated. This means you should avoid deconstructing them and always refer to properties as attrs.x or slots.x. Note that, unlike props, attrs and slots are non-reactive. If you are going to change application side effects based on attrs or slots, you should do so in the onUpdated lifecycle hook.

The return value of the setup function

4.1 The return value of the Setup function — object

If setup returns an object, the object’s property can be accessed in the component’s template like the props property passed to Setup:

<template> <! -- Used in templates will be automatically unlocked, Value --> <div>{{readersNumber}} {{book.title}}</div> </template> <script> import {ref, reactive } from 'vue' export default { setup() { const readersNumber = ref(0) const book = reactive({ title: 'Vue 3 Guide' }) // expose to template return { readersNumber, book } } } </script>Copy the code

Note that refs returned from setup are automatically unwrapped when accessed in the template, so.value should not be used in the template.

4.2 Return value of setup function — render function

Setup can also return a render function that directly uses reactive state declared in the same scope:

import { h, ref, reactive } from 'vue'

export default {
  setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })
    // Please note that we need to explicitly expose ref value here
    return () => h('div', [readersNumber.value, book.title])
  }
}
Copy the code

The new Setup component option is executed before the component is created, once the props is resolved, and acts as an entry point to the composition API.

Setup functions do not use this internally

Inside setup(), this will not be a reference to the active instance, because setup() is called before parsing the other component options, so this inside setup() behaves completely differently than this in the other options. This can cause confusion when using setup() with other optional apis.

6. Responsive system API

Separate the same parts of different components and maintain them separately, with the goal of improving code reuse

6.1 reactive

Reactive () receives a common object and returns a reactive proxy for that common object. Vue.observable() equivalent to 2.x

const obj = reactive({ count: 0 })
Copy the code

Reactive transformations are “deep” : they affect all nested properties inside the object. The Proxy implementation based on ES2015 does not return a Proxy object equal to the original object. It is recommended to use only proxy objects instead of relying on primitive objects. It helps us create responsive data objects.

Import {reactive} from 'vue' export default {setup() {// state = reactive({count: 0,})}}Copy the code

6.2 ref

Accepts a parameter value and returns a reactive and mutable REF object. The ref object has a single.value attribute that points to an internal value. Create a reactive data object based on the basic data types (string, Boolean, numeric).

// syntax import {ref} from 'vue'; Export default {setup() {const name = ref('test'); // Change the default value of name neme.value = "test "; return { name } } }Copy the code

If an object is passed to a REF, the reactive methods are called for the deep response transformation. Value is directly referenced by data name in the view.

{{ name }}
Copy the code

6.3 toRefs

Function: Reactive data objects created by Reactive support es6 deconstruction assignment while maintaining the reactive nature

Import {reactive,toRefs} from 'vue' export default {setup() {const {name,age,sex} = toRefs(reactive({ Name: 'test ', age: 18, sex:' female '})); return { name, age, sex } } }Copy the code

6.4 the computed

There are two ways to use a responsive computed API:

  1. Pass in a getter function that returns a ref object that cannot be manually modified by default.
const count = ref(1) const plusOne = computed(() => count.value + 1) console.log(plusOne.value) // 2 plusOne.value++ // Error!Copy the code
  1. Passing in a possessionget 和 setFunction to create a calculated state that can be manually modified.
const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: (val) => {
    count.value = val - 1
  },
})

plusOne.value = 1
console.log(count.value) // 0
Copy the code
  1. The type definition
// Read-only function computed<T>(getter: () => T): Readonly<Ref<Readonly<T>>> // Movable function computed<T>(options: {get: () => T set: (value: T) => void }): Ref<T>Copy the code

6.5 watch

The Watch API is exactly equivalent to 2.x this.$watch (and the corresponding option in Watch). Watch needs to listen for specific data sources and perform side effects in callback functions. The default is lazy, meaning that callbacks are executed only when the source changes are being listened for.

  • contrastwatchEffect.watchAllow us to:

    • Lazy execution side effects;
    • Make it clearer which state changes trigger the listener restart side effect;
    • Access values before and after listening state changes.
  • Listening to a single data source

The listener’s data source can be a getter function with a return value, or it can be ref:

Const state = reactive({count: 0}) watch(() => state.count, (count, prevCount) => {/*... Const count = ref(0) watch(count, (count, prevCount) => {/* prevCount, prevCount, prevCount, prevCount, prevCount, prevCount, prevCount, prevCount, prevCount, prevCount, prevCount, prevCount, prevCount, prevCount) * /})Copy the code
  • Listening to multiple data sources

Watcher can also use arrays to listen for multiple sources at the same time:

watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
  /* ... */
})
Copy the code
  • withwatchEffectThe act of sharing

Watch and watchEffect behave the same in stopping listening, clearing side effects (onInvalidate is passed in as the third argument to the callback accordingly), side effect refresh timing, and listener debugging.

7. Code segmentation

Code split Options API convention:

  • Set the receive parameters in props
  • Set variables in data
  • Set calculation properties in computed
  • Set the listening properties in Watch
  • Set event methods in Methods

You’ll notice that the Options APi dictates where we should do what, which in turn forces us to split code to some extent.

Now with the Composition API, this is no longer the convention, so the organization of code is very flexible, and our control code can be written inside the Setup