最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vuex中mutations和actions的區(qū)別及說(shuō)明

 更新時(shí)間:2022年12月09日 09:17:39   作者:多看書少吃飯  
這篇文章主要介紹了Vuex中mutations和actions的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

mutation

我們知道,在使用vuex對(duì)項(xiàng)目狀態(tài)進(jìn)行管理時(shí),只能使用commit來(lái)提交mutation對(duì)store中的狀態(tài)進(jìn)行更改

Vuex 中的 mutation 非常類似于事件:每個(gè) mutation 都有一個(gè)字符串的 事件類型 (type) 和 一個(gè) 回調(diào)函數(shù) (handler)。這個(gè)回調(diào)函數(shù)就是我們實(shí)際進(jìn)行狀態(tài)更改的地方,并且它會(huì)接受 state 作為第一個(gè)參數(shù):

const store = new Vuex.Store({
? state: {
? ? count: 1
? },
? mutations: {
? ? increment (state) {
? ? ? // 變更狀態(tài)
? ? ? state.count++
? ? }
? }
})
//你不能直接調(diào)用一個(gè) mutation handler。這個(gè)選項(xiàng)更像是事件注冊(cè):“當(dāng)觸發(fā)一個(gè)類型為 increment 的 mutation 時(shí),調(diào)用此函數(shù)?!币獑拘岩粋€(gè) mutation handler,你需要以相應(yīng)的 type 調(diào)用 store.commit 方法:
store.commit('increment') ??

Mutation 必須是同步函數(shù)

mutations: {
? someMutation (state) {
? ? api.callAsyncMethod(() => {
? ? ? state.count++
? ? })
? }
}

我們注意上面這段代碼,在mutation里面加入了異步處理的函數(shù)。

其實(shí)mutation是可以正常使用的,但是我們?cè)谌粘5拈_(kāi)發(fā)中debug的時(shí)候,我們需要查看devtool中的mutation日志。

理論上來(lái)說(shuō),是mutation走一步,devtool記錄一步,但是在mutation中加入異步函數(shù)就會(huì)導(dǎo)致我們devtool的記錄失敗,因?yàn)閐evtool不知道你里面的異步函數(shù)什么時(shí)候調(diào)用,在哪里調(diào)用

Action

Action 類似于 mutation,不同在于:

Action 提交的是 mutation,而不是直接變更狀態(tài)。

Action 可以包含任意異步操作。

const store = new Vuex.Store({
? state: {
? ? count: 0
? },
? mutations: {
? ? increment (state) {
? ? ? state.count++
? ? }
? },
? actions: {
? ? increment (context) {
? ? ? context.commit('increment')
? ? }
? }
})

Action 函數(shù)接受一個(gè)與 store 實(shí)例具有相同方法和屬性的 context 對(duì)象,因此你可以調(diào)用 context.commit 提交一個(gè) mutation,或者通過(guò) context.state 和 context.getters 來(lái)獲取 state 和 getters。

實(shí)踐中,我們會(huì)經(jīng)常用到 ES2015 的 參數(shù)解構(gòu) (opens new window)來(lái)簡(jiǎn)化代碼(特別是我們需要調(diào)用 commit 很多次的時(shí)候):

actions: {
? increment ({ commit }) {
? ? commit('increment')
? }
}

在實(shí)際開(kāi)發(fā)的store文件中

// src/store/index.js

import Vue from 'vue';
import Vuex from '@/vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
? state: {
? ? num: 10
? },
? getters: {
? ? getPrice(state) {
? ? ? return state.num * 10
? ? }
? },
? // 同步更新?tīng)顟B(tài)
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'

