目录
4.1 添加注册页面
4.2 注册表单验证
4.3提交注册信息
4.4 完善注册功能
4.5 完善登录功能
4.6 推出用户登录
4.7 用户登录界面
4.8 小结
4.1 添加注册页面
<template>
<div class="navbar-right">
<div class="nav navbar-nav github-login">
<a href="#" class="btn btn-default login-btn">
<i class="fa fa-user"></i> 登 录
</a>
<a href="#" class="btn btn-default login-btn">
<i class="fa fa-user-plus"></i> 注 册
</a>
</div>
</div>
</template>
<script>
export default {
name: 'TheEntry'
}
</script>
<style scoped>
</style>
<script>
// 引入 TheEntry.vue 的默认值
import TheEntry from '@/components/layouts/TheEntry'
export default {
name: 'TheHeader',
// 添加 components 选项,并注册 TheEntry
components: {
TheEntry
},
data() {
.
.
.
</script>
2、查找 <div id="top-navbar-collapse" 元素,在其内部添加『入口组件』:
src/components/layouts/TheHeader.vue
<div id="top-navbar-collapse" :class="['collapse', 'navbar-collapse', { in: showCollapsedNav }]">
<ul class="nav navbar-nav">
<li v-for="(item, index) in navList" :class="{ active: index === activeNavIndex }">
<a href="#" @click="changeNavIndex(index)">{
{ item }}</a>
</li>
</ul>
<!-- 入口组件 -->
<div class="navbar-right">
<TheEntry/>
</div>
</div>
<template>
<div class="row">
<div class="col-md-4 col-md-offset-4 floating-box">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">请注册</h3>
</div>
<div class="panel-body">
<div class="form-group">
<label class="control-label">用户名</label>
<input type="text" class="form-control" placeholder="请填写用户名">
</div>
<div class="form-group">
<label class="control-label">密码</label>
<input type="password" class="form-control" placeholder="请填写密码">
</div>
<div class="form-group">
<label class="control-label">确认密码</label>
<input type="password" class="form-control" placeholder="请填写确认密码">
</div>
<div class="form-group">
<label class="control-label">图片验证码</label>
<input type="text" class="form-control" placeholder="请填写验证码">
</div>
<div class="thumbnail" title="点击图片重新获取验证码">
<div class="captcha"></div>
</div>
<button type="submit" class="btn btn-lg btn-success btn-block">
<i class="fa fa-btn fa-sign-in"></i> 注册
</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Register'
}
</script>
<style scoped>
.thumbnail { width: 170px; margin-top: 10px; cursor: pointer;}
.thumbnail .captcha { height: 46px; background: #E1E6E8;}
</style>
> cd ~/Code/vuejs-essential
> npm install vue-router --save
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const routes = [
{
path: '/auth/register',
name: 'Register',
component: () => import('@/views/auth/Register')
}
]
const router = new Router({
mode: 'history',
routes
})
export default router
在引入 vue-router 后,我们需要使用 Vue.use 来使用插件:
Vue.use(Router)
component: () => import('@/views/auth/Register')
component: () => import('@/views/auth/Register')
import Register from '@/views/auth/Register'
const routes = [
{
path: '/auth/register',
name: 'Register',
component: Register
}
]
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App),
}).$mount('#app')
我们先引入路由配置:
// 如果引入的是 index.js,可以使用下面的简写,等价于 import router from './router/index.js'
import router from './router'
然后在当前实例中注入路由:
new Vue({
router
})
<template>
<div id="wrap">
<TheHeader/>
<div id="main-container" class="container main-container">
<router-view/>
</div>
<TheFooter/>
</div>
</template>
<!-- 修改 -->
<a href="#" class="btn btn-default login-btn">
<i class="fa fa-user-plus"></i> 注 册
</a>
<!-- 为 -->
<router-link to="/auth/register" class="btn btn-default login-btn">
<i class="fa fa-user-plus"></i> 注 册
</router-link>
<router-link> 组件支持用户在具有路由功能的应用中导航,通过 <router-link> 上的 to 属性可以指定目标地址,这里是一个字符串 /auth/register,对应路由配置中的 path。
现在的页面效果如下:
从上面的演示可以看到,当切换回首页时页面重新加载了,我们需要打开 TheHeader.vue 文件,将 Logo 链接用 <router-link> 替换:
src/components/layouts/TheHeader.vue
<!-- 修改 -->
<a href="/" class="navbar-brand">
<span class="title">{
{ logo.title }}</span>
<img :src="logo.src" :alt="logo.title">
</a>
<!-- 为 -->
<router-link to="/" class="navbar-brand">
<span class="title">{
{ logo.title }}</span>
<img :src="logo.src" :alt="logo.title">
</router-link>
4.2 注册表单验证
function validate(el, modifiers, bindingValue) {
bindingValue = bindingValue && typeof bindingValue === 'object' ? bindingValue : {}
const value = typeof el.value === 'string' ? el.value.trim() : ''
const { title = '该项', error } = bindingValue
let defaultError = ''
if (modifiers.required && value === '') {
defaultError = `${title}不能为空`
} else if (bindingValue.target) {
const target = document.querySelector(bindingValue.target)
const targetValue = target ? target.value : null
if (targetValue !== value) {
defaultError = `输入的${title}不匹配`
}
} else if (bindingValue.regex) {
try {
if (!bindingValue.regex.test(value)) {
defaultError = `${title}格式不正确`
}
} catch (e) {}
}
if (defaultError) {
if (error === undefined) {
showError(el, defaultError)
} else {
showError(el, error)
}
} else {
showError(el)
}
}
function showError(el, error) {
const parentElement = el.parentElement
const errorElement = getErrorElement(el)
if (error === undefined) {
errorElement.style.display = 'none'
parentElement.classList.remove('has-error')
} else {
errorElement.textContent = error
errorElement.style.display = 'block'
parentElement.classList.add('has-error')
}
}
function getErrorElement(el) {
const parentElement = el.parentElement
let errorElement = parentElement.querySelector('.help-block')
if (!errorElement) {
const tpl = `<span class="help-block"></span>`
const fragment = document.createRange().createContextualFragment(tpl)
parentElement.appendChild(fragment)
errorElement = parentElement.querySelector('.help-block')
}
return errorElement
}
export default {
bind(el, binding, vnode) {
const { value, arg, modifiers } = binding
const eventType = ['change', 'blur', '