前言
本來只是想寫個Vuet實現登入退出的例子的,但是又覺得這樣乾貨太少。一個好的開源專案,少不了單元測試和e2e測試,為了保證Vuet教程的豐富性和程式的穩定性,所以我選擇了寫的例子即能當教程使用,也可以用於測試,豐富的應用場景和測試,能保證日後的版本迭代不會因為修復了一個bug而引發了一大堆bug的尷尬。
原始碼地址
執行Vuet專案
git clone https://github.com/medevicex/vuet.git
npm install
npm run dev
npm run dev:test # 執行測試,需要電腦本地安裝firefox和chrome瀏覽器複製程式碼
開始
哈哈,上面直接拋原始碼地址,感覺也是挺尷尬的,我們先分析一下我們這個登入退出所需要所的功能
- 登入頁面,使用者資訊頁面,是兩個不同的頁面,就涉及到了多元件狀態共享
- 我期望使用者在已登入的情況下,每次到使用者資訊頁面時,先渲染本地的使用者資訊,然後再去請求伺服器更新本地的使用者資訊
- 將登入退出的方法,集中起來管理,方面在在各個元件中呼叫
多元件共享狀態和方法
Vuet提供了全域性的mapModules方法,可以讓我們連線到掛載在Vue例項上的Vuet例項
ages/Home.vue
import { mapRules, mapModules } from 'vuet'
export default {
mixins: [
// manual:規則,可以將通用的更新模組狀態的方法集中起來,
// 可以理解成vuex中的action,只不過他是可以允許在裡面更改模組狀態的
// need 規則,會在元件每一次的beforeCreate鉤子中,傳送請求更新一次使用者的資訊
mapRules({ manual: 'user', need: 'user' }),
// 連線使用者模組
mapModules({ user: 'user' })
]
}複製程式碼
定義一個user模組
vuet/user.js
export default {
data () {
// 一個Object物件中,是否有data方法,是構成Vuet.js一個模組的依據
// 當你呼叫reset方法時,將會重置整個模組的狀態
// 例如在元件中:this.$vuet.reset('模組名稱')
return {
name: null,
age: null,
sex: null,
count: 0
}
},
async fetch ({ state }) {
// 當need規則觸發更新時,出呼叫一次fetch方法更新
// 我們可以在這裡直接更改state,也可以return一個Object物件來更新狀態
// 在實際專案中,使用者未登入時,我們並不需要向伺服器傳送真正的請求
// 所以我們可以判斷一下使用者的名稱是否存在,否則的話不向伺服器進行真正的請求
if (state.name === null) return
// 下面資料因為是模擬的,所以就直接return好了
return {
name: 'Vuet',
age: 18,
sex: 'male',
count: ++state.count
}
},
// 注:你要在元件中使用manual規則才能向元件注入這些方法
// 例如:mapRules({ manual: '模組名稱' })
// 呼叫:this.$模組名稱.xxx()
manuals: {
async signin ({ state }, from) { // 定義了一個登入的方法
if (from.name === 'Vuet' && from.pass === '2017') {
return {
success: true,
msg: 'Login was successful',
data: {
name: 'Vuet',
age: 18,
sex: 'male',
count: ++state.count
}
}
}
return {
success: false,
msg: 'Logon failure',
data: null
}
},
async sigout () {
// 使用者選擇退出後,直接呼叫reset的方法即可重置使用者資訊
this.reset()
}
}
}複製程式碼
實現使用者登入
pages/Signin.vue
<template>
<div class="inner">
<b class="msg" style="color:red" v-if="msg">{{ msg }}</b>
<form @submit.prevent="submit">
<div>
<label>User name:<input class="name" type="text" v-model="form.name"></label>
</div>
<div>
<label>Password:<input class="pass" type="password" v-model="form.pass"></label>
</div>
<button>Signin</button>
</form>
</div>
</template>
<script>
import { mapRules, mapModules } from 'vuet'
export default {
mixins: [
// 使用manual規則取得user模組裡面manuals的方法
mapRules({ manual: 'user' }),
// 連線使用者的模組資訊
mapModules({ user: 'user' })
],
data () {
return {
msg: null,
form: {
name: null,
pass: null
}
}
},
methods: {
async submit () {
const res = await this.$user.signin(this.form)
this.msg = res.msg
if (res.success) {
// 登入成功後,直接賦值更新使用者資訊
this.user = res.data
setTimeout(() => {
this.$router.replace({ name: 'home' })
}, 500)
}
}
}
}
</script>
<style scoped>
</style>複製程式碼
總結
其實教程並沒有寫得特別詳細的過程,主要是為了體現出Vuet一種開放的姿態,它可以在任意元件直接對模組的狀態進行直接的賦值更新,也可以使用類似action的方法進行更新,它可以讓你為所欲為,用得好的人可以讓你開發的效率飆升,用得不好,也會導致你程式中的狀態難以追蹤變化的記錄。哈哈,不小心被嚇到了吧,其實這些都是有辦法可以解決的,下次有機會,我們可以再討論一下使用Vuet的正確姿勢。