您的位置:首页 > 产品设计 > UI/UE

从零构建 vue2 + vue-router + vuex 开发环境到入门,实现基本的登录退出功能

2017-06-29 11:38 911 查看
github:https://github.com/lzxb/vue2-demo


源码说明


项目目录说明

.
|-- config                           // 项目开发环境配置
|   |-- index.js                     // 项目打包部署配置
|-- src                              // 源码目录
|   |-- components                   // 公共组件
|       |-- header.vue               // 页面头部公共组件
|       |-- index.js                 // 加载各种公共组件
|   |-- config                       // 路由配置和程序的基本信息配置
|       |-- routes.js                // 配置页面路由
|   |-- css                          // 各种 css 文件
|       |-- common.css               // 全局通用 css 文件
|   |-- iconfont                     // 各种字体图标
|   |-- images                       // 公共图片
|   |-- less                         // 各种 less 文件
|       |-- common.less              // 全局通用 less 文件
|   |-- pages                        // 页面组件
|       |-- home                     // 个人中心
|       |-- index                    // 网站首页
|       |-- login                    // 登录
|       |-- signout                  // 退出
|   |-- store                        // vuex 的状态管理
|       |-- index.js                 // 加载各种 store 模块
|       |-- user.js                  // 用户 store
|   |-- template                     // 各种 html 文件
|       |-- index.html               // 程序入口 html 文件
|   |-- util                         // 公共的 js 方法, vue 的 mixin 混合
|   |-- app.vue                      // 页面入口文件
|   |-- main.js                      // 程序入口文件,加载各种公共组件
|-- .babelrc                         // ES6 语法编译配置
|-- gulpfile.js                      // 启动,打包,部署,自动化构建
|-- webpack.config.js                // 程序打包配置
|-- server.js                        // 代理服务器配置
|-- README.md                        // 项目说明
|-- package.json                     // 配置项目相关信息,通过执行 npm init 命令创建
.


1.html 入口文件,源文件路径: src/template/index.html

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,minimal-ui">
<title>vue2-demo</title>
</head>

<body>
<div id="app">
<router-view></router-view>
4000
;
</div>
</body>

</html>


2.js 入口文件,源文件路径: src/main.js

import Vue from 'vue'
import VueRouter from 'vue-router'

import routes from './config/routes'
import store from './store/'
import components from './components/' //加载公共组件

import './css/common.css'
import './less/common.less'

Object.keys(components).forEach((key) => {
var name = key.replace(/(\w)/, (v) => v.toUpperCase()) //首字母大写
Vue.component(`v${name}`, components[key])
})

Vue.use(VueRouter)

const router = new VueRouter({
routes
})
router.beforeEach(({meta, path}, from, next) => {
var { auth = true } = meta
var isLogin = Boolean(store.state.user.id) //true 用户已登录, false 用户未登录

if (auth && !isLogin && path !== '/login') {
return next({ path: '/login' })
}
next()
})

new Vue({ store, router }).$mount('#app')


3.页面路由,权限配置,源文件路径: src/config/routes.js

import App from '../app'

export default [
{
path: '/',
component: App,
children: [
{
path: '/login', //登录
meta: { auth: false },
component: resolve => require(['../pages/login/'], resolve)
},
{
path: '/signout', //退出
component: resolve => require(['../pages/signout/'], resolve)
},
{
path: '/home', //个人主页
component: resolve => require(['../pages/home/'], resolve)
},
{
path: '/', //首页
meta: { auth: false },
component: resolve => require(['../pages/index/'], resolve)
},
{
path: '*', //其他页面,强制跳转到登录页面
redirect: '/login'
}
]
}
]


4.页面入口组件,源文件路径: src/app.vue

<style lang="less" scoped>

</style>
<template>
<router-view></router-view>
</template>
<script>
export default {

}
</script>


5.store 实例化,导入各种 modules ,源文件路径: src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'

Vue.use(Vuex)

export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production', //在非生产环境下,使用严格模式
modules: {
user
}
})


6.定义 store user 模块,源文件路径: src/store/user.js

import Vue from 'vue'

export const USER_SIGNIN = 'USER_SIGNIN' //登录成功
export const USER_SIGNOUT = 'USER_SIGNOUT' //退出登录

export default {
state: JSON.parse(sessionStorage.getItem('user')) || {},
mutations: {
[USER_SIGNIN](state, user) {
sessionStorage.setItem('user', JSON.stringify(user))
Object.assign(state, user)
},
[USER_SIGNOUT](state) {
sessionStorage.removeItem('user')
Object.keys(state).forEach(k => Vue.delete(state, k))
}
},
actions: {
[USER_SIGNIN]({commit}, user) {
commit(USER_SIGNIN, user)
},
[USER_SIGNOUT]({commit}) {
commit(USER_SIGNOUT)
}
}
}


