一. 概述
在Vue2
时期,组件里定义的各类变量、方法、计算属性等是分别存放到data
、methods
、computed
等选项里,这样编写的代码不便于后期的查阅,查找一个业务逻辑需要在各个选项来回切换。vue3.0
组合式APIsetup
函数的推出就是为了解决这个问题,它让我们的逻辑关注点更加集中,语法也更加精简,但是当我们在使用vue3.0
的语法就构建组件的时候,总是需要把外面定义的方法变量必须要return出去才能在,比较麻烦一些.
vue3.2
语法糖的出现以及一些新增的API,让我们的代码进一步简化。【学习视频分享:vue视频教程、web前端视频】
【资料图】
什么是语法糖?
语法糖(英语:Syntactic sugar)是由英国计算机科学家彼得·兰丁发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。
Vue3.2
语法糖
来看下vue3.0
与vue3.2
的单文件组件(SFC,即.vue 文件)的结构对比
vue3.0
组件 <script>export default { components: { }, props: { }, setup () { return {} }}</script>
登录后复制
vue3.2
组件 <script setup>import MyTestVue from "./MyTest.vue";import { ref } from "vue";const title = ref("测试一下")const changeTitle = () => { title.value = "Hello,World"}</script>
登录后复制
对比vue3.0
与vue3.2
版本的组件模板,最主要的变化是3.2中没有了setup
函数,而是把它放在了script标签中。
我们定义的属性和方法也不用在return中返回,直接就可以用在模板语法中...
这些是直观的变化,接下来我们学习具体的用法。
二.使用介绍
1.组件注册
vue3.0
中使用组件,需要使用 components 选项来显式注册:
<script>import ComponentA from "./ComponentA.js"export default { components: { ComponentA }, setup() { // ... }}</script>
登录后复制
vue3.2
<script setup>
的单文件组件中,导入的组件可以直接在模板中使用,组件会自动注册,并且无需指定当前组件的名字,它会自动以文件名为主,也就是不用再写name属性了。
<script setup>import ComponentA from "./ComponentA.vue"</script>
登录后复制
2.Props 声明
在vue3.0
中,prop
可以使用props
选项来声明
<script>export default { props: ["foo"], // 或者用这种方式指类型与默认值 // props: { // foo:{ // type: String, // default: "" // }, // }, setup(props) { // setup() 接收 props 作为第一个参数 console.log(props.foo) }}</script>
登录后复制
vue3.2
组件中,props
可以使用defineProps()
宏来声明
<script setup>const props = defineProps(["foo"])// 或者const propsOther = defineProps({ title: String, likes: Number})console.log(props.foo)</script>
登录后复制
3.计算属性
我们一般使用计算属性来描述依赖响应式状态的复杂逻辑。说白了就是这个计算属性的值依赖于其他响应式属性的值,依赖的属性发生变化,那么这个计算属性的值就会进行重新计算。
<script setup>import { ref, computed } from "vue"const firstName = ref("John")const lastName = ref("Doe")const fullName = computed({ // getter get() { return firstName.value + " " + lastName.value }, // setter set(newValue) { // 注意:我们这里使用的是解构赋值语法 [firstName.value, lastName.value] = newValue.split(" ") }})</script>
登录后复制
当调用fullName.value = "John Doe"
时,setter
会被调用,而firstName
和 lastName
会被更新,在vue3.2
中我们可以直接在标签中使用它,不在需要return返回。
4. watch
在组合式API中,我们可以使用watch
函数在每次响应式状态发生变化时触发回调函数,watch
的第一个参数可以是不同形式的“数据源”:它可以是一个ref
(包括计算属性)、一个响应式对象、一个 getter
函数、或多个数据源组成的数组:watch()
是懒执行的:仅当数据源变化时,才会执行回调,例如:
<script setup>import { ref,watch } from "vue";const props = defineProps({ title: String, itemList: { type: Array, default: () => [{ text: "title", value: 0 }] }})watch(() => props.itemList.length,(newValue,oldValue) => { console.log("newValue===",newValue); console.log("oldValue===",oldValue);})</script>
登录后复制
<script setup>import { ref,watch } from "vue";...watch(() => props.itemList,(newValue,oldValue) => { console.log("newValue===",newValue); console.log("oldValue===",oldValue);},{deep:true})</script>
登录后复制
watch
也可以同时监听多个属性:
<script setup>import { ref,watch } from "vue";const props = defineProps({ title: String, itemList: { type: Array, default: () => [{ text: "title", value: 0 }] }})// 同时监听多个属性watch(() => [props.itemList,props.title],(newValue,oldValue) => { console.log("newValue===",newValue); console.log("oldValue===",oldValue);},{deep:true}) </script>
登录后复制
5. watchEffect()
与watch()
的懒执行不同的是,watchEffect()
会立即执行一遍回调函数,如果这时函数产生了副作用,Vue
会自动追踪副作用的依赖关系,自动分析出响应源。上面的例子可以重写为:
<script setup> ...watchEffect(() => { console.log("itemList===",props.itemList.length); console.log("title===",props.title);})</script>
登录后复制
这个例子中,回调会立即执行。在执行期间,它会自动追踪props.itemList.length
作为依赖(和计算属性的行为类似)。每当传入的itemList.length
变化时,回调会再次执行。
如果要清除watchEffect()
的的监听,只需要显示的调用watchEffect()
的返回函数就可以了,例如:
<script setup> ...const stopEffect = watchEffect(() => { console.log("itemList===",props.itemList.length); console.log("title===",props.title);})stopEffect()</script>
登录后复制
6.组件的事件调用
6.1 子组件调用父组件的方法
vue3.0
中如果我们的子组件触发父组件的方法,我们的做法:
子组件<script>export default { emits: ["inFocus", "submit"], setup(props, ctx) { ctx.emit("submit",params) }}// 或者将可以将emit解构使用export default { setup(props,{emit}) { emit("submit",params) }}</script>父组件