一、composition API的简单介绍
Composition API也叫组合式API,是Vue3.x的新特性
通过创建Vue组件,我们可以将接口的可重复部分及其功能提取到可重用的代码段中。仅此一项就可以使我们的应用程序在可维护性和灵活性方面走的更远。然而,我们的经验已经证明,光靠这一点可能是不够的,尤其是当你的应用程序变得非常大的时候——想想几百个组件。在处理如此大的应用程序时,共享和重用代码变得尤为重要。
通俗的讲:
没有Composition API之前vue相关业务的代码需要配置到option的特定的区域,中小型项目是没有问题的,但是在大型项目中会导致后期的维护性比较复杂,同时代码可复用性不高。Vue3.x中的composition-api就是为了解决这个问题而生的。
composition-api提供了以下几个函数:
- setup
- ref
- reactive
- watchEffect
- watch
- computed
- toRefs
- 生命周期的hooks
注意:所有的组合式API都要写在setup函数里面
setup ref reactive toRefs 使用
<template>
<div>
{{title}}
<br>
{{userinfo.username}} --- {{userinfo.age}}
<br>
<button @click="getUsername">获取username</button>
<br>
<button @click="getTitle">获取title</button>
<br> <br>
{{description}}
<br>
<input type="text" v-model="description">
</div>
</template>
<script>
import {ref, reactive, toRefs} from 'vue'
export default {
name: "Home",
setup() {
// ref 定义响应式数据 字符串 number bool 数组
// reactive 定义响应式数据 定义对象
var title = ref("我是一个标题");
var userinfo = reactive({
username: "zs",
age: 18
});
// 想让标签直接使用里面的key,需要使用toRefs
var article = reactive({
description: "我是一个描述",
click: 200
});
// 定义方法
// 获取reactive定义的数据
var getUsername = () => {
alert(userinfo.username);
};
// 获取ref定义的数据
var getTitle = () => {
alert(title.value);
};
// 修改reactive定义的数据
var setUsername = () => {
userinfo.username = "lisi";
};
// 修改ref定义的数据
var setTitle = () => {
title.value = "修改ref定义的title"
};
// 返回,这样才能被上面标签使用
return {title, userinfo, getUsername, getTitle, setUsername, setTitle, ...toRefs(article)}
},
data() {
return {
msg: "我是Home组件"
}
},
components: {}
}
</script>
<style lang="scss" scoped>
.home {
padding: 20px;
}
div {
text-align: center;
padding: 40px;
}
</style>
computed使用
<template>
<div>
<h2>获取用户信息</h2>
<input type="text" v-model="firstName" placeholder="firstName"/> <br>
<input type="text" v-model="lastName" placeholder="lastName"/> <br>
{{fullName}}
</div>
</template>
<script>
import {reactive, toRefs, computed} from 'vue'
export default {
name: "Login",
setup() {
var userinfo = reactive({
firstName: "",
lastName: ""
});
var fullName = computed(() => {
return userinfo.firstName + " " + userinfo.lastName;
});
return {...toRefs(userinfo), fullName}
},
}
</script>
<style scoped>
</style>
watchEffect watch props 使用
<template>
<div>
search
num --- {{num}}
count --- {{count}}
<hr>
<input type="text" v-model="keyword"/> <br>
{{keyword}}
<hr>
msg: {{msg}}
</div>
</template>
<script>
// watchEffect
// import {reactive, toRefs, watchEffect} from 'vue'
//
// export default {
// name: "Search",
// setup() {
// let data = reactive({
// num: 1,
// count: 1
// });
// // 没办法指定要监视的数据
// watchEffect(() => {
// // 这里面用了什么,就表示监视了什么,所以监视了,num 和 data
// console.log(`num=${data.num}`);
// console.log(`count=${data.count}`);
// }
// );
//
// // 定时器
// setInterval(() => {
// data.count++;
// }, 1000);
// return {...toRefs(data)}
// }
// }
// watch
import {ref, reactive, toRefs, watch} from 'vue'
export default {
name: "Search",
props: ["msg"],
setup(props) {
// 获取父组件传过来的值msg
console.log(props.msg);
let data = reactive({
num: 1,
count: 1
});
// 指定监视的数据data
watch(data, () => {
console.log(`num=${data.num}`);
}
);
// 定时器
setInterval(() => {
data.num++;
}, 1000);
let keyword = ref("");
// 还可以获取新数据和老数据
watch(keyword, (newData, oldData) => {
console.log(newData, oldData);
});
return {...toRefs(data), keyword}
}
}
</script>
<style scoped>
</style>
provide 和 inject
非组合式api中的用法(无法动态改变)
App.vue 里 注册 组件 Home.vue , Home.vue里注册Location.vue
把App.vue里的值 传递给 Location.vue
App.vue
<template>
<!--3.使用组件-->
<Home></Home>
</template>
<script>
// 1.引入组件
import Home from "./components/Home";
export default {
data() {
return {
msg: "App根组件"
}
},
// 2.挂载组件
components: {
Home
},
// 提供一些数据
provide() {
return {
title: "App组件title",
userinfo: {
username: "zs",
age: 18
}
}
}
}
</script>
<!-- scoped 表示css是一个局部作用域-->
<style lang="scss" scoped>
h2 {
text-align: center;
}
</style>
Location.vue
<template>
<div>
location -- {{title}} <br>
{{userinfo.username}} --- {{userinfo.age}}
</div>
</template>
<script>
export default {
name: "Location",
// 注入,app组件提供的数据 key
inject: ["title", "userinfo"]
}
</script>
<style scoped>
</style>
组合式api中的用法(数据可以动态改变)
App.vue
<template>
<!--3.使用组件-->
<Home></Home>
<button @click="setTitle">修改title</button>
{{title}}
</template>
<script>
// 1.引入组件
import Home from "./components/Home";
import {ref, provide} from "vue"
export default {
name: "App",
setup() {
let title = ref("我是App组件里的title");
// 提供title
provide("title", title);
// 修改title
let setTitle = () => {
title.value = "我是修改后的App组件里的title";
};
return {title, setTitle}
},
components: {
Home
}
}
</script>
<!-- scoped 表示css是一个局部作用域-->
<style lang="scss" scoped>
h2 {
text-align: center;
}
</style>
Location.vue
<template>
<div>
Location
{{title}}
</div>
</template>
<script>
import {inject} from 'vue';
export default {
name: "Location",
setup() {
let title = inject("title");
return {title}
}
}
</script>
<style scoped>
</style>