Vue3.2 版本开始才能使用语法糖!
什么是 setup script
它是 Vue3 的一个新语法糖,在 setup 函数中。所有 ES 模块导出都被认为是暴露给上下文的值,并包含在 setup() 返回对象中。相对于之前的写法,使用后,语法也变得更简单。
使用方式极其简单,仅需要在 script 标签加上 setup 关键字即可。示例:
<script setup></script>
里面的代码会被编译成组件 setup() 函数的内容。这意味着与普通的 <script>
只在组件被首次引入的时候执行一次不同,<script setup>
中的代码会在每次组件实例被创建的时候执行。
组件自动注册
在 script setup 中,引入的组件可以直接使用,无需再通过 components 进行注册,并且无法指定当前组件的名字,它会自动以文件名为主,也就是不用再写 name 属性了。示例:
<template>
<Child />
</template>
<script setup>
import Child from "./Child.vue";
</script>
属性和方法无需返回
<script setup>
中无需 return 声明的变量、函数
<script setup>
//import引入的内容
import { getToday } from "./utils";
// 变量
const msg = "Hello!";
// 函数
function log() {
console.log(msg);
}
</script>
<!--在template中直接使用声明的变量、函数以及import引入的内容-->
<template>
<div @click="log">{{ msg }}</div>
<p>{{ getToday() }}</p>
</template>
使用 props
defineProps
代替 props,接收父组件传递的数据(父组件向子组件传参)
<script setup>
// import { defineProps } from "vue";
// defineProps在<script setup>中自动可用,无需导入
// 需在.eslintrc.js文件中【globals】下配置【defineProps: true】
const props = defineProps({
title: String,
});
</script>
使用 emits
defineEmit
代替 emit,子组件向父组件传递数据(子组件向外暴露数据)
<script setup>
// import { defineEmits } from "vue";
// defineEmits<script setup>中自动可用,无需导入
// 需在.eslintrc.js文件中【globals】下配置【defineEmits: true】
const emit = defineEmits(["change", "delete"]);
</script>
组件之间使用 v-model
- 子组件
<template>
<span @click="changeInfo">我叫{{ modelValue }},今年{{ age }}岁</span>
</template>
<script setup>
defineProps({
modelValue: String,
age: Number,
});
const emit = defineEmits(["update:modelValue", "update:age"]);
const changeInfo = () => {
// 触发父组件值更新
emit("update:modelValue", "Tom");
emit("update:age", 30);
};
</script>
- 父组件
<template>
<!-- v-model:modelValue简写为v-model // 可绑定多个v-model -->
<child v-model="state.name" v-model:age="state.age" />
</template>
<script setup>
import { reactive } from "vue";
// 引入子组件
import child from "./child.vue";
const state = reactive({
name: "Jerry",
age: 20,
});
</script>
获取 slots 和 attrs
可以通过useContext
从上下文中获取 slots 和 attrs。不过提案在正式通过后,废除了这个语法,被拆分成了useAttrs
和useSlots
。
<!--旧-->
<script setup>
import { useContext } from "vue";
const { slots, attrs } = useContext();
</script>
<!--新-->
<script setup>
import { useAttrs, useSlots } from "vue";
const attrs = useAttrs();
const slots = useSlots();
</script>
defineExpose API
使用 <script setup>
的组件,父组件是无法通过 ref 或者 $parent 获取到子组件的 ref 等响应数据,需要通过defineExpose
主动暴露
<script setup>
import { defineExpose } from "vue";
const a = 1;
const b = 2;
//主动暴露组件属性
defineExpose({
a,
});
</script>
在 setup 访问路由
访问路由实例组件信息:route 和 router
setup
里不能访问this
,不能再直接访问this.$router
或this.$route
。(getCurrentInstance
可以替代this
但不推荐)
使用useRoute
函数和useRouter
函数替代this.$route
和this.$router
<script setup>
import { useRouter, useRoute } from 'vue-router'
const route = useRoute()
const router = useRouter()
function pushWithQuery(query) {
router.push({
name: 'search',
query: {
...route.query,
},
})
}
<script/>
路由导航守卫
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from "vue-router";
// 添加一个导航守卫,在当前组件将要离开时触发。
onBeforeRouteLeave((to, from, next) => {
next();
});
// 添加一个导航守卫,在当前组件更新时触发。
// 在当前路由改变,但是该组件被复用时调用。
onBeforeRouteUpdate((to, from, next) => {
next();
});
</script>
生命周期
通过在生命周期钩子前面加上 “on” 来访问组件的生命周期钩子。
下表包含如何在 Option API 和 setup() 内部调用生命周期钩子
Option API | setup 中 |
---|---|
beforeCreate | 不需要 |
created | 不需要 |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
activated | onActivated |
deactivated | onDeactivated |
原型绑定与组件内使用
- main.js
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
// 获取原型
const prototype = app.config.globalProperties;
// 绑定参数
prototype.name = "Jerry";
- 组件内使用
<script setup>
import { getCurrentInstance } from "vue";
// 获取原型
const { proxy } = getCurrentInstance();
// 输出
console.log(proxy.name);
</script>
v-bind() CSS 变量注入
<template>
<span>Jerry</span>
</template>
<script setup>
import { ref, reactive } from "vue";
// prop接收样式
const props = defineProps({
border: {
type: String,
default: "1px solid yellow",
},
});
// 常量声明样式
const background = "red";
// 响应式数据声明样式
const color = ref("blue");
const style = reactive({
opacity: "0.8",
});
</script>
<style lang="scss" scoped>
span {
// 使用常量声明的样式
background: v-bind(background);
// 使用响应式数据声明的样式
color: v-bind(color);
opacity: v-bind("style.opacity");
// 使用prop接收的样式
border: v-bind("props.border");
}
</style>
标签:vue,const,setup,语法,组件,import,defineProps
From: https://www.cnblogs.com/icey-Tang/p/17009944.html