Vue3 学习——vue中使用vuex(超详细)

Vue3 学习——vue中使用vuex(超详细)

Vue3 学习——vue中使用vuex(超详细)

回顾: Vue——基础知识学习与项目实操 Vue——配置环境与创建项目

文章目录

Vue3 学习——vue中使用vuex(超详细)一、vuex 介绍二、vuex 应用1、补充(1.1)登录验证方式(1.2)用ajax从url中获取数据并显示

2、vuex 如何维护 state(2.1)store 的构建(2.2)组件访问store(实现组件间交互)(2.3) ajax 实现用户动态页面从云端动态获取(2.4)ajax 实现当前登录用户动态发帖(2.5)ajax 实现当前登录用户动态删帖(2.6)注册功能实现

一、vuex 介绍

通过vuex可方便各个组件间信息传递,vuex类似react中的redux。

全局维护一个对象,该对象是一个状态store树,包含 state 与操作。所有组件之间实现交互时,不需要直接交互,而是分别对维护的全局state进行交互即可。

在store文件夹,默认有 index.js文件。 index.js 中各部分解释如下:

import { createStore } from 'vuex'

// 类似 Redux 中的建立状态树

export default createStore({

// 1、 存储所有全局数据

state: {

},

// 2、 需要通过计算获取state里的内容获取的数据

// 只能读取不可修改

getters: {

},

// 3、定义对state的各种操作

// why不直接实现在mutation里需要写到action里?

// mtations不能执行异步操作。aq:从云端获取信息-->(等待云端反馈)更新到state异步操作

// 因此说:对于异步操作需要放到action里,简单的直接赋值操作可以直接放到mutation里

mutations: {

updataUser(state,user){

state.user.username = user.username;

}

},

// 3、定义对state的各种操作

// actions无法直接修改state,需要在mutations里更新

// mutation不支持异步,所以需要在action里写api到url

actions: {

// 比说action定义了更新state的操作

// 但是不可对其直接修改

// 所有的修改操作必须放到mutations里

},

// state中信息过长时

// 用来将state进行分割

// 如下,将state树分割出一个user state。

modules: {

user: ModuleUser,

}

})

state中信息过长时,modules 用来将state进行分割。 如下,将 state 树分割出一个user state。同样的user下也有这几部分内容:state、getters、mutation、actions、modules。在新建的user. js文件中写入如下代码:

// user. js

const ModuleUser = {

state: {

id: "",

username: "",

photo: "",

},

getters: {

},

mutations: {

updateUser(state,user){

state.id = user.id;

state.username = user.username;

},

},

actions: {

}

modules: {

}

};

export default ModuleUser;

注意:

调用mutation里的方法用 context.commit(store里)或 store.commit(store外) 调用action里的方法用context.dispatch(store)里 或store.dispatch(store外)

补充:

context的话就相当于state的父亲,上一级,包含着state中的所有属性 context:{ state, 等同于store. $ state,若在模块中则为局部状态 rootState, 等同于store. $ state,只存在模块中 commit, 等同于store. $ commit dispatch, 等同于store. $ dispatch getters 等同于store.$ getters } 常规写法调用的时候会使用context.commit,

二、vuex 应用

全局存储用户信息,通过vuex维护实现登录功能与用户信息的访问。 登录操作时,如何向服务器验证。

1、补充

(1.1)登录验证方式

传统用户登录验证方式:(用户信息存在数据库里)

登录时客户端向服务器发送用户名和密码进行验证,然后服务器返回给客户端一个session_id,并将session_id存储到数据库里。 当客户端未来再访问服务器的链接时,都会默认将session_id带上,当服务器接收到客服端请求时,会将session_id取出,去数据库中查看是否存在,若存在,将id对应infomation传递给用户。 session_id 存在cookie 里,跨域(本地当前域名访问域名不同的API)很难处理。 jwt 用户登录验证方式:(用户信息存在jwt中) 登录时客户端向服务器发送用户名和密码进行验证,然后服务器返回给客户端一个jwt,jwt不会存储到数据库里。 当客户端未来再访问服务器请求时,如果请求需要验证,则需要附加上jwt。服务器端可以验证jwt是否合法。 如何验证jwt? 将用户信息info 加上私钥加密后生成签名,将info 与 签名 作为公钥传给用户。未来每次验证用户发送info与签名。服务器将info+私所存钥经过加密算法后如果生成签名,则验证通过。

(1.2)用ajax从url中获取数据并显示

格式如下:

