从零构建vue2 + vue-router + vuex 开发环境到入门,实现基本的登录退出功能(二)...
发布日期:2021-10-26 23:04:10 浏览次数:1 分类:技术文章

前言

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

github:

源码说明

项目目录说明

.|-- 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的完整项目,可以使用最简单的方式实现页面后退时状态还原,局部滚动条还原等。复制代码
上一篇:python面向对象(二)
下一篇:用 Swift 实现通知推送的新手指南

关于作者

    白红宇是个全栈工程师,前端vue,小程序,app开发到后端框架设计,数据库设计,环境部署上线运维。

最新文章

必知必会的 Vim 编辑器基础命令 | Linux 中国 2021-05-06
如何为你的开源项目编写实用的文档 | Linux 中国 2021-05-06
ffsend:在命令行中通过 FireFox Send 分享文件 | Linux 中国 2021-05-06
应对新冠病毒的 7 个开源硬件项目 | Linux 中国 2021-05-06
Google 发出了 40000 次国家支持黑客攻击警告 | 每日安全资讯 2021-05-06
使用 K3s 在树莓派上运行 Kubernetes 集群 | Linux 中国 2021-05-06
4 个 Linux 命令行下的 Markdown 工具 | Linux 中国 2021-05-06
我眼中的 2020 年最漂亮的 Linux 发行版 | Linux 中国 2021-05-06
Fedora 32 发布日期、新功能和其它信息 | Linux 中国 2021-05-06
Purism Librem Mini:隐私为重的基于 Linux 的微型个人电脑 | Linux 中国 2021-05-06
黑客 1 亿美元叫卖 AMD Navi 显卡源码 | 每日安全资讯 2021-05-06
在 Linux 上查看和配置密码时效 | Linux 中国 2021-05-06
将你的 Google Drive 连接到 Fedora 工作站 | Linux 中国 2021-05-06
未来 Firefox 或将强制启用 HTTPS 链接 禁止访问不安全页面 | 每日安全资讯 2021-05-06
在 Linux 系统中手动滚动日志 | Linux 中国 2021-05-06
新型冠状病毒对远程网络的影响 | Linux 中国 2021-05-06
水狐:一个支持旧版扩展的火狐复刻版 | Linux 中国 2021-05-06
2020 年将是 SD-WAN 的回顾之年 | Linux 中国 2021-05-06
10 篇关于 Linux 的好文章 | Linux 中国 2021-05-06
GNOME 3.36 发布,对视觉和性能进行了改进 | Linux 中国 2021-05-06