const user = {
? state: {
? ? token: getToken(),
? ? name: '',
? ? avatar: '',
? ? roles: [],
? ? permissions: []
? },
//同步方法
? mutations: {
? ? SET_TOKEN: (state, token) => {
? ? ? state.token = token
? ? },
? ? SET_NAME: (state, name) => {
? ? ? state.name = name
? ? },
? ? SET_AVATAR: (state, avatar) => {
? ? ? state.avatar = avatar
? ? },
? ? SET_ROLES: (state, roles) => {
? ? ? state.roles = roles
? ? },
? ? SET_PERMISSIONS: (state, permissions) => {
? ? ? state.permissions = permissions
? ? }
? },
//異步方法
? actions: {
? ? // 登錄(使用單點(diǎn)登錄此處就作廢)
? ? Login({ commit }, userInfo) {
? ? ? const loginType = userInfo.loginType
? ? ? const tentantCode = userInfo.tentantCode
? ? ? const username = userInfo.username.trim()
? ? ? const password = userInfo.password
? ? ? const code = userInfo.code
? ? ? const uuid = userInfo.uuid
? ? ? return new Promise((resolve, reject) => {
? ? ? ? login(loginType, tentantCode, username, password, code, uuid).then(res => {
? ? ? ? ? setToken(res.token)
? ? ? ? ? commit('SET_TOKEN', res.token)
? ? ? ? ? resolve()
? ? ? ? }).catch(error => {
? ? ? ? ? reject(error)
? ? ? ? })
? ? ? })
? ? },

? ? // 獲取用戶信息
? ? GetInfo({ commit, state }) {
? ? ? return new Promise((resolve, reject) => {
? ? ? ? getInfo().then(res => {
? ? ? ? ? if (res.data.rolePermission
? ? ? ? ? ? && res.data.rolePermission
? ? ? ? ? ? > 0) { // 驗(yàn)證返回的roles是否是一個(gè)非空數(shù)組
? ? ? ? ? ? commit('SET_ROLES', res.roles)
? ? ? ? ? ? commit('SET_PERMISSIONS', res.permissions)
? ? ? ? ? } else {
? ? ? ? ? ? commit('SET_ROLES', ['ROLE_DEFAULT'])
? ? ? ? ? }
? ? ? ? ? commit('SET_NAME', res.data.nickName
? ? ? ? ? )
? ? ? ? ? commit('SET_AVATAR', res.data.avatar)
? ? ? ? ? resolve(res)
? ? ? ? }).catch(error => {
? ? ? ? ? reject(error)
? ? ? ? })
? ? ? })
? ? },

? ? // 退出系統(tǒng)
? ? LogOut({ commit, state }) {
? ? ? return new Promise((resolve, reject) => {
? ? ? ? logout(state.token).then(() => {
? ? ? ? ? commit('SET_TOKEN', '')
? ? ? ? ? commit('SET_ROLES', [])
? ? ? ? ? commit('SET_PERMISSIONS', [])
? ? ? ? ? removeToken()
? ? ? ? ? resolve()
? ? ? ? }).catch(error => {
? ? ? ? ? reject(error)
? ? ? ? })
? ? ? })
? ? },

? ? // 前端 登出
? ? FedLogOut({ commit }) {
? ? ? return new Promise(resolve => {
? ? ? ? commit('SET_TOKEN', '')
? ? ? ? removeToken()
? ? ? ? resolve()
? ? ? })
? ? }
? }
}

export default user

比如我們?cè)诘卿浀臅r(shí)候需要觸發(fā)store中的方法

<template>
? <div>單點(diǎn)登錄頁(yè)面</div>
</template>

