Syntactic sugar for Vue3 script setup

script setup syntactic sugar

1. Combined API: setup()

In the Composition API series of Vue 3, a brand new setup function is introduced . It is a component option that is executed before the component is created. Once the props are parsed, it serves as the entry point of the composition API.
The setup option is a function that takes props and context , and we expose everything that setup returns to the rest of the component (computed properties, methods, lifecycle hooks, etc.) as well as the component's template.

<script>
// 这是一个基于 TypeScript 的 Vue 组件
import { defineComponent } from 'vue'

export default defineComponent({
  setup(props, context) {
    // 在这里声明数据,或者编写函数并在这里执行它

    return {
      // 需要给 `<template />` 用的数据或函数,在这里 `return` 出去
    }
  },
})

</script>

The new setup option is executed before the component is created and after the props are parsed, which is the entry point of the combined API.
Note:
① You should avoid using this in setup, because it will not find the component instance. The call to setup happens before data properties, computed properties or methods are parsed, so they cannot > be accessed in setup.
②In the script tag added with setup, we don’t need to declare and method. This way of writing will automatically expose all top-level variables and functions to the template (template) for use. Here we emphasize the sentence "exposing to the template is not the same as exposing to the
outside world
.
"
Component lifecycle
Changes in the lifecycle of Vue can be intuitively understood from the following table:

Vue 2 life cycle Vue 3 life cycle
beforeCreate setup -- executed before component creation
created setup – executed after the component is created
beforeMount onBeforeMount – executed before the component is mounted on the node
mounted onMounted – executed after the component is mounted
beforeUpdate onBeforeUpdate – executed before the component is updated
updated onUpdated – Executed after the component is updated
beforeDestroy onBeforeUnmount – executed before the component is unmounted
destroyed onUnmounted – executed after the component is unmounted
errorCaptured onErrorCaptured – the hook function is activated when an exception from a descendant component is captured

The beforeCreate and created in the Vue 2 life cycle have been replaced by setup in Vue 3 .

Two, script setup syntactic sugar

It's a new syntactic sugar for Vue3, in the setup function. All ES module exports are considered values ​​exposed to the context and are included in the setup() return object. Compared with the previous way of writing, the grammar becomes simpler after use.
1. Auto-registration properties and methods do not need to return, use directly
①, script setup syntactic sugar is not a new functional module, it just simplifies the writing method of the previous composition API (compositionApi) that must return **(return)**, and has better runtime performance.
②. In the setup function: All ES module exports are considered as values ​​exposed to the context and included in the setup() return object. Compared with the previous way of writing, the grammar becomes simpler after use.
You don't have to worry about the learning cost of setup syntactic sugar, it is a simplification of the combined API, and there are no new knowledge points. You just need to understand some usage and subtle differences, even easier than writing setup() before!
The usage is also very simple, just add the setup keyword to the script tag

<script setup>
</script>

2. Using
ref in component core API Expose variables to template
ref is the most commonly used reactive API , which can be used to define all types of data , including Node nodes and components . Returns a responsive object , all values ​​are obtained through the .value property .

<template>
    <div>{
   
   {counter}}</div>
</template>
<script setup >
import { ref } from 'vue'

const counter = ref(0);//不用 return ,直接在 templete 中使用

const timer = setInterval(() => {
    counter.value++
}, 1000)

onUnmounted(() => {
    clearInterval(timer);
})
</script>

reactive
returns a reactive proxy for an object.

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

const state = reactive({
    counter: 0
})
// 定时器 每秒都会更新数据
const timer = setInterval(() => {
    state.counter++
}, 1000);

onUnmounted(() => {
    clearInterval(timer);
})
</script>
<template>
    <div>{
   
   {state.counter}}</div>
</template>

Using ref can also achieve our expected 'counter', and in the template, vue has processed it, we can use counter directly without writing counter.value

The relationship between ref and reactive:
ref is a **{value:'xxxx'} structure, value is a reactive object** The bottom layer of reactive is Proxy
, the essence of ref is also packaged with reactive, so it is also Proxy , and the essence of ref is also reactive
. ref(obj) is equivalent to reactive({value: obj}) Specify the name of the current component , and it will automatically take the file name as the main 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>

4. Define the props of the component
defineProps—>[used to receive the props from the parent component]
specify the current props type through defineProps, and obtain the props object
example of the context:

<script setup>
   // defineEmits,defineProps无需导入,直接使用
   const props = defineProps({
      title: String,
   })
</script>
<!-- 或者 -->
<script setup lang="ts"> 
    import { ref,defineProps } from 'vue';
    
    type Props={ 
        msg:string 
    }
    defineProps<Props>(); 
</script>

5. Define emit
defineEmit—>[transfer events from child components to parent components] use defineEmit to define the events contained in the current component, and execute the emit code example
through the returned context :

<script setup>
     // defineEmits,defineProps无需导入,直接使用
     const emit = defineEmits(['change','delete'])
</script>

6. defineExpose API
defineExpose —> [component exposes its own attributes]
traditional writing method, we can access the content of the child component through the ref instance in the parent component, but in the script setup , this method cannot be used. The setup is equivalent to a closure. Except for the internal template template, no one can access the internal data and methods.
Components of script setup do not expose any internally declared properties to the outside by default. If some properties need to be exposed, you can use defineExpose
Note : At present, it is found that the properties and methods exposed by defineExpose are all unknown types. If there is a method to correct the type, please add it in the comment area.
If you need to expose the data and methods in the setup , you need to use the defineExpose API . Example:

//子组件
<template>
     {
   
   {msg}}
</template>
<script setup>
import  {ref} from 'vue'
let msg = ref("Child Components");
let num = ref(123);
// defineExpose无需导入,直接使用
defineExpose({
      msg,
     num
})
</script>
//父组件
<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>

7. Parent-child component communication

//父组件
<template>
  <div class="wrapper">
     <Child :page="page"
                @pageFn="pageFn"
                ref="childRef"
     >
    <button @click="doSth1"> defineExpose</button>
  </div>
</template>

<script setup>
import {ref} from 'vue'
import Child from './Child.vue'

const childRef = ref();
const page = ref(1)
const  pageFn = (num) => {
  page.value += num
}
function doSth1() {
  console.log(childRef.value)
  childRef.value.doSth();
}
</script>

<style scoped>
div {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
</style>
//子组件
<template>
  <!--  <p>子</p>-->
  <button @click="butFn">改变page值: {
   
   { page }} </button>
</template>
<script setup>
// defineEmits,defineProps无需导入,直接使用
const props = defineProps({
    page: Number
});//接收父组件传来的值
const emit = defineEmits(["pageFn"]); //定义一个变量来接收父组件传来的方法
const butFn = () => {
   emit('pageFn', props.page)
}
function doSth(){
   console.log(333,'defineExpose');
}
defineExpose({ doSth });
// 获取父组件传递过来的数据
console.log(props.page, "parent value"); // parent value
</script>
<style scoped>
button {
  margin: 20px;
}
</style>

The child component receives the data passed by the parent component through defineProps, the child component sends information to the parent component through defineEmits definition event, and uses the defineExpose child component to pass the parent component

Guess you like

Origin blog.csdn.net/renfeideboke/article/details/129127105