## 一、setup语法糖简述 在CompositionAPI的setup函数中声明的数据、函数等内容,都需要通过return对外暴露,才能被组件的视图模板使用,这就造成了书写上的不方便。于是,Vue官方推出了新的setup语法糖,用来代替setup函数与返回属性及注册组件。 #### 1、基本结构 ```html ``` #### 2、修改`CompositionAPI.vue` ```html 父组件 我是一个DOM对象 change 隐藏/显示子组件 子组件 ``` ## 二、setup语法糖基本用法 #### 1、获取父组件传递的参数 在setup语法糖中无法直接去定义组件setup函数以外的属性,可以使用`defineProps({})`来获取`props`对象,相当于是获取setup中的`props`参数。 ```html ``` #### 2、子组件向父组件传值 可以使用`defineEmits({'函数名',...})`来获取`emits`函数对象,通过`emits('函数名',参数值)`来进行传值 ```html 给父组件传值 ``` ## 三、用setup语法糖重写TodoList #### 1、修改`TodoList.vue` ```html TodoList ``` #### 2、修改`DoList.vue` ```html ``` #### 3、修改`AddNew.vue` ```html 添加 ``` Loading... ## 一、setup语法糖简述 在CompositionAPI的setup函数中声明的数据、函数等内容,都需要通过return对外暴露,才能被组件的视图模板使用,这就造成了书写上的不方便。于是,Vue官方推出了新的setup语法糖,用来代替setup函数与返回属性及注册组件。 #### 1、基本结构 ```html <script setup> <!-- 组合式API代码 --> </script> ``` #### 2、修改`CompositionAPI.vue` ```html <template> <div> <h2>父组件</h2> <span v-text="num"></span> <br> <span v-text="newNum"></span> <br> <span v-text="user"></span> <div ref="domobj">我是一个DOM对象</div> <br> <hr> <span v-text="store.state"></span> <br> <button @click="change">change</button> <hr> <button @click="show">隐藏/显示子组件</button> <h2 v-if="isShow">子组件</h2> <hello v-if="isShow" :params="{num,newNum,user}" @childMsg="getChildMsg"></hello> </div> </template> <script setup> import { ref, computed, watch, provide, onBeforeMount, onMounted, onBeforeUpdate, onUpdated } from "vue"; import Hello from "@/components/Hello.vue"; import {useStore} from "vuex"; console.log("这是setup函数"); // undefined console.log(this); const num = ref(10); const user = ref({ userId: 100, userName: "张三" }); let newNum = computed(() => { return num.value * num.value; }); const isShow = ref(true); // 声明响应式数据去绑定DOM对象 let domobj = ref(null); // 获取store对象 const store = useStore(); // watch监听普通数据 watch(num, (newValue, oldValue) => { console.log("watch监听1"); console.log(newValue, oldValue); }); // watch监听对象属性 watch(() => { return user.value.userName }, (oldValue, newValue) => { console.log("watch监听2"); console.log(newValue, oldValue); }); // 挂载前 onBeforeMount(() => { console.log("父组件onBeforeMount"); }); // 挂载后 onMounted(() => { // 获取DOM对象 console.log(domobj); console.log("父组件onMounted"); }); // 数据更新前 onBeforeUpdate(() => { console.log("父组件onBeforeUpdate"); }); // 数据更新后 onUpdated(() => { console.log("父组件onUpdated"); }); function change() { num.value++; // 引用式数据可直接修改其内部值 user.value.userName = "李四"; } function getChildMsg(msg) { alert(msg); } function show() { isShow.value = !isShow.value; } provide('msg', user); </script> <style scoped> </style> ``` ## 二、setup语法糖基本用法 #### 1、获取父组件传递的参数 在setup语法糖中无法直接去定义组件setup函数以外的属性,可以使用`defineProps({})`来获取`props`对象,相当于是获取setup中的`props`参数。 ```html <template> <div> <span v-text="params.num"></span><br> <span v-text="params.newNum"></span><br> <span v-text="params.user"></span><br> <hr> <GrandSon></GrandSon> </div> </template> <script setup> import {onBeforeUnmount, onUnmounted} from "vue"; import GrandSon from "@/components/GrandSon.vue"; const props = defineProps({ params: Object }); const context = defineEmits({ }) console.log(props); // 卸载挂载前 onBeforeUnmount(() => { console.log("子组件onBeforeUnmount"); }); // 卸载挂载后 onUnmounted(() => { console.log("子组件onUnmounted"); }); </script> <style scoped> </style> ``` #### 2、子组件向父组件传值 可以使用`defineEmits({'函数名',...})`来获取`emits`函数对象,通过`emits('函数名',参数值)`来进行传值 ```html <template> <div> <span v-text="params.num"></span><br> <span v-text="params.newNum"></span><br> <span v-text="params.user"></span><br> <button @click="sendMsg">给父组件传值</button> <hr> <GrandSon></GrandSon> </div> </template> <script setup> import {onBeforeUnmount, onUnmounted} from "vue"; import GrandSon from "@/components/GrandSon.vue"; const props = defineProps({ params: Object }); //获取emits函数对象 const emits = defineEmits(['childMsg']) console.log(props); onBeforeUnmount(() => { console.log("子组件onBeforeUnmount"); }); onUnmounted(() => { console.log("子组件onUnmounted"); }); //给父组件传值 function sendMsg() { emits("childMsg", "这是给父组件传的值"); } </script> <style scoped> </style> ``` ## 三、用setup语法糖重写TodoList #### 1、修改`TodoList.vue` ```html <template> <div> <h1>TodoList</h1> <AddNew @submitNew="addNewItem"></AddNew> <DoList :list="todoList" @handleJudge="judgeItem"></DoList> <hr/> <DoList :list="doneList" :listType="true" @handleDelete="deleteItem"></DoList> </div> </template> <script setup> import {ref} from "vue"; import AddNew from "@/components/AddNew.vue"; import DoList from "@/components/DoList.vue"; const todoList = ref([]); const doneList = ref([]); function addNewItem(newItem) { todoList.value.unshift(newItem); } function deleteItem(index) { doneList.value.splice(index, 1); } function judgeItem(index) { doneList.value.unshift(todoList.value.splice(index, 1)[0]); } </script> <style scoped> </style> ``` #### 2、修改`DoList.vue` ```html <template> <div> <ol reversed> <li v-for="(item,index) in list" :key="index" @click="judgeItem(index)"> <span v-text="item"></span> </li> </ol> </div> </template> <script setup> const props = defineProps({ list: { type: Array, required: true }, listType: { type: Boolean, default: false } }) const emits = defineEmits(['handleDelete','handleJudge']) function judgeItem(index) { if (props.listType) { emits('handleDelete', index); return; } emits('handleJudge', index); } </script> <style scoped> ol { margin-bottom: 20px; } ol li { cursor: pointer; } </style> ``` #### 3、修改`AddNew.vue` ```html <template> <div> <input type="text" v-model="newItem"> <button @click="handleAdd">添加</button> </div> </template> <script setup> import {ref} from "vue"; const newItem = ref(''); const emits = defineEmits(['submitNew']) function handleAdd() { if (newItem.value === '') { alert("添加的内容不能为空"); return; } emits('submitNew', newItem.value); newItem.value = ''; } </script> <style scoped> input { outline: none; width: 300px; height: 30px; border: solid 1px #999; border-radius: 5px; padding-left: 10px; } button { border: none; outline: none; width: 80px; height: 36px; background-color: #42b983; border-radius: 10px; margin-left: 10px; color: #fff; } button:hover { background-color: #34e590; } </style> ``` 最后修改:2025 年 10 月 31 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 👆请简单粗暴地爱我。