Vue3常用的hooks方法

249 阅读2分钟

本地存储方法

我们经常需要使用localStorageAPI,一个好用的可组合函数封装将帮助我们更好地使用它

import { customRef } from "vue"

/**
 * @description 本地存储方法封装
 * @param key 键名
 * @param initValue	初始值 
 * @returns value
 */
export const useLocalStorage = (key: string, initValue: any) => {
	// 创建自定义ref,对依赖项进行跟踪和更新
	const value = customRef((track, trigger) => {
		return {
			// 获取数据值
			get: () => {
				track()
				const val = localStorage.getItem(key)
				if (val) return val
				// 把初始化的值存进去
				localStorage.setItem(key, initValue)
				return initValue
			},
			// 监听数据变化
			set: (newVal: any) => {
				trigger()
				localStorage.setItem(key, newVal)
			}
		}
	})

	return value
}
<script setup lang="ts">
import { useLocalStorage } from "@/hooks"

const counter = useLocalStorage("counter", 0)

// 更新 counter 值
const update = () => {
	counter.value++
}

</script>

<template>
	<div>{{ counter }}</div>
	<el-button type="primary" @click="update">更新</el-button>
</template>

自定义防抖Ref

防抖函数在输入框操作场景中非常有用。一个 防抖的refVue.js更加灵活

import { customRef } from "vue"

/**
 * @description 自定义防抖Ref
 * @param value 数据值
 * @param delay 延迟时间
 * @returns value
 */
export const useDebouncedRef = (value: number | string, delay: number = 300) => {
	let timer: any
	return customRef((track, trigger) => {
		return {
			get: () => {
				track()
				return value
			},
			set: (newVal: any) => {
				timer && clearTimeout(timer)
				timer = setTimeout(() => {
					trigger()
					value = newVal
				}, delay);
			}
		}
	})
}
<script setup lang="ts">
import { useDebouncedRef } from "@/hooks"

const text = useDebouncedRef("hello")

</script>

<template>
	<el-input v-model="text" placeholder="Please input" />
</template>

表格多选操作

多选是表格批量编辑、删除常用的功能,我们用hooks也封装一下吧

import { ref, computed } from "vue"
import { ElTable } from 'element-plus'

/**
 * @description 表格多选操作
 * @param rowKey 键名
 */
export const useSelection = (rowKey: string = "id") => {
	const multipleTableRef = ref<InstanceType<typeof ElTable>>()
	const selectList = ref([])

	// 获取ids
	const selectListIds = computed(() => {
		const ids = selectList.value.map(item => item[rowKey])
		return ids
	})

	// 多选操作
	const handleSelectionChange = (rowArr: any) => {
		selectList.value = rowArr
	}

	// 关闭多选
	const clearSelection = () => {
		multipleTableRef.value!.clearSelection()
	}

	return {
		multipleTableRef,
		selectList,
		selectListIds,
		clearSelection,
		handleSelectionChange
	}
}
<script setup lang="ts">
import { useSelection } from "@/hooks"
import { watch } from 'vue';

const { multipleTableRef, selectListIds, handleSelectionChange } = useSelection()

const tableData: any[] = [
  { id: '1', name: 'Tom' },
  { id: '2', name: 'Tom' }
]
watch(selectListIds, (newVal) => {
	console.log(newVal)
})
</script>

<template>
	<el-table
    ref="multipleTableRef"
    :data="tableData"
    style="width: 100%"
    @selection-change="handleSelectionChange"
  >
    <el-table-column type="selection" width="55" />
	  <el-table-column property="name" label="Name" width="120" />
  </el-table>
</template>

网络是否可用

import { ref, onMounted, onUnmounted } from 'vue';

/**
 * @description 网络是否可用
 * @returns 
 */
export const useOnline = () => {
	const online = ref(false)

	const showStatus = (val: any) => {
		online.value = typeof val == 'boolean' ? val : val.target.online
	}

	// 在页面加载后,设置正确的网络状态
	navigator.onLine ? showStatus(true) : showStatus(false)

	onMounted(() => {
		// 开始监听网络状态变化
		window.addEventListener("online", showStatus)
		window.addEventListener("offline", showStatus)
	})

	onUnmounted(() => {
    // 移除监听网络状态的变化
    window.removeEventListener("online", showStatus);
    window.removeEventListener("offline", showStatus);
  });

	return {
		online
	}
}