iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 24
0
Modern Web

實作小範例入門 Vue & Vuex 2.0系列 第 24

vue & vuex 24 - Login - I (action Promise、rouetr change)

前面做了幾個範例,今天我們來做一個登入頁面,試試看 vue-router 轉跳頁面以及 vuex 如何驗證搭配 Promise 使用。

vue & vuex 24 - Login

今天目標:

  1. 新增 login page
  2. 預設顯示 login
  3. 登入成功轉跳到 Hello page

Template use bootstrap example signin


login 算是全域行為,所以就不細分成 module 直接設計在 root 裡面。

vuex action Promise

有時候發出去的 action 是非同步事件,可是 vue UI 需要知道事件回傳的狀態是 successerror

如果,這樣的狀態不太需要存在 vuex 裡面。

我們就可以利用 ES6 Promise 包裝,回傳 resolvereject 來反應 UI 變化。

Promise

  • resolve 結果會在 then 裡面收到,
  • reject 結果會在 catch 裡面收到。

store/root.js

export const actions = {
  // login
  actionLogin ({ commit }, { email, password}) {
    // 目前沒找到比較好的範例 API,因此使用延遲 1.5s 模擬 ajax 以及簡單驗證。
    console.log('1. actionLogin');
    commit(types.LOADING, true); // 打開遮罩
    // 使用 Promise 包裝 API
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (email === 'vue_vuex2@ironman2017.tw' && password === '123') {
          console.log('2. Promise resolve');
          commit(types.LOADING, false); // 關閉遮罩
          resolve(); // resolve 結果會在 then 裡面收到
        }
        // error
        else {
          commit(types.LOADING, false); // 關閉遮罩
          reject(); // reject 結果會在 catch 裡面收到
        }
      }, 1500);
    });
  }
}

vue-router 轉跳

使用 $router.push 轉跳到 hello Page

// path
$router.push('/hello');
// name
$router.push({name: 'hello'});

login.vue

<template>
  <div id="login">
    <img src="static/img/ironman2017.jpg" class="responsive-img">
    <div class="container">
      <div class="form-signin">
        <h2 class="form-signin-heading">Please sign in</h2>
        <label for="email" class="sr-only">Email address</label>
        <input
          v-model="email"
          type="email"
          id="email"
          class="form-control"
          placeholder="Email address" required autofocus />
        <label for="inputPassword" class="sr-only">Password</label>
        <input
          v-model="password"
          @keyup.enter="login"
          type="password"
          id="inputPassword"
          class="form-control"
          placeholder="Password" required />
        <button 
          class="btn btn-lg btn-primary btn-block"
          type="submit"
          @click="login">
          Sign in
        </button>
        <br/>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'

export default {
  data () {
    return {
      email: 'vue_vuex2@ironman2017.tw',
      password: '',
    }
  },
  methods: {
    login () {
	  // 因為 action 包裝了 Promise 所以可以使用 then 和 catch 來接收非同步回傳狀態
      this.$store.dispatch('actionLogin', {
        email: this.email,
        password: this.password
      })
      .then(() => { // 接收 resolve
        console.log('3. get Promise resolve');
        setTimeout(() => {
          // 使用 $router.push 轉跳到 hello Page
          this.$router.push('/hello');
        }, 1000);
      })
      .catch(() => { // 接收 reject
        console.log('error get Promise reject!');
      });
    }
  }
}
</script>

Promise 流程

順序 框架 事件 回傳
1 Vue 按下登入按鈕 發動 action
2 vuex action 使用 ajax 調用 API
3-1 vuex ajax response success resolve
4-1 Vue action method .then 接收 resolve
3-2 vuex ajax response error reject
4-2 Vue action method .catch 接收 reject

vue & vuex 24 Promise 流程


github 完整範例:

實作小範例入門 Vue & Vuex 2.0 - github 完整範例

使用 git checkout 切換每天範例。


上一篇
vue & vuex 23 - Open Data - III (搜尋條件、select option、v-else、watch)
下一篇
vue & vuex 25 - Login - II (router auth、rouetr beforeEach)
系列文
實作小範例入門 Vue & Vuex 2.030

尚未有邦友留言

立即登入留言