> For the complete documentation index, see [llms.txt](https://close.gitbook.io/yun-wei-bi-ji/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://close.gitbook.io/yun-wei-bi-ji/centos/vue/xiang-mu/2-08.-feng-zhuang-zu-he-shi-api-jian-hua-dai-ma.md).

# 2 08.封装组合式api简化代码

> 为了减少代码复杂量，我们简化一下代码 ，方便扩展性

* #### 组合式API
* > 新建文件： src/composables/useManager.js

```js
import { ref, reactive } from 'vue'
import { logout, updatepassword } from "~/api/manager"
import { showModal, toast } from "~/composables/util"
import { useRouter } from "vue-router"
import { useStore } from "vuex"



export function userRepassword() {
    const store = useStore()
    const router = useRouter()

    // 修改密码,点击登录验证
    const formDrawerRef = ref(null)
    const formRef = ref(null)

    const form = reactive({
        oldpassword: '',
        password: '',
        repassword: '',

    })

    // 定义验证规则
    const rules = {
        oldpassword: [
            {
                required: true,
                message: '旧密码不能为空',
                trigger: 'blur',
            },
        ],
        password: [
            {
                required: true,
                message: '新密码不能为空',
                trigger: 'blur',
            },
        ],
        repassword: [
            {
                required: true,
                message: '确认密码不能为空',
                trigger: 'blur',
            },
        ]
    }


    const onSubmit = () => {
        formRef.value.validate((valid) => {
            if (!valid) {
                console.log('error')
            }

            // 加载动画
            formDrawerRef.value.showLoading()

            updatepassword(form).then(res => {
                toast('修改密码成功，请重新登录')
                store.dispatch('logout')
                router.push('/login')
            }).finally(() => {
                formDrawerRef.value.hideLoading()
            })

        })
    }

    const openRePasswordForm = () => formDrawerRef.value.open()

    return {
        formDrawerRef,
        form,
        rules,
        formRef,
        onSubmit,
        openRePasswordForm
    }

}


export function useLogout() {
    const store = useStore()
    const router = useRouter()
    function handleLogout() {
        showModal("是否要退出登录？").then(res => {
            logout().finally(() => {
                // 退出
                store.dispatch('logout')
                // 跳转回登录页
                router.push('/login')
                // 提示退出登录成功
                toast('退出登录成功')
            })
        })
    }

    return {
        handleLogout
    }
}
```

* #### 代码更改

  > FHeader.vue

```js
<template>
    <div class="f-header">
        <span class="logo">
            <el-icon class="mr-1"><eleme-filled></eleme-filled></el-icon>
            Vue+Vite编程
        </span>
        <el-icon class="icon-btn"><fold /></el-icon>
        <el-tooltip effect="dark" content="刷新" placement="bottom">
            <el-icon class="icon-btn" @click="handleRefresh"><refresh /></el-icon>
        </el-tooltip>
        


        <div class="ml-auto flex items-center">
            <el-tooltip effect="dark" content="全屏" placement="bottom">
                <el-icon  class="icon-btn" @click="toggle">
                    <full-screen v-if="!isFullscreen"/>
                    <aim v-else/>
                </el-icon>
            </el-tooltip>
            <el-dropdown class="dropdown" @command="handleCommand">
                <span class="flex items-center text-light-50">
                    <el-avatar class="mr-2" :size="25" :src="$store.state.user.avatar"></el-avatar>
                    {{ $store.state.user.username }}
                    <el-icon class="el-icon--right"> <arrow-down /></el-icon>
                </span>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item command="rePassword">修改密码</el-dropdown-item>
                        <el-dropdown-item command="logout">退出登录</el-dropdown-item>
                    </el-dropdown-menu>
                </template>
        </el-dropdown>
        </div>
    </div>


<!-- 修改密码 Start -->

    <form-drawer ref="formDrawerRef" title="修改密码" destroyOnClose @submit="onSubmit">

        <el-form  ref="formRef" :rules="rules" :model="form" label-width="80px" size="small">
            <el-form-item prop="oldpassword" label="旧密码">
                <el-input v-model="form.oldpassword" placeholder="请输入旧密码">
                    <template #prefix>
                        <el-icon><User /></el-icon>
                    </template>
                </el-input>
            </el-form-item>
            <el-form-item prop="password" label="新密码">
                <el-input type="password" v-model="form.password" placeholder="请输入新密码" show-password>
                    <template #prefix>
                        <el-icon><Lock /></el-icon>
                    </template>
                </el-input>
            </el-form-item>
            <el-form-item prop="repassword" label="确认密码">
                <el-input type="password" v-model="form.repassword" placeholder="请输入确认密码" show-password>
                    <template #prefix>
                        <el-icon><Lock /></el-icon>
                    </template>
                </el-input>
            </el-form-item>
        </el-form>

    </form-drawer>
    
<!-- 修改密码 End -->
</template>


<script setup>
import FormDrawer from '~/components/FormDrawer.vue'
import { useFullscreen } from '@vueuse/core'
import { userRepassword, useLogout } from '~/composables/useManager'

const { 
    // 是否全屏状态
    isFullscreen, 
    toggle 
} = useFullscreen()


const {
    formDrawerRef,
    form,
    rules,
    formRef,
    onSubmit,
    openRePasswordForm
} = userRepassword()


const {
    handleLogout
} = useLogout()


const handleCommand = (c) =>{
    switch (c) {
        case "logout":
            handleLogout()
            break;

        case "rePassword":
            openRePasswordForm()
            break;
    }
}


// 刷新
const handleRefresh = () => location.reload()




</script>

<style>
.f-header{
    @apply flex items-center bg-indigo-500 text-light-50 fixed top-0 left-0 right-0;
    height: 64px;
}

.logo{
    width: 250px;
    @apply flex justify-center items-center text-xl font-thin;
}

.icon-btn{
    @apply flex justify-center items-center;
    width: 42px;
    height: 64px;
    cursor: pointer;
}

.icon-btn:hover{
    @apply bg-indigo-600;
}

.f-header .dropdown{
    height: 64x;
    cursor: pointer;
    @apply flex justify-center items-center mx-5;
}
</style>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://close.gitbook.io/yun-wei-bi-ji/centos/vue/xiang-mu/2-08.-feng-zhuang-zu-he-shi-api-jian-hua-dai-ma.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
