Vue 3 中引入的一种新的编写 Vue 组件的方式,可以将 2.x 中与组件逻辑相关的选项以 API 函数的形式重新设计。
在说 Vue3 之前,我们先看看 Vue2 项目中是如何编写逻辑代码的,
新建一个组件
<template>
<div></div>
</template>
<script>
export default {
name: "demo",
props: {},
data() {
return {};
},
created() {},
watch: {},
computed: {},
methods: {}
};
</script>
<style></style>
每个属性都有自己的功能,比如 data 定义数据、methods 中定义方法、computed 中定义计算属性、watch 中监听属性改变,小项目中这种方式确实能带来很大的便利,但是当我们组件变得更大,更复杂时,逻辑会不断增长,那么同一个功能的逻辑就会被拆分的很分散。尤其是对于后面接手的同事,可读性会很低,很难理解。一个功能会跳到多个地方,比较容易出差错,而且后期维护会很复杂。
是不是可以将一个功能点涉及到的数据和逻辑组织到一起,Composition API 就这么诞生了,它很好的解决了上面的问题。接下来认识下 Composition API,由于对 TS 支持更友好,所以 demo 用 ts 做示例
<template>
<div>
<a-button type="primary" @click="getValue(22)">Primary Button</a-button>
<a-input v-model:value="count"></a-input>
<div>{{ count }}</div>
<div>{{ x }}-{{ y }}</div>
<a-button @click="add">点击</a-button>
<div>{{ counter.count }}</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { postLogin } from "@/api/user";
import { useMouse } from "@/hooks/main";
import { useCounterStore } from "@/store/modules/counter";
defineProps<{ msg: string }>();
// 获取鼠标位置信息
const { x, y } = useMouse();
const counter = useCounterStore();
function add() {
counter.count++;
counter.$patch({ count: counter.count });
counter.increment();
}
// 获取数据
function getdata(title?: string) {
postLogin({ username: "22", password: "33" })
.then(res => {
console.log(res);
})
.catch(err => {
console.log("0000");
});
}
// 获取值
const count = ref(0);
function getValue(value?: any): void {
count.value = value;
}
</script>
<style scoped lang="less">
.read-the-docs {
color: #888;
}
.vue {
.vue-child {
font-size: 40px;
background: @main-color-theme1;
}
}
</style>
代码中我们可以看到,少了一些选项,功能点逻辑更加集中,看不懂没关系,这里只是演示,后面会详细讲解,这篇文章主要讲解 Composition API 的 setup 函数
一 setup 函数
setup 其实就是组件的另外一个选项,只不过这个选项强大到我们可以使用它来替代之前所编写的大部分其他选项,比如:methods、computed、data、生命周期等选项。
参数
props:父组件传递过来的属性
context:是一个普通的 JavaScript 对象,它暴露三个组件的 property
props
因为 props 是响应式的,你不能使用 ES6 解构,因为它会消除 prop 的响应性。如果需要解构 prop,可以通过使用 setup 函数中的 toRefs 来安全地完成此操作。
Vue3.0 使用
<script>
export default {
setup (props) {
return {}
}
}
</script>
Vue3.2 使用
<script setup>
export default {
const props = defineProps({
treeCode: String,
});
}
</script>
script setup 是一种编译时语法糖,可在 SFC 内使用 Composition API 时极大地提升工作效率。
context
里面包含有三个属性 attrs、slots 和 emit
(1)attrs:里面包含了所有的非 props 属性。
(2)slots:父组件传递过来的插槽。
(3)emit:当我们组件内部需要发出事件时会用到 emit。
Vue3.0 使用
<script>
export default {
setup (props.{attrs,slots,emit}) {
return {}
}
}
</script>
Vue3.2 使用
<script setup>
export default {
// defineProps
const props = defineProps({
treeCode: String,
});
// defineEmits
const emit = defineEmits(['on-confirm'])
// useSlots
const slots = useSlots()
}
</script>
在 script setup 使用 slots 和 attrs 的情况应该是很比较少见的,大部分人是(SFC)模式开发,在 template 通过 slot 标签就可以渲染插槽,可以在模板中通过 $slots 和 $attrs 来访问它们。主要在 JSX /TSX 使用比较多。
this
setup 不可以使用 this
setup() 自身并不含对组件实例的访问权,即在 setup() 中访问 this 会是 undefined。我们可以理解为:this未指向当前的组件实例,在setup被调用之前,data,methods,computed等都没有被解析,但是组件实例确实在执行setup函数之前就已经被创建好了。