vue 登录案例

 main.js

import App from './App.vue'
import Vue from 'vue'
import router from './router/'
import components from './components/header.js' //加载公共组件 
import store from './store/'
Object.keys(components).forEach((key) => {
  var name = key.replace(/(\w)/, (v) => v.toUpperCase()) //首字母大写
  Vue.component(`v${name}`, components[key])
})


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({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

router.js

import Vue from 'vue'
import Router from 'vue-router'
import App from '../App.vue'
// import Home from '../pages/home.vue'
const Home = () => import('../pages/home.vue')
const Login = () => import('../pages/login.vue')
const Main = () => import('../pages/main.vue')
const Loginout = () => import('../pages/loginout.vue')



Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: '/',
     component:App,
     children:[
      { path: '/', meta: { auth: false },component: Home },  //首页
      { path: '/login', meta: { auth: false },component: Login }, //登录
      { path: '/main', component: Main },  //个人中心
      { path: '/loginout', component: Loginout },  //退出
      {
        path: '*', //其他页面,强制跳转到登录页面
        redirect: '/login'
    }
     ]
    },
    


  ]
})
export default router

登录状态管理器store

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'
// 挂载vuex
Vue.use(Vuex)

// 创建vue对象
export default new Vuex.Store({
    modules:{
        user
    }
})

store.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)
        }
    }
}

login.vue

<template>
  <div>
    <v-header title="登录">
      <router-link slot="left" to="/">返回</router-link>
    </v-header>
    <form class="login" @submit.prevent="submit">
      <div class="line">
                        <div v-show="btn && !form.id">id不能为空</div>

        <input type="text" placeholder="请输入你的id" v-model="form.id" />
      </div>
      <div class="line">
                        <div v-show="btn && !form.pwd">用户名不能为空</div>

        <input type="text" placeholder="请输入密码" v-model="form.pwd" />
      </div>
      <button>登录</button>
    </form>
  </div>
</template>
<script>
import { mapActions } from "vuex";
import { USER_SIGNIN } from "../store/user";
export default {
  data() {
    return {
      btn: false,
      form: {
        id: "",
        pwd: ""
      }
    };
  },
  methods: {
    ...mapActions([USER_SIGNIN]),

    submit() {
      this.btn = true
      if (!this.form.id || !this.form.pwd) return 
      this.USER_SIGNIN(this.form);
      console.log(this.form);
      this.$router.replace({ path: "/" });
    }
  }
};
</script>
<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>

home.vue

<template>
  <div>
    <v-header title="首页">
      <router-link slot="right"  v-if="user.id" to="/main">{{user.id}}</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">
            哈哈,恭喜你已经入坑Vue2
        </div>
  </div>
</template>

<script>
  import {mapState} from 'vuex'

export default {
  data() {
    return {};
  },
  computed:{
    ...mapState({user:state => state.user})
  }
};
</script>
<style lang="less" scoped>
.login-msg {
  text-align: center;
  padding: 50px;
}
</style>

main.vue

<template>
  <div>
    <v-header title="个人中心">
      <router-link slot="left" to="/">首页</router-link>
      <router-link slot="right" to="/loginout">退出</router-link>
    </v-header>
    <div>欢迎回家{{user.pwd}}</div>
  </div>
</template>
<script>
import { mapState } from "vuex";
export default {
  data() {
    return {};
  },
  computed: {
    ...mapState({ user: state => state.user })
  }
};
</script>
<style lang="less" scoped>
</style>

loginout.vue

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

公共组件header

header.vue

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

猜你喜欢

转载自www.cnblogs.com/recommencer/p/12811351.html