Vuex入门简单示例(二)

前言

我想写一系列关于Vuex的入门文章,我是看着vuex官网文档,结合自己从零搭建的vue项目来实践vuex的知识。

Vuex入门系列:

 

本文涉及知识点:

  1. vue cli3快速构建项目
  2. 安装并使用vue-router
  3. 安装并使用vuex
  4. router beforeEach 导航守卫实现登录判断
  5. 关闭console.log Eslint检查
  6. vuex之state
  7. vuex之mutation

 

用vue cli3构建一个简单的项目

vue create vuex-login

Please pick a preset 选择默认 default (babel, eslint)

回车,自动安装,完成后

cd vuex-login

安装vue-router

yarn add vue-router

安装vuex

yarn add vuex

运行项目,看看初始化的页面

yarn run serve

这样子就ok,继续...

 

整理下代码

  • 删掉src/components里面的HelloWorld.vue文件
  • 删除App.vue中引用HelloWorld.vue组件的相关代码

 

在App.vue添加<router-view />标签

src/App.vue

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style>
</style>

 

在src/components下新建两个vue文件

src/components/Home.vue

<template>
  <div class="home">
  首页 </div> </template> <script> export default { name: 'Home' } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>

src/components/login.vue

<template>
  <div class="login">
  登录页 </div> </template> <script> export default { name: 'Login' } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>

等下路由会用到这两个页面

 

使用vue-router和vuex

vue-router和vuex都安装了,现在开始写router和store,为了简单方便,我就直接写在main.js里面了。

1.引用vue-router和vuex

src/main.js

import VueRouter from 'vue-router' //导入依赖
import Vuex from 'vuex' //导入依赖

Vue.use(VueRouter) //使用依赖
Vue.use(Vuex) //使用依赖

2.导入页面组件

src/main.js

// 页面组件
import Home from '@/components/Home'
import Login from '@/components/Login'

3.编写路由代码

src/main.js

const router = new VueRouter({
  routes: [
    {
      path: '/',
      component: Home
    },
    {
      path: '/login',
      component: Login
    }
  ]
})

在Vue实例添加router

src/main.js

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

4.编写store代码

src/main.js

const store = new Vuex.Store({
  state: {
    isLogin: false
  }
})

知识点讲解

  • state是状态对象
  • mutations是更改状态对象状态的方法(后面会用到)

 

先写一个isLogin状态,默认值false

在Vue实例添加store

src/main.js

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app')

 

到这里,项目基本搭建完成。

接下来,我们实现一个这样的效果,根据isLogin状态的值来判断页面的跳转。

先用写死的isLogin的值来实现一个简单固定版,后面再改成用store来实现的真实版本。

这里用到路由拦截(导航守卫)方法

 

路由拦截(导航守卫)

首先,改造一下路由的代码,给它们加上name和meta等属性

src/main.js

const router = new VueRouter({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home,
      meta: { auth: true }
    },
    {
      path: '/login',
      name: 'login',
      component: Login,
      meta: { auth: true }
    }
  ]
})

auth: true 表示此路由需要验证

然后,用router.beforeEach拦截路由

src/main.js

// const store...

/* 路由拦截:检查是否登录,未登录则跳到登录页 */
router.beforeEach((to, _, next) => {
  console.log(to);
  // 过滤需要验证的路由
  if (to.matched.some( m => m.meta.auth)) {
    // 这一个判断非常重要,没有的话会导致栈溢出报错
    if (to.name == 'login') {
      next()
    } else {
      if (store.state.isLogin == true) {
        next()
      } else {
        next('/login')
      }
    }
  } else {
    next()
  }
})

 

关闭console.log eslint检查

此处为了调试代码,写了console.log,eslint检查默认console.log是会报错的。

要关闭这一项检查,修改package.json文件,在eslintConfig里面的rules里面加上 "no-console": "off"

 

现在页面根据isLogin来跳转应该是没有问题了。你可以手动修改isLogin的值来试试。

