vue3学习之自定义Hooks

我爱海鲸 2024-05-31 15:29:49 前端

简介hook、usePageRouter

之前的文章:vue3学习之模块化妙用,鼠标追踪器

自定义hook

  • 什么是hook?—— 本质是一个函数,把setup函数中使用的Composition API进行了封装,类似于vue2.x中的mixin

  • 自定义hook的优势:复用代码, 让setup中的逻辑更清楚易懂。

useSum.ts中内容如下

import {ref,onMounted} from 'vue'

export default function(){
  let sum = ref(0)

  const increment = ()=>{
    sum.value += 1
  }
  const decrement = ()=>{
    sum.value -= 1
  }
  onMounted(()=>{
    increment()
  })

  //向外部暴露数据
  return {sum,increment,decrement}
}

useDog.ts中内容如下:

import {reactive,onMounted} from 'vue'
import axios,{AxiosError} from 'axios'

export default function(){
  let dogList = reactive<string[]>([])

  // 方法
  async function getDog(){
    try {
      // 发请求
      let {data} = await axios.get('https://dog.ceo/api/breed/pembroke/images/random')
      // 维护数据
      dogList.push(data.message)
    } catch (error) {
      // 处理错误
      const err = <AxiosError>error
      console.log(err.message)
    }
  }

  // 挂载钩子
  onMounted(()=>{
    getDog()
  })
	
  //向外部暴露数据
  return {dogList,getDog}
}

组件中具体使用:

<template>
  <h2>当前求和为:{{sum}}</h2>
  <button @click="increment">点我+1</button>
  <button @click="decrement">点我-1</button>
  <hr>
  <img v-for="(u,index) in dogList.urlList" :key="index" :src="(u as string)"> 
  <span v-show="dogList.isLoading">加载中......</span><br>
  <button @click="getDog">再来一只狗</button>
</template>

<script lang="ts">
  import {defineComponent} from 'vue'

  export default defineComponent({
    name:'App',
  })
</script>

<script setup lang="ts">
  import useSum from './hooks/useSum'
  import useDog from './hooks/useDog'
	
  let {sum,increment,decrement} = useSum()
  let {dogList,getDog} = useDog()
</script>

js的用法:

import {isEmptyStr,isEmptyObject,formatDateTime,isCodeTrue} from '@/utils/index.js' 请参考:vue3学习之工具方法

usePage.js:

import {ref} from 'vue'
import {isEmptyStr,isEmptyObject,formatDateTime,isCodeTrue} from '@/utils/index.js'

// 分页请求
export default function () {
	
	// 分页的基本数据
	const pageRequest = ref({
		  current: 1,
		  orders: [
		    {
		      asc: true,
		      column: ""
		    }
		  ],
		  size: 5
	})
	
	// 当前分页请求是否还有下一页
	const isNextPage = (pageObject) =>{
		if (isEmptyObject(pageObject) && isEmptyObject(pageObject.pages)) {
			return false;
		}
		if (pageRequest.value.current >= pageObject.pages) {
			return false;
		} else {
			return true;
		}
	}
	
	
	/**
	 * 分页函数
	 * page 请求参数
	 * pageRequestCallbackFunc 具体的分页请求回调
	 * status 'reset' 重置为第一页 'previous' 上一页 'next' 下一页
	 * 用法:
	 * 	 pageFunc(
			{
				taskId:taskId.value,
				// 测量状态 1 已完成 0 未完成
				progress:0
			},async (pageObject)=>{
				await groupStore.teamTestingScaleListFunc(pageObject)
			}
		)
	 */
	const pageFunc =(page,pageRequestCallbackFunc,status=null) =>{
		if (status === 'reset') {
			// 重置为第一页
			pageRequest.value.current = 1
		} else if (status === 'previous') {
			// 上一页
			if (pageRequest.value.current <= 1) {
				pageRequest.value.current = 1
			} else {
				pageRequest.value.current = pageRequest.value.current - 1	
			}
		} else if (status === 'next') {
			pageRequest.value.current = pageRequest.value.current + 1
		}
		// 分页请求数据
		let pageRequestObject = Object.assign({},pageRequest.value,page);
		// 回调具体的分页请求
		pageRequestCallbackFunc(pageRequestObject)
	}
	
	return {
		pageRequest,
		pageFunc,
		isNextPage
	}
}

usePageRouter.js:(uniapp上的使用)

import {ref} from 'vue'
import {isEmptyStr,isEmptyObject,formatDateTime,isCodeTrue} from '@/utils/index.js'

// 分页请求
export default function () {

	// 获取当前页面的page对象
	const getCurrentPageRoute = () =>{
		var pages = getCurrentPages();
		var page = pages[pages.length - 1];
		return page.route;
	}
	
	// 只有一个路由页面时,返回route页面
	const someTimeBackRoute = (route) =>{
		let pages = getCurrentPages();
		if (pages.length === 1) {
			uni.reLaunch ({
				// url:'../home/index'
				url:route
			})
			return true;
		}
		return false;
	}
	
	// 根据输入的route页面,返回route页面
	const someTimeBackPress = (route) =>{
		let pages = getCurrentPages();
		let index = 1;
		for (let i = 0 ; i < pages.length; i++) {
			var page = pages[i];
			console.log('page'+i,page.route,route)
			if (page.route === route) {
				index = pages.length - i - 1;
				uni.navigateBack({
					delta:index
				})
				return true;
			}
		}
		return false;
	}
	
	
	// 根据输入的route页面,返回route页面,如果没有找到那个页面则返回指定的defaultRoute页面
	const someTimeBackDefault = (route,defaultRoute) =>{
		let pages = getCurrentPages();
		let index = 1;
		for (let i = 0 ; i < pages.length; i++) {
			var page = pages[i];
			console.log('page'+i,page.route,route)
			if (page.route === route) {
				index = pages.length - i - 1;
				uni.navigateBack({
					delta:index
				})
				return true;
			}
		}
		uni.reLaunch ({
			// url:'../home/index'
			url:defaultRoute
		})
		return false;
	}
	
	return {
		getCurrentPageRoute,
		someTimeBackRoute,
		someTimeBackPress,
		someTimeBackDefault,
	}
}

使用:

import usePageRouter from '@/hooks/usePageRouter.js'
const {someTimeBackRoute,someTimeBackPress,someTimeBackDefault} = usePageRouter()


onBackPress((options)=>{
		return someTimeBackRoute('../home/index')
	})

someTimeBackDefault('pages/evaluation/evaluationMyTest','../home/index')

setTimeout(()=>{
				if (someTimeBackRoute('../home/index')) {
					return;
				}
				someTimeBackPress('pages/home/index')
			},0)

onBackPress((options)=>{
		if (options.from === 'navigateBack') {  
			return false;  
		}  
		if (someTimeBackRoute('../home/index')) {
			return true;
		}
	    return someTimeBackPress('pages/evaluation/evaluationMyTest')
	})

你好:我的2025