1.使用vuex/store管理數據vue
2.登陸註冊邏輯ios
3.Nuxt的本地存儲git
github
<template> <div class="container"> <!-- 主要內容 --> <el-row type="flex" justify="center" align="middle" class="main"> <div class="form-wrapper"> <!-- 表單頭部tab --> <el-row type="flex" justify="center" class="tabs"> <span :class="{active: currentTab === index}" v-for="(item, index) in [`登陸`, `註冊`]" :key="index" @click="handleChangeTab(index)"> {{item}} </span> </el-row> <!-- 登陸功能組件 --> <LoginForm v-if="currentTab == 0"/> <!-- 註冊功能組件 --> <!-- <RegisterForm v-if="currentTab == 1"/> --> </div> </el-row> </div> </template> <script> import LoginForm from '@/components/user/loginForm' export default { components: { LoginForm }, data(){ return { currentTab: 0 } }, methods: { handleChangeTab(index){ this.currentTab = index; }, } } </script> <style scoped lang="less"> .container{ background:url(http://157.122.54.189:9095/assets/images/th03.jfif) center 0; height: 700px; min-width:1000px; .main{ width:1000px; height: 100%; margin:0 auto; position: relative; .form-wrapper{ width:400px; margin:0 auto; background:#fff; box-shadow: 2px 2px 0 rgba(0,0,0,0.1); overflow:hidden; .tabs{ span{ display: block; width:50%; height: 50px; box-sizing: border-box; border-top:2px #eee solid; background:#eee; line-height: 48px; text-align: center; cursor: pointer; color:#666; &.active{ color:orange; border-top-color: orange; background:#fff; font-weight: bold; } } } } } } </style>
思路:vuex
1.在components/user中新建loginForm.vue表單組件axios
2.使用Element-ui的表單組件服務器
3.表單數據綁定app
4.表單驗證less
5.登陸接口異步
實現步驟:
1.新建loginForm.vue表單組建
<template> <el-form :model="form" ref="form" :rules="rules" class="form"> <el-form-item class="form-item"> <el-input placeholder="用戶名/手機"> </el-input> </el-form-item> <el-form-item class="form-item"> <el-input placeholder="密碼" type="password"> </el-input> </el-form-item> <p class="form-text"> <nuxt-link to="#">忘記密碼</nuxt-link> </p> <el-button class="submit" type="primary" @click="handleLoginSubmit"> 登陸 </el-button> </el-form> </template> <script> export default { data(){ return { // 表單數據 form: {}, // 表單規則 rules: {}, } }, methods: { // 提交登陸 handleLoginSubmit(){ console.log(this.form) } } } </script> <style scoped lang="less"> .form{ padding:25px; } .form-item{ margin-bottom:20px; } .form-text{ font-size:12px; color:#409EFF; text-align: right; line-height: 1; } .submit{ width:100%; margin-top:10px; } </style>
<!-- 登陸功能組件 -->
<!-- <LoginForm v-if="currentTab == 0"/> -->
2.表單數據綁定
// 其餘代碼... data(){ return { // 表單數據 form: { username: "", // 登陸用戶名/手機 password: "" // 登陸密碼 }, // 其餘代碼... } }, // 其餘代碼...
<!-- 其餘代碼... --> <el-form-item class="form-item"> <!-- 新增了v-model --> <el-input placeholder="用戶名/手機" v-model="form.username"> </el-input> </el-form-item> <el-form-item class="form-item"> <!-- 新增了v-model --> <el-input placeholder="密碼" type="password" v-model="form.password"> </el-input> </el-form-item> <!-- 其餘代碼... -->
3.表單驗證
// 其餘代碼... data(){ return { // 其餘代碼... // 表單規則 rules: { username: [ { required: true, message: '請輸入用戶名', trigger: 'blur' }, ], password: [ { required: true, message: '請輸入密碼', trigger: 'blur' }, ], }, } }, // 其餘代碼...
<!-- 其餘代碼... --> <!-- 新增了prop屬性 --> <el-form-item class="form-item" prop="username"> <el-input placeholder="用戶名/手機" v-model="form.username"> </el-input> </el-form-item> <!-- 新增了prop屬性 --> <el-form-item class="form-item" prop="password"> <el-input placeholder="密碼" type="password" v-model="form.password"> </el-input> </el-form-item> <!-- 其餘代碼... -->
4.登陸接口
接下來要調用登陸的接口進行登陸了,若是一切正常的話,咱們能夠看到後臺返回的用戶信息,若是登陸失敗,咱們須要對統一對錯誤的返回進行處理,這個咱們在最後再統一實現。
// 其餘代碼... // 提交登陸 methods: { handleLoginSubmit(){ // 驗證表單 this.$refs['form'].validate((valid) => { // 爲true表示沒有錯誤 if (valid) { this.$axios({ url: "/accounts/login", method: "POST", data: this.form }).then(res => { console.log(res.data); }) } }) } } // 其餘代碼...
帳號:13800138000
密碼:123456
若是正常登陸應該能夠在控制看到打印出來的用戶信息,則表示登陸成功了。
5.總結
使用Element-ui
的表單組件綁定數據和驗證表單
調用登陸接口
思路:
實現步驟:
// 每一個小倉庫都必須暴露出 state, mutations
export const state = {
userInfo: {
// 用戶驗證的token
token: "",
// 用戶信息
user: {
}
}
}
export const mutations = {
// 設置用戶信息
setUserInfo(state, data){
state.userInfo = data;
}
}
在登陸請求發送成功後存儲用戶輸入的數據到vuex的store倉庫中。
// 提交登陸 handleLoginSubmit(){ // 驗證表單 this.$refs['form'].validate((valid)=>{ // 爲true表示沒有錯誤 if(valid){ this.$axios({ url: '/accounts/login', method: 'POST', data: this.form }).then(res=>{ // 1.保存到vuex, 注意調用方法時加上命名空間,也就是方法所在的模塊user this.$store.commit('user/setUserInfo', res.data) }) } }) }
在頁面中顯示用戶登陸的手機號,在header.vue組件中替換下面代碼。
<span class="el-dropdown-link"> <img src="http://157.122.54.189:9095/assets/images/avatar.jpg" alt=""> {{this.$store.state.user.userInfo.user.username}} <i class="el-icon-arrow-down el-icon--right"></i> </span>
nuxt下的store的使用
1.先新建數據的模塊,一個模塊就是一個文件,文件名字就是模塊的名字,好比新建一個user模塊,每一個模塊裏面能夠暴露出3個經常使用的屬性
// 每一個小倉庫都必須暴露出 state, mutations export const state = { userInfo: { // 用戶驗證的token token: "", // 用戶信息 user: { } } } export const mutations = { // 設置用戶信息 setUserInfo(state, data){ state.userInfo = data; } }
2.讀取user下面的用戶
{{ $store.state.user.userInfo.user.username }}
3.調用mutations下的方法時候必需要帶有模塊名稱
// 1.保存到vuex this.$store.commit("user/setUserInfo", res.data);
由於這個項目是Node.js項目,因此不能使用使用localStorage方法來存儲,這裏須要安裝一個插件解決這個本地存儲問題。
安裝:yarn add vuex-persistedstate
配置nuxt.config.js,在plugins中添加下面配置。
{ src: '~/plugins/localStorage.js', ssr: false }
在plugins目錄中新建localStorage.js並添加以下代碼。
// ~/plugins/localStorage.js import createPersistedState from 'vuex-persistedstate' export default ({store}) => { window.onNuxtReady(() => { createPersistedState({ key: 'store' })(store) }) }
使用一個第三方的插件vuex-persistedstate
, 經過這個插件會自動把store的數據保存到本地,而且在應用加載完後會自動把本地的數據從新賦值給store。
當本地保存的數據被清除後,頁面中仍會顯示頭像,應該顯示的是"登陸/註冊"按鈕,修改爲下面的代碼便可。
<div> <div v-if="!$store.state.user.userInfo.token"> <nuxt-link to="/user/login">登陸 / 註冊</nuxt-link> </div> <div v-else> <el-dropdown> <span class="el-dropdown-link"> <img :src="$axios.defaults.baseURL + $store.state.user.userInfo.user.defaultAvatar" alt /> {{this.$store.state.user.userInfo.user.username}} <i class="el-icon-arrow-down el-icon--right" ></i> </span> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>我的中心</el-dropdown-item> <el-dropdown-item>退出</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </div>
給header.vue組件中的退出按鈕添加一個退出事件
<!-- 給經過native給elementUI組件綁定原生事件 --> <el-dropdown-item @click.native="handleLogout">退出</el-dropdown-item>
methods: { // 退出登陸,清空本地用戶數據 handleLogout(){ this.$store.commit('user/clearUserInfo'); } }
在store/user.js模塊的mutations中添加一個清空數據的方法。
// 設置用戶數據爲空 clearUserInfo(state){ state.userInfo = {}; }
登陸成功以後跳轉到首頁,在loginForm.vue中添加下面代碼。
// 跳轉到首頁 this.$router.push("/");
actions是異步的修改倉庫的數據,而且依賴mutations。
mutations:用於同步修改倉庫的數據。
actions:用於異步修改倉庫的數據,例如登陸。
將發送登陸請求的代碼寫到actions的方法裏面,方便之後維護和調用。
在store/user.js中新增actions。
// 異步修改倉庫的數據 export const actions = { // login(store, data){ login({commit}, data){ return this.$axios({ url: "/accounts/login", method: "POST", data:data }).then(res => { // store.commit("setUserInfo", res.data) commit("setUserInfo", res.data) // 1.保存到vuex, 注意調用方法時加上命名空間,也就是方法所在的模塊user // 登陸後的行爲應該由調用的頁面去執行,不能寫死,由於每一個頁面登陸成功執行的操做可能不同 // this.$router.push("/"); }); } }
loginForm.vue組件中的發送登陸請求方法的代碼改成:
methods: { // 提交登陸 handleLoginSubmit() { // 驗證表單 this.$refs["form"].validate(valid => { // 爲true表示沒有錯誤 if (valid) { this.$store.dispatch('user/login', this.form).then(res=>{ this.$router.push('/'); }) } }); } }
什麼狀況下把方法封裝到actions?
異步的方法須要複用的時候,能夠考慮把方法封裝到actions,好比登陸這些方法。
actions要怎麼聲明?
actions裏面的方法第一個參數是store對象,這個對象下面能夠訪問到全部store的屬性(commit, dispatch, state...)用commit修改state數據;
第二個是可選的,是傳遞進來的參數。
怎麼調用actions的方法?
this.$store.dispatch('user/login', this.form).then(res=>{ this.$router.push('/'); })
何時使用Vuex?
項目數據比較多,須要多個組件去共享數據的時候能夠使用vuex
怎麼使用?
state: 存儲數據
mutations: 設置修改state的數據
actions: 異步修改state的數據,把能夠複用的請求放到actions裏面(actions須要調用mutations的方法修改數據)
使用時候注意的問題
單詞別寫錯
注意調用mutations和actions的方法記得加上模塊名字(命名空間)