一、Composition API优势
相对于vue2的option API Vue3的Composition API设计更有优势
Composition(组合式)Api 功能分组
Composition(组合式)Api 功能导入复用
组合式Api 所解决的问题
(1) 更好的代码组织结构
(2) 相同的代码逻辑可以进行复用
home.vue 3种方式递进升级
<template>
<div class="home">
<div>
<p>{{ name }}</p>
<button @click="getName">姓名</button>
</div>
<div>
<p>{{ age }}</p>
<button @click="getAge">年龄</button>
</div>
</div>
<HomeB></HomeB>
</template>
<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";
import HomeB from "./HomeB.vue";
// import { ref } from "vue";
import { useName, useAge } from "./user";
export default {
name: "Home",
setup() {
// 1.Composition(组合式)Api
// const people = {
// name: "yusir",
// age: 18,
// };
// const name = ref("");
// const getName = () => {
// name.value = people.name;
// };
// const age = ref("");
// const getAge = () => {
// age.value = people.age;
// };
// return {
// name,
// getName,
// age,
// getAge,
// };
/* ------------------------ */
// 2.Composition(组合式)Api 功能分组
// const people = {
// name: "yusir",
// age: 18,
// };
// return {
// ...useName(people), //展开运算符
// ...useAge(people),
// };
// function useName(people) {
// const name = ref("");
// const getName = () => {
// name.value = people.name;
// };
// return {
// name,
// getName,
// };
// }
// function useAge(people) {
// const age = ref("");
// const getAge = () => {
// age.value = people.age;
// };
// return {
// age,
// getAge,
// };
// }
/* ------------------------ */
// 3.Composition(组合式)Api 功能导入复用
// 组合式Api 所解决的问题
// (1) 更好的代码组织结构
// (2) 相同的代码逻辑可以进行复用
const people = {
name: "yusir",
age: 18,
};
return {
...useName(people), //展开运算符
...useAge(people),
};
},
components: {
HelloWorld,
HomeB,
},
};
</script>
HomeB.vue
<template>
<div class="home">
<div>
<p>{{ name }}</p>
<button @click="getName">姓名</button>
</div>
<div>
<p>{{ age }}</p>
<button @click="getAge">年龄</button>
</div>
</div>
</template>
<script>
import { useName, useAge } from "./user";
export default {
name: "HomeB",
setup() {
const people = {
name: "yusirxiaer",
age: 19,
};
return {
...useName(people), //展开运算符
...useAge(people),
};
},
};
</script>
<style lang='less' scoped></style>
user.js
import {
ref
} from 'vue'
export function useName(people) {
const name = ref("");
const getName = () => {
name.value = people.name;
};
return {
name,
getName,
};
}
export function useAge(people) {
const age = ref("");
const getAge = () => {
age.value = people.age;
};
return {
age,
getAge,
};
}
二、setup 入口函数
1.组件创建之前被调用
setup 先于created执行,this指向windows
created()里打印的this 是proxy对象 指向组件实例
setup函数参数
Props Context (看HomeB子组件)
Context JavaScript对象
- context.attrs: Attribute属性(非响应式对象)非props数据
- context.slots: 插槽(非响应式对象)
- context.emit: 触发事件的方法 === this.$emit
2.this不会只指向当前组件实例
3.返回值
返回一个对象,对象的属性可以直接在模板中进行使用(就像Vue2使用data和methods一样)
看代码例子
Home.vue
<template>
<HomeB :title="title" desc="父组件传递过来的普通属性" @update="update">
<h1>普通的匿名插槽</h1>
<h2>{{ title }}</h2>
</HomeB>
</template>
<script>
// @ is an alias to /src
import HomeB from "./HomeB.vue";
export default {
name: "Home",
setup() {
},
data() {
return {
title: "父组件的title",
};
},
created() {
console.log("created()打印this");
console.log(this);
},
methods: {
update(newTitle) {
this.title = newTitle;
},
},
components: {
HomeB,
},
};
</script>
HomeB.vue
<template>
<div class="homeB">
</div>
</template>
<script>
export default {
name: "HomeB",
props: {
title: {
type: String,
required: true,
},
},
setup(props, { attrs, slots, emit }) {
console.log("props:", props);
console.log("Attribute (非响应式的对象):", attrs);
console.log("插槽:", slots.default());
emit("update", "子组件更新数据的事件");
},
};
</script>
<style lang='less' scoped></style>