$.ajax({

url:" 链接地址 ",

type: " 方法:POST、GET、DELETE等",

data: { 需要输入的参数 },

headers: {

'Authorization':"Bearer " + access, // 是否验证jwt:

},

success(resp){

成功时的回调函数

}

});

示例如下:

// 从 api 中获取数据

$.ajax({

url: 'https://app165.acapp.acwing.com.cn/myspace/userlist/',

type: 'get',

// resp 为api中的用户列表数据

success(resp) {

users.value = resp;

}

})

// API:输入user_id获取获取某个用户的信息,需要jwt验证

$.ajax({

url: "https://app165.acapp.acwing.com.cn/myspace/getinfo/",

type: "GET",

data: {

user_id: access_obj.user_id,

},

// jwt验证,授权

headers: {

'Authorization':"Bearer " + access,

},

// 这里的resp为当前user_id下的用户信息

success(resp) {

...

}

})

},

error(){

...

}

});

2、vuex 如何维护 state

实现登录页面,向服务器发送用户名和密码,服务器返回jwt。验证登录后显示用户列表信息。实现退出页面,退出时将所获取的jwt删除即可。

(2.1)store 的构建

import $ from "jquery";

import jwt_decode from "jwt-decode";

// 装解码包

const ModuleUser = {

// 1、state 中存储属性信息

state: {

id: "",

username: "",

photo: "",

followerCount: 0,

access: "",

refresh: "",

is_login:false,

},

getters: {

},

// 2、 mutation 中写入需要更改state的操作或者无需异步的操作

// actions无法直接修改state,需要在mutations里更新

// mutation不支持异步,所以需要在action里写api到url

mutations: {

updateUser(state,user){

state.id = user.id;

state.username = user.username;

state.photo = user.photo;

state.followerCount = user.followerCount;

state.access = user.access;

state.refresh = user.refresh;

state.is_login = user.is_login;

},

updateAccess(state,user){

state.access = user.access;

},

// 退出操作:清空jwt即可

// 同步操作,可直接写到mutation

logout(state){

state.id = "";

state.username = "";

state.photo = "";

state.followerCount = 0;

state.access = "";

state.refresh = "";

state.is_login = false;

}

},

// 3、 action 中写入异步操作:用ajax从url中获取数据

// 模仿登录验证时向服务器发送请求,并接收jwt获取信息的过程

// 根据发送的username和password得到access里的userid(和其它信息),然后根据userid得到单个用户的信息

actions: {

// context传API,data 自定义传

login: (context, data) => {

$.ajax({

// API:传入用户名和密码,获取token:得到access和refresh

url: "https://app165.acapp.acwing.com.cn/api/token/",

type: "POST",

data: {

username: data.username,

password: data.password,

},

// 成功的回调函数

success(resp) {

// resp为获取的refresh 对象,此时获得的resp是access和refresh的BS6码,需要解码出来

// 获取refresh对象后解析数出来

const {access,refresh} = resp;

// 解码,需要装解码包,npm i jwt-decode。

const access_obj = jwt_decode(access); //解码后access值包含user_id

// 每隔4.5分钟获取一次,mutation中更新一下access

setInterval(() => {

$.ajax({

// 刷新的JWT的API

url:"https://app165.acapp.acwing.com.cn/api/token/refresh/",

type: "POST",

data: {

refresh,

},

// 无需jwt验证

success(resp){

// 调用mutation中的更新操作(action中不能直接对state进行操作)

context.commit("updateAccess",resp.access);

}

});

},4.5*60*1000)

$.ajax({

// API:输入user_id获取获取某个用户的信息,需要jwt验证

url: "https://app165.acapp.acwing.com.cn/myspace/getinfo/",

type: "GET",

data: {

user_id: access_obj.user_id,

},

// jwt验证,授权

headers: {

'Authorization':"Bearer " + access,

},

// 这里的resp为当前user_id下的用户信息

success(resp) {

// API :第一个参数为mutation里的方法名称字符串。第二个参数为user信息

context.commit("updateUser",{

...resp,

access:access,

refresh:refresh,

is_login:true,

});

// 调用login里的success

data.success();

}

})

},

error(){

// 调用login里的error

data.error();

}

});

}

},

modules: {

}

};

export default ModuleUser;

(2.2)组件访问store(实现组件间交互)

点击Navbar中的登录按钮路由跳转登录组件页面,登录组件访问store中内容。登录组件如下:

// LoginView.vue

点击Navbar中的退出按钮,退出访问store中内容,删除jwt。如下:

// NavBar.vue