“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。无状态逻辑:在实际开发中,我们都会封装工具类函数,但这类封装一般都是无状态的逻辑,它一般是接收一些输入数据后立刻返回所期望的输出。
举例:时间封装,比如传入一个时间戳,返回对应格式化时间。
vue中reactive有状态逻辑:负责管理随时间而变化的状态。
当我们无需考虑视图布局,只是纯逻辑复用时,推荐用组合式函数替代无渲染组件。
基础代码-未抽离
login.vue页面
vue3逻辑复用
组合式函数
通过例子编写组合式函数
使用组合式API实现登录功能封装/逻辑抽离<script setup >1
import { reactive, ref } from 'vue'2
import { ElMessage } from 'element-plus'3
const loginModel = ref({4
username: '',5
password: '',6
})7
const user = ref()8
const login = async () => {9
user.value = { id: 1, username: loginModel.value.username }10
ElMessage.success('login success')11
}12
const loggedIn = computed(() => user.value?.id)// 判断user 中是否已登录13
const logout = async () => {14
user.value = null 15
ElMessage.success('Logout success')16
}17
</script >18
<template >19
<div class ="login-container ">20
<div class ="login-img ">21
<img src ="../../assets/images/login.png " alt ="">22
</div >
23
抽离可复用的逻辑代码
我们需要将逻辑抽离到单独的文件夹中去,在src目录下新建名为composables的文件夹,它专门用来存储一些抽离出来的逻辑,新建一个useUser.js,将用户相关的逻辑抽离到此文件中。
/composables/useUser.js <h1>24
Login 25
</h1>26
<p v-if ="loggedIn ">27
Welcome {{ user?.username }},28
<a href ="#" @click.prevent ="logout ">Logout </a >29
</p >30
<div v-else class ="input-container ">31
<el-form ref ="form " :model ="loginModel " label-width ="80px ">32
<el-form-item label ="Username ">33
<el-input v-model ="loginModel.username " placeholder ="Username " />34
</el-form-item >35
<el-form-item label ="Password ">36
<el-input v-model ="loginModel.password " placeholder ="Password " />37
</el-form-item >38
<el-form-item >39
<el-button type ="primary " @click ="login ">40
Login 41
</el-button >42
</el-form-item >43
</el-form >44
</div >45
</div >46
</template >
47import { computed , ref } from 'vue'1
import { ElMessage } from 'element-plus'2
3
const user = ref ()// 登录存储的用户信息4
export const useUser = () => {5
const loginModel = ref ({6
username : '',7
password : '',8
})9
const user = ref ()// 登录存储的用户信息
10
login.vue const login = async () => {11
}12
const loggedIn = computed (() => user .value ?.id )// 判断user 中是否已登录13
const logout = async () => {14 user .value = null 15
ElMessage .success ('Logout success')16
}17
18
// 注册数据19
//const registerModel = ref({})20
// 注册方法21
//const register = async () => {22
// 里面完成注册相关的功能23
// }24
25
return {26
loginModel ,27
user ,28
login ,29
loggedIn ,30
logout ,31
32
// 导出即可使用33
//registerModel,34
//register,35
}36
}
37
38<script setup >1
import { useUser } from '@/composables/useUser'2
const { loginModel, login, loggedIn, logout, user } = useUser()3
</script >4
<template >5
<div class ="login-container ">6
<div class ="login-img ">7
<img src ="../../assets/images/login.png " alt ="">8
</div >9
<h1>
10
home.vue Login 11
</h1>12
<p v-if ="loggedIn ">13
Welcome {{ user?.username }},14
<a href ="#" @click.prevent ="logout ">Logout </a >15
</p >16
<div v-else class ="input-container ">17
<el-form ref ="form " :model ="loginModel " label-width ="80px ">18
<el-form-item label ="Username ">19
<el-input v-model ="loginModel.username " placeholder ="Username " />20
</el-form-item >21
<el-form-item label ="Password ">22
<el-input v-model ="loginModel.password " placeholder ="Password " />23
</el-form-item >24
<el-form-item >25
<el-button type ="primary " @click ="login ">26
Login 27
</el-button >28
</el-form-item >29
</el-form >30
</div >31
</div >32
</template >
33<script setup >1
import { useUser } from '@/composables/useUser'2
const { user, loggedIn, logout } = useUser()3
</script >4
5
<template >6
<div >7
<div v-if ="!loggedIn ">8
未登录9
</div >10
<div v-else @click ="logout ">11
已登录: {{ user.username }}12
</div >13
<div />14
</div >
15
组合式函数约定用驼峰命名法命名,并以“use”作为开头。
推荐组合式函数始终返回一个包含多个 ref 的普通的非响应式对象。
目的是为了外部调用组合式函数后,对返回值进行解构为 ref 之后仍可以保持响应性。
但是将返回值解构为 ref 之后,需要用 .value 获取值,如果希望以对象属性的形式来使用组合式函数中返回的状态,可以将返回的对象用 reactive() 包装一次,这样内部的 ref 就会自动进行解包:
在vue中除了内置指令v-model、v-if、v-for等,还可以实现自定义指令。
自定义指令有两种作用域:
自定义局部指令:组件中通过 directives 选项,只能在当前组件中使用;
自定义全局指令:app的 directive 方法,可以在任意组件中被使用;我们一般写在 main.js 中,或者写一个单独的 js 文件然后在 main.js 中引入。
局部指令只能在当前.vue文件中使用,全局指令可以在所有的.vue文件中使用。
1.局部指令实现方式
在<script setup>中(使用组合式),任何以 v 开头的驼峰式命名的变量都可以被用作一个自定义指令。
</template >
16命名
返回值// x 和 y 是两个 ref 1
const { x , y } = useMouse ()
2const mouse = reactive (useMouse ())1
// mouse.x 链接到了原来的 x ref 2
console .log (mouse .x )
3自定义指令
自定义指令实现例子<script setup >1
// 在模板中启用 v-color 2
const vColor = {3
// 类似组件生命周期钩子 钩子函数会接收到指令所绑定元素作为其参数4
mounted: (el, binding) => {5
// console.log('指令', el, binding)6
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论