【Vue 技巧】做一个全局登录弹窗,任何地方访问

需要一个登录弹窗,在任何地方都能使用。

需求

  1. 在任何页面内能访问
  2. 在路由拦截能访问

解决方案

任何地方都能访问,第一个想到的是挂载原型链Vue.prototype.$someThing。而访问一个实例,一般是ref去访问,路由是在Vue配置时组成了守卫,这时还访问不了vue实例refs是实例属性,就更访问不了组件实例了,可能可以动态改路由守卫,但是这里准备用单开一个vue实例,这样就可以暴露一个单独实例出来了。

步骤

1. 新建一个js文件,引入main.js

由于我的项目搭建是@/components/index.js负责注册全局组件,所以这里在@/components/index.js引入。

// @/components/index.js
import Vue from 'vue'
import '@/components/LoginDialog' //在这引入全局登录弹窗
import SvgIcon from '@/components/SvgIcon.vue'

Vue.component('SvgIcon', SvgIcon)
复制代码

2. 新建一个实例,挂载到document.body

import Vue from 'vue'
import LoginDialog from './index.vue'

// 这里可以用Vue.extend()创建子类,但是我没打算注册为组件,就直接`new Vue`
const loginDialog = new Vue(LoginDialog) 
loginDialog.$mount(document.createElement('div'))
document.body.appendChild(loginDialog.$el)

Vue.prototype.$loginDialog = loginDialog

export default loginDialog
复制代码

3. 在路由守卫里访问

直接引入实例

import router from './router'
import store from '@/store'
import loginDialog from '@/components/LoginDialog'

const whiteList = ['/']

router.beforeEach((to, from, next) => {
    if (store.getters.token) next()
    else if (whiteList.indexOf(to.path) > -1) next()
    else loginDialog.open()
})
复制代码

4. 在页面内访问

<vs-button @click="login" transparent>登录</vs-button>
login() {
    this.$loginDialog.open()
}
复制代码

image.png

这里就有2个根实例

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享