vue自定义全局登录插件

vue自定义全局登录插件, 在全局任意位置使用this.$login()即可调起登录弹窗
分为两个文件:
Login.vue(登录样式主体)
index.js(插件方法及注册到全局)
使用方法

以下具体代码:

loading.vue

注意:若组件内使用i18n, 请用i18n.t(keyName),而不是this.$t(keyName)
listener方法可供 调用的父组件内 监听事件及传递值

src/components/login/Login.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<template>
<yr-modal
v-model="visible"
title=""
:width="410"
:height="400"
class="login"
:btns="false"
>
<div slot="content">
<div class="htitle">{{ i18n.t('loginTt') }}</div>
<div class="form">
<div class="input">
<input v-model="formData.userName" type="text" :placeholder="i18n.t('usercountTip')" />
</div>
<div class="input">
<input v-model="formData.password" type="text" :placeholder="i18n.t('userPwd')" />
</div>
<div class="btn">
<div class="log" @click="login">{{ i18n.t('login') }}</div>
<div class="reg">
<a href="/register.html">{{ i18n.t('regTip') }}</a>
</div>
</div>
</div>
</div>
</yr-modal>
</template>
<script>
import Api from '@/api/api'
import { isDeviceMobile } from '@/js/util'
import i18n from '@/locales/index'
// import defaultSettings from '@/settings.js'

export default {
props: {
// eslint-disable-next-line
value: {},
listener: { // 每个阶段会回调
type: Function,
default: null
}
},
data() {
return {
i18n: i18n,
visible: true,
formData: {
userName: '',
password: ''
}
}
},
computed: {
isDeviceMobile() {
return isDeviceMobile()
}
},
watch: {
value: {
handler(val) {
if (val !== undefined) {
this.visible = val.visible
}
},
deep: true,
immediate: true
},
visible: {
handler(val) {
if (!val) {
document.body.removeChild(this.$el)
this.$destroy()
}
},
immediate: true
}
},
mounted() {
},
methods: {
close() {
this.visible = false
this.listener && this.listener({ act: 'close' })
},
login() {
const params = {
userName: this.formData.userName,
password: this.formData.password
}
const language = (i18n.locale || 'zh-CN').toLowerCase()
Api.login(params, language).then(res => {
// 供外部使用
// this.listener && this.listener({ act: 'login', res: res.data })
}).catch(() => {
return false
})
}
}
}
</script>

<style lang="less" scoped>
.login.yr-modal {
/deep/ .content {
text-align: center;
background:linear-gradient(180deg,rgba(255,255,255,1) 0%,rgba(248,251,254,1) 100%);
border-radius:4px;
top: 30%;
left: 50%;
transform: translate(-50%, -30%);
position: absolute;
max-width: calc(100% - 20px);
max-height: 100%;
.m-header {
padding-top: 24px;
padding-bottom: 32px;
border-bottom: none;
height: 70px;
}
.m-content {
padding: 0 35px 45px;
.htitle {
font-size: 20px;
font-weight:600;
line-height:28px;
color: #1E1E1E;
letter-spacing: 2px;
}
.form {
width: 100%;
margin-top: 40px;
margin-bottom: 40px;
color: #9D9EA5;
font-size:12px;
font-weight:400;
.input {
width: 100%;
height: 40px;
margin-bottom: 24px;
border-radius: 4px;
border:1px solid #C0C2CB;
input {
text-align: center;
background: #fff;
padding: 0 16px;
outline: 0;
height: calc(100% - 4px);
margin-left: 2px;
margin-right: 2px;
width: calc(100% - 4px);
margin-top: 1px;
position: relative;
top: 1px;
&::-webkit-input-placeholder {
color: #9D9EA5;
}
&::-moz-placeholder {
color: #9D9EA5;
}
&::-ms-input-placeholder {
color: #9D9EA5;
}
}
}
.btn {
width: 100%;
text-align: center;
.log {
display: block;
height:40px;
background:#1E1E1E;
box-shadow:0px 2px 3px 0px rgba(0,0,0,0.15);
border-radius:4px;
line-height: 40px;
color: #fff;
font-size: 14px;
margin-bottom: 20px;
cursor: pointer;
}
.reg {
text-align: center;
a {
font-size:12px;
font-weight:400;
color:#1159FF;
line-height:17px;
text-decoration: underline;
}
}
}
}
}
}
}
</style>
index.js

src/components/login/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import Login from './Login.vue'
const LOGIN = {
install(Vue, options = {}) {
if (typeof window !== 'undefined' && window.Vue) {
Vue = window.Vue
}
Vue.component('yrLogin', Login)

function yrLogin(options) {
const VueLogin = Vue.extend({
data() {
return {
options: { ...options }
}
},
render(h) {
return h('yrLogin', {
props: this.options
})
}
})
const newLogin = new VueLogin()
const vm = newLogin.$mount()
const el = vm.$el
document.body.appendChild(el)
vm.visible = true
return vm
}
Vue.prototype.$yrLogin = yrLogin
}
}
export default LOGIN
使用方法
1
2
3
> src/main.js
import yrLogin from '@/components/login'
Vue.use(yrLogin)

组件内调用

1
2
3
4
5
this.$yrLogin({
listener: (res) => {
console.log(res)
}
})
------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!