接下来想想如何动态修改isLogin,这里会用到更多vuex的知识

 

先说说如何在Vue组件中获得Vuex状态

在Home.vue和Login.vue文件都加上$store.state.isLogin来实时显示isLogin的值

src/components/Login.vue(src/components/Home.vue同样)

<template>
  <div class="login">
    登录状态:{{$store.state.isLogin}} <br>
    登录页 
  </div>
</template>

我们把isLogin的默认值设为false, 默认都会跳到登录页。

我们给登录页加一个按钮

src/components/Login.vue

<template>
  <div class="login">
    登录状态:{{$store.state.isLogin}} <br/>
    <button @click="LoginHandle">登录</button>
  </div>
</template>

点击按钮修改isLogin的值,并跳转到首页

src/components/Login.vue

<script>
export default {
  name: 'Login',
  methods: {
    LoginHandle () {
      this.$store.commit('changeLogin', true)
      this.$router.push('/')
    }
  }
}
</script>

浏览器预览下试试

这里贴一下Mutation的概念

更改Vuex的store中的状态的唯一方法是提交mutation.Vuex中的mutation非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数。

 

到这里应该就明白了vuex中两个基本的概念,state和mutation,更多知识点在用到的时候再说吧。

 

现在,我们把登录页丰富一下。加上用户名和密码。点登录后保存起来。

src/components/Login.vue

<template>
  <div class="login">
    登录状态:{{$store.state.isLogin}} <br/>
    <div>
      <input v-model="username" type="text" placeholder="用户名"> <br>
      <input v-model="password" type="password" placeholder="密码"> <br>
      <button @click="LoginHandle">登录</button>
    </div>
  </div>
</template>
// ...
data () {
    return {
      username: '',
      password: ''
    }
  },
// ...

修改store对象,添加username和password状态,以及修改状态的方法。

src/main.js

const store = new Vuex.Store({
  state: {
    isLogin: false, //登录状态
    username: '', //用户名
    password: '' //密码
  },
  mutations: {
    // 修改登录状态
    changeLogin(state, data) {
      state.isLogin = data
    },
    // 修改用户名状态
    changeUsername(state, data) {
      state.username = data
    },
    // 修改密码状态
    changePassword(state, data) {
      state.password = data
    }
  }
})

 

再次回到Login.vue完善登录函数

src/components/Login.vue

// ...
  methods: {
    LoginHandle () {
      // 表单验证
      if (!this.username || !this.password ) return;
      
      // 修改isLogin状态
      this.$store.commit('changeLogin', true)
      // 修改username状态
      this.$store.commit('changeUsername', this.username)
      // 修改password状态
      this.$store.commit('changePassword', this.password)
      
      this.$router.push('/') // 跳到首页
    }
  }
// ...

修改Home.vue,显示用户名

src/components/Home.vue

<template>
  <div class="home">
    登录状态:{{$store.state.isLogin}} <br>
    {{$store.state.username}},你好! <br>
    首页 
  </div>
</template>

在vue的计算属性computed中获取store中的数据,也能实现同样的效果。

src/components/Home.vue修改如下:

<template>
  <div class="home">
    登录状态:{{isLogin}} <br>
    {{username}},你好! <br>
    首页 
  </div>
</template>

<script>
export default {
  name: 'Home',
  computed: {
    isLogin () {
      return this.$store.state.isLogin
    },
    username () {
      return this.$store.state.username
    }
  }
}
</script>

 

 

最终登录页效果:

登录后首页:

至此,基本完成了用户名和密码的存储过程。

说明一下,这个示例没有任何样式。凑活看吧。

 

 

后记

现在看这些东西都很简单的样子,感觉都没必要写出来。但事实上也是绕了很多圈子,最后才明白的。

我尽量写得简单易懂可执行,希望对和我之前一样的新手有所帮助。

于我而言,就当作对知识的梳理吧。

 

参考文档:Vuex官方中文文档 

  

posted on 2019-08-13 18:54  白小鸽  阅读(1369)  评论(1编辑  收藏  举报