<script>
import {
? doLoginByTicket,
? getInfo,
? isLogin,
? getSsoAuthUrl,
? getRouter,
} from "../api/login";
import { getToken, setToken } from "@/utils/auth";
export default {
? name: "Screenfull",
? data() {
? ? return {};
? },
? created() {
? ? this.checkIsLogin();
? },

? methods: {
? ? checkIsLogin() {
? ? ? isLogin().then((res) => {
? ? ? ? if (res.data == true) {
? ? ? ? ? //獲取用戶信息;
? ? ? ? ? console.log("isLogin", res);
? ? ? ? ? // this.$router.push("/");
? ? ? ? } else {
? ? ? ? ? //獲取請(qǐng)求進(jìn)來(lái)的完整url
? ? ? ? ? let url = window.location.href;
? ? ? ? ? if (url.indexOf("ticket=") < 0) {
? ? ? ? ? ? //如果沒(méi)有ticket
? ? ? ? ? ? getSsoAuthUrl({ clientLoginUrl: url }).then((res) => {
? ? ? ? ? ? ? window.location.href = res.data;
? ? ? ? ? ? });
? ? ? ? ? ? return;
? ? ? ? ? }
? ? ? ? ? let tstr = url
? ? ? ? ? ? .substring(url.indexOf("?") + 1)
? ? ? ? ? ? .split("=")[1]
? ? ? ? ? ? .split("#")[0]; //先截取url的?后面的參數(shù)部分,在根據(jù)&分割成參數(shù)數(shù)組
? ? ? ? ? doLoginByTicket({ ticket: tstr }).then((res) => {
? ? ? ? ? ? if (res.code == 200) {
? ? ? ? ? ? ? setToken(res.data);
? ? ? ? ? ? ? getInfo().then((res) => {
? ? ? ? ? ? ? ? if (res.data.rolePermission) {
? ? ? ? ? ? ? ? //觸發(fā)mutations同步方法
? ? ? ? ? ? ? ? ? this.$store.commit("SET_ROLES", ["admin"]);
? ? ? ? ? ? ? ? ? this.$store.commit("SET_PERMISSIONS", ["*:*:*"]);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? commit("SET_ROLES", ["ROLE_DEFAULT"]);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? this.$store.commit("SET_NAME", res.data.nickName);
? ? ? ? ? ? ? });
? ? ? ? ? ? ? getRouter().then(() => {
?? ??? ??? ??? ?//觸發(fā)actions異步方法
? ? ? ? ? ? ? ? this.$store.dispatch("GenerateRoutes");
? ? ? ? ? ? ? ? window.location.reload();
? ? ? ? ? ? ? });
? ? ? ? ? ? } else {
? ? ? ? ? ? ? console.log("檢查票據(jù)失敗");
? ? ? ? ? ? }
? ? ? ? ? });
? ? ? ? }
? ? ? });
? ? },
? },
};
</script>

<style lang="scss" scoped></style>

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue使用new Image()實(shí)現(xiàn)圖片預(yù)加載功能

    Vue使用new Image()實(shí)現(xiàn)圖片預(yù)加載功能

    這篇文章主要介紹了如何在 Vue 中實(shí)現(xiàn)圖片預(yù)加載的一個(gè)簡(jiǎn)單小demo以及優(yōu)化方案,文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-11-11
  • Vue可自定義tab組件用法實(shí)例

    Vue可自定義tab組件用法實(shí)例

    在本篇文章里小編給大家分享了關(guān)于Vue可自定義tab組件用法實(shí)例以及相關(guān)知識(shí)點(diǎn),需要的朋友們參考下。
    2019-10-10
  • Vue通知提醒框(Notification)圖文詳解

    Vue通知提醒框(Notification)圖文詳解

    最近有個(gè)項(xiàng)目需求就是在客戶端的右上角要實(shí)時(shí)展示提醒消息,下面這篇文章主要給大家介紹了關(guān)于Vue通知提醒框(Notification)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • 基于Vue.js實(shí)現(xiàn)一個(gè)完整的登錄功能

    基于Vue.js實(shí)現(xiàn)一個(gè)完整的登錄功能

    在現(xiàn)代Web應(yīng)用中,用戶登錄功能是一個(gè)核心模塊,它不僅涉及到用戶身份驗(yàn)證,還需要處理表單驗(yàn)證、狀態(tài)管理、接口調(diào)用等多個(gè)環(huán)節(jié),本文將基于一個(gè)Vue.js項(xiàng)目中的登錄功能實(shí)現(xiàn),深入解析其背后的技術(shù)細(xì)節(jié),幫助開(kāi)發(fā)者更好地理解和實(shí)現(xiàn)類似功能,需要的朋友可以參考下
    2025-02-02
  • 詳解VS Code使用之Vue工程配置format代碼格式化

    詳解VS Code使用之Vue工程配置format代碼格式化

    這篇文章主要介紹了詳解VS Code使用之Vue工程配置format代碼格式化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 使用Vue與Firebase構(gòu)建實(shí)時(shí)聊天應(yīng)用的示例代碼

    使用Vue與Firebase構(gòu)建實(shí)時(shí)聊天應(yīng)用的示例代碼

    隨著互聯(lián)網(wǎng)通訊技術(shù)的不斷進(jìn)步,實(shí)時(shí)聊天應(yīng)用現(xiàn)在已成為我們?nèi)粘I钪胁豢苫蛉钡囊徊糠?無(wú)論是社交媒體平臺(tái)、工作溝通工具還是客戶支持系統(tǒng),實(shí)時(shí)聊天都在不斷被需求,今天,我們將介紹如何使用Vue.js與Firebase來(lái)構(gòu)建一個(gè)簡(jiǎn)單而強(qiáng)大的實(shí)時(shí)聊天應(yīng)用,需要的朋友可以參考下
    2024-11-11
  • 詳解如何實(shí)現(xiàn)Element樹(shù)形控件Tree在懶加載模式下的動(dòng)態(tài)更新

    詳解如何實(shí)現(xiàn)Element樹(shù)形控件Tree在懶加載模式下的動(dòng)態(tài)更新

    這篇文章主要介紹了詳解如何實(shí)現(xiàn)Element樹(shù)形控件Tree在懶加載模式下的動(dòng)態(tài)更新,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • Vue2.0結(jié)合webuploader實(shí)現(xiàn)文件分片上傳功能

    Vue2.0結(jié)合webuploader實(shí)現(xiàn)文件分片上傳功能

    這篇文章主要介紹了Vue2.0結(jié)合webuploader實(shí)現(xiàn)文件分片上傳功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-03-03
  • Vue 自定義組件 v-model 使用詳解

    Vue 自定義組件 v-model 使用詳解

    這篇文章主要介紹了Vue 自定義組件 v-model 使用介紹,包括vue2中使用和vue3中使用,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • vue-cli3設(shè)置代理無(wú)效的解決

    vue-cli3設(shè)置代理無(wú)效的解決

    這篇文章主要介紹了vue-cli3設(shè)置代理無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評(píng)論

凤城市| 潮州市| 塔河县| 临漳县| 万山特区| 安徽省| 昌都县| 巴楚县| 五家渠市| 改则县| 民乐县| 宜丰县| 田东县| 龙游县| 报价| 会理县| 克东县| 泽库县| 固始县| 白沙| 琼海市| 乌兰县| 清河县| 方山县| 朝阳县| 铅山县| 河南省| 尼勒克县| 惠安县| 将乐县| 东海县| 雅江县| 岑巩县| 金堂县| 阳春市| 昌都县| 永城市| 前郭尔| 嵩明县| 漳州市| 甘肃省|