vue3的 Composition (合成) api,setup的用法

引入

Vue2的组件中,数据是写在data里面,方法写在methods里。这样子在小型的组件中是很清晰的,但是当在大型组件中,数据跟方法就会多起来,而数据与其相关联的方法就会被其他数据和方法分隔的很远,往往很难被看出它们之间的关联。因此,Vue3中就有了合成api来解决这个问题,帮助我们将有关联的数据与方法囊括起来。

setup在vue的生命周期

setup在vue的生命周期中是比 beforeCreate 还要早执行的
在这里插入图片描述

用法

在vue3组件中的 setup 选项使用 Composition API
setup 是一个函数,它会在创建组件之前执行 props ,也就是说,setup 执行时尚未创建组件实例,因此选项 this内部没有任何内容 setup 。这意味着,除了 props ,你将无法访问组件中声明的任何属性-本地状态,计算属性或方法。

export default {
    
    
	components: {
    
     RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
	props:{
    
    
		user:{
    
     type:String }
	},
	setup(props) {
    
    
		console.log(props) // { user:'' }
		return {
    
    }
	}
}

它跟 data 类似,都是返回组件中用到的函数或者方法

一个计数的例子
vue2写法

<template>
	<div>
		<h1 @click="changeEvent"> 计数:{
    
    {
    
    count}} </h1>
	</div>
</template>

<script>
export default{
    
    
	name:'App',
	data(){
    
    
		return{
    
    
			count:0
		}
	},
	methods:{
    
    
		changeEvent(){
    
    
			this.count++
		}
	}
}
 </script>

vue3的 setup 写法

ref

setup里面的基本类型变成是响应式的使用,就要把数据写在ref中

<template>
	<div>
		<h1 @click="changeEvent"> 计数:{
    
    {
    
    count}} </h1>
	</div>
</template>

<script>
import {
    
     ref } from 'vue'
export default{
    
    
	name:'App',
	data(){
    
    
		return{
    
    
		}
	},
	setup(){
    
    
		// 要放到 ref 里面才会是响应式的
		const count = ref(0)
		function changeEvent(){
    
    
			// 在这里获取 count 的值是保存到了 count.value 里的
			count.value++
		}
		return {
    
    
			count,
			changeEvent
		}
	}
}
 </script>

reactive和toRefs

setup里面的对象要响应式,使用reactive
像ref一样使用reactive,通过toRef进行转换

<template>
	<div>
		<!-- ref的方式 -->
		<h1 @click="changeEvent"> 计数:{
    
    {
    
    count}} </h1>
		<!-- reactive的方式 -->
		<h1>用户名:{
    
    {
    
    user.username}}</h1>
		<!-- toRefs的方式 -->
		<h1 @click="changeUsername">用户名:{
    
    {
    
    username}}</h1>
	</div>
</template>

<script>
import {
    
     ref,reactive,toRefs } from 'vue'
export default{
    
    
	name:'App',
	data(){
    
    
		return{
    
    
		}
	},
	setup(){
    
    
		// 要放到 ref 里面才会是响应式的
		const count = ref(0)
		function changeEvent(){
    
    
			// 在这里获取 count 的值是保存到了 count.value 里的
			count.value++
		}

		const user = reactive({
    
    
			username:'ayaan',
			age:18,
			type:'帅'
		})
		function changeUsername(){
    
    
			user.username = 'abc'
		}

		return {
    
    
			count,
			changeEvent,
			user,
			...toRefs(user),
			changeUsername
		}
	}
}
 </script>

computed、watch、watchEffect

这是setup里面的computed和watch,它们的作用和外面的computed和watch是一样的

watchEffect其实就是自动监听回调函数里面的数据改变而触发执行,而watch就是要指定监听的数据

例子:利用computed翻转username,利用watchEffect监听age改变

<template>
	<div>
		<!-- ref的方式 -->
		<h1 @click="changeEvent"> 计数:{
    
    {
    
    count}} </h1>
		<!-- reactive的方式 -->
		<h1>用户名:{
    
    {
    
    user.username}}</h1>
		<!-- toRefs的方式 -->
		<h1 @click="changeUsername">用户名:{
    
    {
    
    username}}</h1>
		<h1>翻转用户名:{
    
    {
    
    user.reverseUsername}}</h1>
	</div>
</template>

<script>
import {
    
     ref,reactive,toRefs,computed,watch,watchEffect } from 'vue'
export default{
    
    
	name:'App',
	data(){
    
    
		return{
    
    
		}
	},
	setup(){
    
    
		// 要放到 ref 里面才会是响应式的
		const count = ref(0)
		function changeEvent(){
    
    
			// 在这里获取 count 的值是保存到了 count.value 里的
			count.value++
		}

		const user = reactive({
    
    
			username:'ayaan',
			reverseUsername:computed(()=>{
    
    
				return user.username.split('').reverse().join('')
			})
			age:18,
			type:'帅'
		})
		function changeUsername(){
    
    
			user.username = 'abc'
		}
		//watchEffect回调函数里面用到了那些数据,那些数据发生改变就会触发这个回调函数
		watchEffect(()=>{
    
    
			console.log(user.age)
			console.log('当user.age发生改变时候就会执行这里')
		})
		//watch监听单个数据改变,例如下面监听count改变
		watch(count,(newValue,preValue)=>{
    
    
			console.log(newValue,preValue)
			console.log('当count发生改变时候就会执行这里')
		})
		//watch监听多个数据改变,例如下面监听count改变
		watch([count,user],(newValue,preValue)=>{
    
    
			console.log(newValue,preValue)
			console.log('当count或者user发生改变时候就会执行这里')
		})

		return {
    
    
			count,
			changeEvent,
			user,
			...toRefs(user),
			changeUsername
		}
	}
}
 </script>

setup中访问props的数据

setup函数本身会传入props参数和content参数,但是外层的props选项也不能省略

import {
    
     ref } from 'vue'
<template>
	<div>
		<!-- props的方式 -->
		<h1>用户名:{
    
    {
    
    username}}</h1>
		<h1>描述:{
    
    {
    
    description}}</h1>
	</div>
</template>

<script>
export default{
    
    
	name:'App',
	data(){
    
    
		return{
    
    
		}
	},
	setup(props,content){
    
    
		console.log(props)
		const description = ref(props.username)
		return{
    
    
			description
		}
	},
	props:['username']
}

content的内容结构如下,它可以获取到父组件传递过来的属性等数据,比如这里的class属性
在这里插入图片描述

setup里面可以用到的生命周期

除了beforeCreate,和created之外都有
它们分别是onBeforeMount,onMounted,onBeforeUpdate,onBeforeUnmount,onUnmounted

import {
    
     ref,onBeforeMount,onMounted,onBeforeUpdate,onBeforeUnmount,onUnmounted } from 'vue'
<template>
	<div>
		<!-- props的方式 -->
		<h1>用户名:{
    
    {
    
    username}}</h1>
		<h1>描述:{
    
    {
    
    description}}</h1>
	</div>
</template>

<script>
export default{
    
    
	name:'App',
	data(){
    
    
		return{
    
    
		}
	},
	setup(props,content){
    
    
		console.log(props)
		const description = ref(props.username)

		onBeforeMount(()=>{
    
    
			console.log('beforeMount')
		})
		//那个变量和生命周期息息相关的话可以写在一起附近
		onBeforeMount(()=>{
    
    
			console.log('可以使用多次onBeforeMount')
		})
		
		return{
    
    
			description
		}
	},
	props:['username']
}

通过Provide和inject将数据提供给子组件

除了使用props传值之外,还可以使用provide(提供)和inject(注入)将数据提供给子组件。

import {
    
     ref,reactive,provide } from 'vue'
<template>
	<div>
		<Student />
	</div>
</template>

<script>
import Student from './components/Student.vue'
export default{
    
    
	name:'App',
	components:{
    
     Student }
	data(){
    
    
		return{
    
    
		}
	},
	setup(props,content){
    
    
		// 提供数据
		const student = reactive({
    
    
			name:'小红',
			className:'三年6班'
		})
		// provide的参数是 key,value 的形式
		provide('student',student)
		
		return{
    
    
		}
	}
}

Student子组件内容

import {
    
     ref,reactive,inject } from 'vue'
<template>
	<div>
		<h1>学生名:{
    
    {
    
    name}}</h1>
		<h1>班级:{
    
    {
    
    className}}</h1>
	</div>
</template>

<script>
export default{
    
    
	name:'Student',
	data(){
    
    
		return{
    
    
		}
	},
	setup(props,content){
    
    
		const student = reject('student')
		return{
    
    
			...student
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_44679078/article/details/109909201