Vue 组件函数如何实现可复用?

How can Vue component functions be made reusable?

在 Vue 应用程序中,我有许多功能只有在用户主动登录时才能使用。

检查用户是否通过身份验证的函数是这样的:

    import {useStore} from "vuex";
    import {useRoute, useRouter} from "vue-router";   
        
    export default {
     setup() {
        const VueStore = useStore();
        const VueRouter = useRouter(); 
        const route$ = useRoute();
    
        const isLoggedIn = ref(VueStore.state.securityStore.isLoggedIn);
            
            async function authenticateIdentity() {
                
                  try {
                    await VueStore.dispatch('securityStore/autoLogin');
                    if (isLoggedIn !== true) {
                      return VueRouter.push({name: "Login", query: {redirect: route$.path}})
                    }
                  } catch (error) {
                    return VueRouter.push({name: "Login", query: {redirect: route$.path}})
                  }
                }
             }
         }

步骤很简单:

  1. 请求 VueStore 运行 自动登录用户的 action(使用 cookie)
  2. 如果认证通过什么都不做(即让调用函数继续)
  3. 否则,如果未通过身份验证,则将用户带到 Login 屏幕

我想将这段代码保存在一个单独的文件中,并在我需要的任何组件中使用它。这在 Vue3 中如何完成?

您可以创建一个插件

const myAuthPlugin = {
  install(app, options) {
    // move the Authentication logic and method here
  }
}

app.use(myAuthPlugin)

可以创建一个允许在其他地方重用该功能的 Vue3 composable

棘手的部分是 vue-router。我们必须确保可组合项中使用的路由器实际上与 App/components 中使用的路由器实例相同。我们不能使用 useRouter(),这是在组件的设置函数中使用路由器的方法(在我们的可组合项中,我们没有设置函数)。因此,我们建议将路由器定义放在一个额外的模块中,并在 App 和可组合定义之间共享此模块。

1。创建新文件 router.js

import {createRouter, createWebHashHistory} from 'vue-router'

const routes = [
    {path: '/', name: 'Home', component: Home},
    {path: '/login', name: 'Login', component: Login},
    ...
    {path: "/:pathMatch(.*)*", component: NotFound},
]

const router = createRouter({
  history: createWebHashHistory(),
  routes: routes
})

export default router;

2。在 main.js

中使用路由器模块
import {createApp} from 'vue'
import router from './router.js'
import App from './components/App.vue'

const myApp = createApp(App);
myApp.use(router)
     .mount('#app');

3。创建可组合项 loggin.js

import {ref} from 'vue';
import store from './store.js';  // assuming this is the file containing the store definition
import router from './router.js';

export async function authenticateIdentity() {
    const isLoggedIn = ref(store.state.securityStore.isLoggedIn);
    try {
        await store.dispatch('securityStore/autoLogin');
        if (isLoggedIn !== true) {
            return router.push({name: "Login", query: {redirect: router.currentRoute.value.path}})
        }
    } catch (error) {
        return router.push({name: "Login", query: {redirect: router.currentRoute.value.path}})
    }
}

4。在其他组件中使用可组合

<script>
import {authenticateIdentity} from 'loggin.js'

export default {
  name: "LoginComponent",
  methods: {
    login(){
      authenticateIdentity().then( ... ).catch( ... );
    }
  }
}
</script>

(调整项目结构/导入路径/名称)