7.加载各种公共组件,源文件路径: src/components/index.js

import header from './header'
export default { header }


8.封装页面公共头部组件,源文件路径: src/components/header.js

<style lang="less" scoped>
.header {
position: relative;
line-height: 38px;
color: #fff;
text-align: center;
background: #222;
.item {
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
a {
color: #fff;
}
}
.left {
left: 10px;
}
.right {
right: 10px;
}
}
</style>
<template>
<header class="header">
<div class="item left">
<slot name="left"></slot>
</div>
<div class="title">{{title}}</div>
<div class="item right">
<slot name="right"></slot>
</div>
</header>
</template>
<script>
export default {
props: {
title: {
type: String,
default: ''
}
}
}
</script>


9.引入全局公共 css ,源文件路径: src/css/common.css

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button{
-webkit-appearance: none !important;
margin: 0;
}


10.引入全局公共 less ,源文件路径: src/less/common.less

* {
padding: 0;
margin: 0;
}


11.创建首页,,源文件路径: src/pages/index.vue

<style lang="less" scoped>
.login-msg {
padding: 50px;
text-align: center;
}
.msg {
padding: 50px;
text-align: center;
font-size: 20px;
color: red;
}
</style>
<template>
<div>
<v-header title="首页">
<router-link slot="right" v-if="user.id" to="/home">{{user.name}}</router-link>
</v-header>
<div class="login-msg" v-if="!user.id">
<router-link to="/login">你还未登录,请先登录</router-link>
</div>
<div class="msg" v-if="user.id">
<img width="50" :src="logo" alt=""> <br>
哈哈,恭喜你已经入坑 Vue2
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import logo from './logo.png'
export default {
data() {
return {
logo
}
},
computed: mapState({ user: state => state.user }),
}
</script>


12.创建登录页,,源文件路径: src/pages/login.vue

<style lang="less" scoped>
.login {
padding: 50px;
text-align: center;
.line {
padding: 5px;
input {
padding: 0 10px;
line-height: 28px;
}
}
button {
padding: 0 20px;
margin-top: 20px;
line-height: 28px;
}
}
</style>
<template>
<div>
<v-header title="登录">
<router-link slot="left" to="/">返回</router-link>
</v-header>
<form class="login" v-on:submit.prevent="submit">
<div class="line">
<div v-show="btn && !form.id">id 不能为空</div>
<input type="number" placeholder="输入你的 id" v-model="form.id">
</div>
<div class="line">
<div v-show="btn && !form.name">用户名不能为空</div>
<input type="text" placeholder="输入你的用户名" v-model="form.name">
</div>
<button>登录</button>
</form>
</div>
</template>
<script>
import { mapActions } from 'vuex'
import { USER_SIGNIN } from 'store/user'

export default {
data() {
return {
btn: false, //true 已经提交过, false 没有提交过
form: {
id: '',
name: ''
}
}
},
methods: {
...mapActions([USER_SIGNIN]),
submit() {
this.btn = true
if(!this.form.id || !this.form.name) return
this.USER_SIGNIN(this.form)
this.$router.replace({ path: '/home' })
}
}
}
</script>


13.创建个人主页,,源文件路径: src/pages/home.vue

<style lang="less" scoped>

</style>
<template>
<div>
<v-header title="首页">
<router-link slot="left" to="/">首页</router-link>
<router-link slot="right" to="/signout">退出</router-link>
</v-header>
<div style="padding: 50px;">{{user.name}}欢迎回家</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: mapState({ user: state => state.user }),
}
</script>


14.创建退出页,,源文件路径: src/pages/signout.vue

<style lang="less" scoped>
.btn {
padding: 50px;
text-align: center;
button {
padding: 5px 10px;
}
}
</style>
<template>
<div>
<v-header title="退出">
<router-link slot="left" to="/home">返回</router-link>
</v-header>
<div class="btn">
<button v-on:click="submit">确认退出</button>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
import { USER_SIGNOUT } from 'store/user'
export default {
methods: {
...mapActions([USER_SIGNOUT]),
submit() {
this.USER_SIGNOUT()
this.$router.replace({ path: '/login' })
}
}
}
</script>


进击 vue2

vue2 重构 cnode 社区,将会近日完成,
一个从 0 构建的 vue2 的完整项目,
可以使用最简单的方式实现页面后台时状态还原,
局部滚动条还原等。


原文地址:https://gold.xitu.io/post/5842554761ff4b006b90c399
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