从零构建 vue2 + vue-router + vuex 开发环境到入门,实现基本的登录退出功能(二) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
1340641314
V2EX    分享发现

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

  •  
  •   1340641314 2016-12-03 14:25:45 +08:00 14058 次点击
    这是一个创建于 3237 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    国庆在回家的路上,得知了 vue2 发布了正式版, 国庆回来后,在公司内两个项目便直接应用上了 vue2 , 一个是 PC 端的商户后台,一个是微信端商城, 都是基于 Vue2 、 vue-router 、 vuex ...... 在开发的过程中,遇到了一系列的问题, 比如页面后退数据还原,滚动条还原, 登录超时,获取列表数据,表单提交, 多台服务器自动化部署,最终后一个个解决了, 能够平稳的从 react 切换到 vue2 开发, vue 的文档功不可没。 

    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> </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

    5 条回复    2018-03-13 08:56:02 +08:00
    Cbdy
        1
    Cbdy  
       2016-12-03 14:38:08 +08:00
    V2EX :有门的话不需要把内容转过来了。
    1340641314
        2
    1340641314  
    OP
       2016-12-03 14:49:26 +08:00
    ...找不到删除的地方
    linmi
        3
    linmi  
       2016-12-03 15:23:19 +08:00   1
    你得去掘金,开发者头条,极客头条发。
    1340641314
        4
    1340641314  
    OP
       2016-12-03 16:55:49 +08:00
    下次会注意的。无意冒犯了社区的精神
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5284 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 09:27 PVG 17:27 LAX 02:27 JFK 05:27
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86