setup
The setup function is an entry function for Vue 3.
parameter
When you use the setup function, it takes two arguments:
- props
- context
Let’s take a closer look at how each parameter is used.
Props
The first argument in the setup function is 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. SRC/templatem.vue:
<template>
<div class="template-m-wrap">
counter ---> {{ counter }}
</div>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
name: 'TemplateM',
props: {
test: {
type: Object,
default: () => {
return {
name: 'haha',
}
},
},
},
setup(props) {
const counter = ref(0)
console.log('props===>', props)
return {
counter,
}
},
})
</script>
Copy the code
However, because props are reactive, you can’t use ES6 deconstruction because it eliminates the responsiveness of prop.
Let’s try deconstructing props in ES6 to see what happens:
<template>
<div class="template-m-wrap">
counter ---> {{ counter }}
<br/>
test.name ---> {{ test.name }}
<br/>
name ---> {{ name }}
</div>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
name: 'TemplateM',
props: {
test: {
type: Object,
default: () => {
return {
name: 'haha',
}
},
},
},
setup(props) {
const counter = ref(0)
console.log('props===>', props)
const {name} = props.test
return {
counter,
name
}
},
})
</script>
Copy the code
We see that the console is starting to alert:
If you need to deconstruct a prop, you can do so safely by using toRefs in the Setup function.
<template>
<div class="template-m-wrap">
counter ---> {{ counter }}
<br/>
test.name ---> {{ test.name }}
<br/>
name ---> {{ name }}
</div>
</template>
<script>
import { defineComponent, ref, toRefs } from 'vue'
export default defineComponent({
name: 'TemplateM',
props: {
test: {
type: Object,
default: () => {
return {
name: 'haha',
}
},
},
},
setup(props) {
const counter = ref(0)
console.log('props===>', props)
const {name} = toRefs(props.test)
return {
counter,
name
}
},
})
</script>
Copy the code
This time we can see the effect as follows:
context
The second argument passed to the setup function is context. Context is a plain JavaScript object that exposes the properties of three components:
<template>
<div class="template-m-wrap">
</div>
</template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
name: 'TemplateM',
props: {
test: {
type: Object,
default: () => {
return {
name: 'haha',
}
},
},
},
setup(props, context) {
console.log('props===>', props, context)
return {
}
},
})
</script>
Copy the code
We can see the effect as follows:
Context is a normal JavaScript object, that is, it is not reactive, which means you can safely use ES6 deconstruction of the context.
setup(props, { attrs, slots, emit }) {
.
}
Copy the code
Pay attention to
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.
Access the component’s property
When SETUP is executed, the component instance has not yet been created. Therefore, you can only access the following property:
props
attrs
slots
emit
In other words, you will not have access to the following component options:
data
computed
methods
Use with templates
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>
<div class="template-m-wrap" title="hhhhh">
<div>{{ readersNumber }} {{ book.title }}</div>
</div>
</template>
<script>
import { defineComponent, ref, reactive } from 'vue'
export default defineComponent({
name: 'TemplateM',
setup() {
const readersNumber = ref(0)
const book = reactive({ title: 'Vue 3 Guide' })
// expose to template
return {
readersNumber,
book,
}
},
})
</script>
Copy the code
We can see the effect as follows:
Note that refs returned from setup are automatically unwrapped when accessed in the template, so.value should not be used in the template.
Using render functions
Setup can also return a render function that directly uses reactive state declared in the same scope:
<template>
<div class="template-m-wrap" title="hhhhh">
</div>
</template>
<script>
import { defineComponent, ref, reactive, h } from 'vue'
export default defineComponent({
name: 'TemplateM',
setup() {
const readersNumber = ref(0)
const book = reactive({ title: 'Vue 3 Guide' })
// expose to template
return () => h('div', [readersNumber.value, book.title])
},
})
</script>
Copy the code
The effect is as follows:
usethis
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.