Vue3 script setup syntax sugar, super cool experience

Keywords: Vue

catalogue

brief introduction

The < script setup > syntax sugar is not a new function module. It only simplifies the writing of return in the previous composition API and has better runtime performance.

In the setup function: all ES module exports are considered to be values exposed to the context and included in the setup() return object. Compared with the previous writing method, the grammar becomes simpler after use.

You don't have to worry about the learning cost of setup syntax sugar. It is a simplification of combinatorial API and has no new knowledge points. You only need to know some usage and subtle differences, even easier than writing setup() before!

The usage is extremely simple. You only need to add the setup keyword to the script tag. Example:

<script setup>

</script>

Note: because the setup syntax sugar is a motion officially determined by vue3.2, the version of vue3.2 is really suitable for the setup syntax sugar.

1. Properties and methods need not be returned and can be used directly

Previously, the use of responsive data was:

<template>
	{{msg}}
</template>

<script>
import { ref } from 'vue'
export default {
	setup () {
		const msg = ref('hello vue3');
		return {
			msg
		}
	}
}
</script>

Now use the setup syntax instead of return and setup functions, just define them in < script setup >:

<template>
	{{msg}}
</template>

<script setup>
import { ref } from 'vue'
const msg = ref('hello vue3');
</script>

reactive, computed, can also be used:

<template>
	<div>{{msg}}</div>
	<div>{{obj.a}}</div>
	<div>{{sum}}</div>
</template>

<script setup>
import { ref, reactive, computed } from 'vue'

const msg = ref('hello vue3');

const obj = reactive({
	a: 1,
	b: 2
})

const sum = computed(() => {
	return obj.a + 3;
});
</script>

2. Automatic component registration

In script setup, the imported components can be used directly without registering through components, and the name of the current component cannot be specified. It will automatically focus on the file name, that is, there is no need to write the name attribute. Example:

<template>
	<Child />
</template>

<script setup>
import Child from '@/components/Child.vue'
</script>

3. Component data transfer (props and emits)

props and emits use the definemits and defineProps methods in the syntax sugar:

Subcomponent Child.vue:

<template>
	<div @click="toEmits">Child Components</div>
</template>

<script setup>
// Definemits and defineprops can be used directly without importing
const emits = defineEmits(['getChild']);
const props = defineProps({
	title: {
		type: String,
		defaule: 'defaule title'
	}
});

const toEmits = () => {
	emits('getChild', 'child value') // Pass data to parent component
}

// Get the data passed by the parent component
console.log(props.title); // parent value
</script>

Parent component Home.vue:

<template>
	<Child @getChild="getChild" :title="msg" />
</template>

<script setup>
import { ref } from 'vue'
import Child from '@/components/Child.vue'
const msg = ref('parent value')
const getChild = (e) => {
	// Receive data from parent component
	console.log(e); // child value
}
</script>

4. Get slots and attrs

You can get slots and attrs from the context through useContext. However, after the proposal was formally adopted, the syntax was abolished and divided into useAttrs and useSlots. Example:

// used
<script setup>
  import { useContext } from 'vue'

  const { slots, attrs } = useContext()
</script>

// new
<script setup>
  import { useAttrs, useSlots } from 'vue'
  
  const slots = useSlots();
  const attrs = useAttrs();
  console.log(attrs.dataId); // View the custom properties passed from the parent component
</script>

5. Define exposure attribute

The components of < script setup > do not expose any internally declared attributes to the outside by default.
If there are some attributes to be exposed, you can use define expose

Subcomponent Child.vue:

<template>
	{{msg}}
</template>

<script setup>
import { ref } from 'vue'

let msg = ref("Child Components");
let num = ref(123);

// defineExpose can be used directly without importing
defineExpose({
	msg,
	num
});
</script>

Parent component Home.vue:

<template>
	<Child ref="child" />
</template>

<script setup>
import { ref, onMounted } from 'vue'
import Child from '@/components/Child.vue'

let child = ref(null);

onMounted(() => {
	console.log(child.value.msg); // Child Components
	console.log(child.value.num); // 123
})
</script>

Posted by StewardManscat on Thu, 04 Nov 2021 13:39:05 -0700