結合 Vue.observable 寫一個簡易 Vuex

来源:https://www.cnblogs.com/wisewrong/archive/2019/09/10/11497394.html
-Advertisement-
Play Games

作為 Vue 全家桶的一員,Vuex 的重要性不言而喻,不管是用來管理狀態,還是封裝 Controler 都很好用 不過在一些體量較小的項目中,為了幾個簡單的狀態或者處理函數而引入 Vuex,就像是高射炮打蚊子,大材小用了 這時候就可以模擬 Vuex,自己寫一個簡單的 Store, 用來管理狀態並 ...


作為 Vue 全家桶的一員,Vuex 的重要性不言而喻,不管是用來管理狀態,還是封裝 Controler 都很好用

不過在一些體量較小的項目中,為了幾個簡單的狀態或者處理函數而引入 Vuex,就像是高射炮打蚊子,大材小用了

這時候就可以模擬 Vuex,自己寫一個簡單的 Store, 用來管理狀態並實時更新數據

 

 

一、構造函數

模擬 Vuex 的結構,創建一個 Class

export default class Store {
  constructor({ states, actions, mutations }) {
    // 狀態
    this.states = states || {};
    // 非同步函數
    this.actions = actions || {};
    // 同步函數
    this.mutations = mutations || {};
  }
  // 調用 mutations 中的同步函數
  commit = (fun, params) => {};
  // 調用 actions 中的非同步函數
  dispatch = (fun, params) => {};
  // 更新 states 的狀態
  update = (key, value) => {};
}

 

然後實例化一個 Store

import Store from './store';

import states from './states';
import actions from './actions';
import mutations from './mutations';

const store = new Store({
  states,
  actions,
  mutations,
});

export default store;

 

然後掛到 vue 的原型上,通過 vue.$store 的方式使用,一個高仿 vuex 的架子就搭好了

// 在 main.js 中引入 Store
import store from './store/index';
Vue.prototype.$store = store;

 

 

二、實現操作函數(commit、dispatch、update

在 Vuex 中,如果需要更新 state 中的狀態,需要通過 commit 調用 mutations 中的方法

而 mutations 的方法都具備一個預設的參數 state,因此 commit 方法可以這麼寫:

// 向 mutations 中的傳入固定參數 state
commit = (fun, params) => {
  this.mutations[fun](this.states, params);
};

 

不過由於一些歷史遺留問題,我習慣用 this.states 的方式獲取 state(這個習慣不好),所以改成了這樣:

  commit = (fun, params) => {
    if (fun) {
      this.mutations[fun].call(this, params);
    } else {
      return false;
    }
  };

類似的 actions 和 update 可以參考 commit 的寫法

 

 

三、響應式對象

目前的 store 有一個致命的問題:state 更新之後並不會即時渲染到視圖層

這時候 Vue 2.6.0 新增的 observable() 就派上用場了

 

如果將一個對象作為入參傳給 Vue.observable() ,經過處理之後,這個對象在 Vue 內就可以實時更新

其返回值可以直接用於 render 和 computed 中,並且會在發生改變時觸發相應的更新

 

於是 Store 的構造函數需要改一改:

  constructor({ states, actions, mutations }) {
    // 狀態
    this.states = Vue.observable(states || {});
    // 非同步函數
    this.actions = Vue.observable(actions || {});
    // 同步函數
    this.mutations = Vue.observable(mutations || {});
  }

 

⚠️註意:

假如對象 obj 經過 observable() 處理之後,賦值給了新對象 new_boj

在 Vue 2.x 中,直接修改 obj 也會觸發 new_boj 的更新

但在 Vue 3.x 中,由於響應機制的變更,只有修改 new_obj 才能觸發視圖層的更新

所以在使用 observable() 的時候,最好始終操作使用 observable() 處理後的 new_obj

 

 

四、簡單用用

超低配的 Vuex 已經寫好了,上面已經把 store 掛到 Vue 的原型上,所以可以直接使用

假如 state 中已經存在一個狀態 name,在組件中可以通過 computed 去獲取

computed: {
    name() {
      return this.$store.states.name;
    },
}

如果需要修改狀態,可以通過 $store.update()

methods: {
    updateName(val) {
        this.$store.update('name', val);
    }  
}

或者使用 $store.commit() 調用 mutations 中的方法

methods: {
    commitName(val) {
        this.$store.commit('handleNameChange', val);
    }  
}

大功告成~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 通過瀏覽器向web服務傳遞base64碼的圖片時遇到參數過長的問題? 解決辦法:查看aiohttp的源碼:aiohttp/http_parser.py下找到: class HeadersParser: def __init__(self, max_line_size: int=8190, max_h ...
  • 彈性佈局的名稱概念: 1、容器:需要添加彈性佈局的父元素;項目:彈性佈局容器中的每一個子元素,稱為項目。 2、主軸:在彈性佈局中,我們會通過屬性規定水平/垂直方向(flex-direction)為主軸;與主軸垂直的另一方向,稱為交叉軸。 彈性佈局的重要的幾大基礎屬性: 1、flex-directio ...
  • 不藉助Math函數求開根值 1、二分迭代法求n開根後的值 思路: left=0 right=n mid=(left+right)/2 比較mid^2與n大小 =輸出; >改變範圍,right=mid,mid重新計算; <改變範圍,left=mid,mid重新計算; 如此迴圈,不過只能是逼近,並不能完 ...
  • 問題產生在學習cabvas給畫布畫圖像的時候發現使用IE edge瀏覽器可以正常顯示圖像,而chrome則不行,經百度後知道是因為chrome瀏覽器會先載入javascript代碼,之後才載入圖片,這樣就造成了我是用drawImage的時候那個圖片並沒有載入出來。解決辦法把畫圖片到canvas的代碼 ...
  • 什麼是HTML? HTML是HyperText Markup Language(超文本標記語言)的簡寫,他不是一種編程語言,而是一種標記語言,用於告訴瀏覽器如何構造你的頁面。“超文本”就是指頁面可以包含圖片、鏈接,甚至音樂、程式等非文字元素。HTML也是一種規範,一種標準,它通過標記符號來 標記要顯 ...
  • 互聯網的迅速發展,軟體行業成了更多年輕人的就業選擇。HTML5簡單易學門檻低,是Web時代前端開發超好用的工具。而HTML5開發人員的就業薪資也遠遠高於其他行業。 資料顯示,初級HTML5開發人員的平均薪資在8K-10K左右,擁有一定工作經驗的人薪資普遍達到15K-20K。如此廣闊的前景當然吸引了無 ...
  • 需求分析 因為有時候想提高性能,只需要一個ajax函數,不想引入較大的jq文件,嘗試過axios,可是get方法不支持多層嵌套的json,post方式後臺接收方式似乎要變。。也許是我不太會用吧。。其實換個方式接收也沒什麼,只是習慣了JQ序列化參數。所以上網搜集了很多資料,同時也進一步瞭解了一點JQ。 ...
  • 一、symbol javascript基本數據類型: null、undefined、number、boolean、string、symbol ES6 引入了一種新的原始數據類型Symbol,表示獨一無二的值(隨機生成的一個永遠都不會重覆的id串) 二、Set和Map 1、Set() 是es6提供的一 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...