Empfehlung: „5 Auswahl an Vue.js-Video-Tutorials“
Heim >Web-Frontend >View.js >Nehmen Sie Vuex als Beispiel, um das Geheimnis der Staatsverwaltung aufzudecken
Empfehlung: „5 Auswahl an Vue.js-Video-Tutorials“
Verwenden Sie Vuex als Leitfaden, um einen Einblick in das gesamte Bild der Staatsverwaltung zu erhalten
Wie wir alle wissen, ist Vuex das offizielle State-Management-Lösung von Vue.
Die Verwendung und API von Vuex sind nicht schwierig und auch die Einführung auf der offiziellen Website ist prägnant und klar. Dadurch ist es sehr einfach, Vuex schnell in Ihr Projekt zu integrieren. Aufgrund der flexiblen Nutzung sind viele Studenten jedoch etwas verwirrt, was das Design und die Verwendung von Vuex angeht.
Bevor wir es verwenden, sollten wir tatsächlich innehalten und über ein paar Fragen nachdenken:
Wenn Sie sich bei diesen Fragen nicht sicher sind, dann herzlichen Glückwunsch, dieser Artikel könnte genau das sein, was Sie brauchen.
Bitte schließen Sie sich mir unten an, um das Geheimnis der Staatsverwaltung vom Ursprung an zu lüften, am Beispiel von Vuex.
Der in diesem Artikel vorgestellte Inhalt umfasst die folgenden Aspekte:
Seit der Geburt der drei großen Frameworks haben die beiden gemeinsamen Funktionen Jquery vollständig erfasst. Diese beiden Funktionen sind:
Die datengesteuerte Ansicht ermöglicht es uns, uns von der Ära zu verabschieden, in der wir uns nur auf den Betrieb von DOM verlassen können, um Seiten zu aktualisieren. Wir müssen das DOM nicht mehr über Suchebenen finden und dann seine Eigenschaften und Inhalte jedes Mal ändern, wenn wir die Seite aktualisieren. Wir können diese Dinge tun, indem wir Daten manipulieren.
Natürlich können Daten in den Augen unseres Frontends grundsätzlich als Speicherung verschiedener Datentypen verstanden werden. 变量
。在 数据驱动
Nach dem Aufkommen dieses Konzepts wurden einigen Variablen auch besondere Bedeutungen zugewiesen.
Erstens handelt es sich um eine gewöhnliche Variable, die sich nicht von der JQ-Ära unterscheidet und nur zum Speichern von Daten verwendet wird. Darüber hinaus gibt es eine Art von Variablen, die eine reaktionsfähige Wirkung haben. Wenn sich die an diese Variablen gebundenen Variablen ändern, nenne ich diese Art von Variablen Zustandsvariablen .
Die sogenannte datengesteuerte Sichtweise bedeutet streng genommen, dass Zustandsvariablen die Sichtweise steuern. Mit der Popularität von Vue und React hat sich der Fokus der Front-End-Entwickler allmählich vom Betrieb des DOM auf den Betrieb von Daten verlagert, und Zustandsvariablen sind zum Kern geworden.
Zustandsvariablen, jetzt scheint jeder sie lieber Zustand zu nennen. Wir sprechen oft über Zustand und Zustandsverwaltung. Tatsächlich bezieht sich dieser Zustand auf Zustandsvariablen. Der im Folgenden erwähnte Zustand bezieht sich auch auf Zustandsvariablen.
Nachdem der Status kommt, kommen auch die Komponenten.
In der JQ-Ära ist eine Front-End-Seite nur ein HTML, und es gibt kein Konzept einer „Komponente“. Es ist nicht allzu schwierig, die öffentlichen Teile der Seite elegant wiederzuverwenden. Glücklicherweise haben die drei großen Frameworks sehr ausgereifte Komponentendesigns hervorgebracht. Es ist einfach, ein DOM-Fragment als Komponente zu extrahieren, und die Komponente kann intern ihren eigenen Zustand beibehalten, wodurch sie unabhängiger wird.
Ein wichtiges Merkmal von Komponenten ist, dass diese internen Zustände von außen isoliert sind. Die übergeordnete Komponente kann nicht auf den internen Status der untergeordneten Komponente zugreifen, aber die untergeordnete Komponente kann auf den von der übergeordneten Komponente übergebenen Status (Props) zugreifen und automatisch entsprechend den Änderungen reagieren.
Diese Funktion kann als modularisierter Zustand verstanden werden. Dies hat den Vorteil, dass nicht berücksichtigt werden muss, dass der aktuelle Einstellungszustand Auswirkungen auf andere Komponenten hat. Natürlich ist es unrealistisch, den Komponentenstatus vollständig zu isolieren. Es wird zwangsläufig erforderlich sein, dass mehrere Komponenten den Status teilen. In diesem Fall besteht die Lösung darin, den Status an die übergeordnete Komponente zu extrahieren, die diesen Komponenten am nächsten liegt, und ihn über Props weiterzugeben .
Das obige Schema der Statusfreigabe stellt in der Regel kein Problem dar und ist zudem eine offiziell empfohlene Best Practice.
Aber wenn Ihre Seite komplex ist, werden Sie feststellen, dass sie immer noch unzureichend ist. Zum Beispiel:
Wenn Sie in diesem Fall weiterhin die Methode „Zustand in übergeordnete Komponente extrahieren“ verwenden, werden Sie feststellen, dass diese sehr kompliziert ist. Und mit zunehmender Anzahl der Komponenten und tieferer Verschachtelungsebene wird die Komplexität immer höher. Da es viele zugehörige Zustände und eine komplexe Übertragung gibt, kann es leicht zu Problemen wie der unerklärlichen Aktualisierung einer bestimmten Komponente oder der Nichtaktualisierung einer bestimmten Komponente kommen, und die Fehlerbehebung bei abnormalen Fehlern kann schwierig sein.
Vor diesem Hintergrund brauchen wir eine elegantere Lösung, um mit dieser komplexen Situation umzugehen.
Wir haben im vorherigen Abschnitt erwähnt, dass wir aufgrund der Komplexität der Seite auf heikle Probleme bei der Implementierung des gemeinsamen Zustands über Komponenten hinweg gestoßen sind.
Gibt es also eine Lösung? Natürlich gibt es das, und dank der Bemühungen der Gemeindevorsteher gibt es mehr als einen Plan. Aber diese Lösungen haben alle einen gemeinsamen Namen, den wir vor zwei Jahren sehr intensiv diskutiert haben – Staatsmanagement.
Zustandsverwaltung kann eigentlich als globale Zustandsverwaltung verstanden werden. Der Zustand unterscheidet sich vom Zustand innerhalb der Komponente. Er wird unabhängig von der Komponente verwaltet und ist dann auf irgendeine Weise mit der Komponente verknüpft.
Das Statusmanagement verfügt über einen eigenen Umsetzungsplan. Vue hat Vuex, React hat Redux, Mobx und natürlich gibt es noch andere Lösungen. Aber sie alle lösen das gleiche Problem, nämlich das Problem der komponentenübergreifenden Zustandsfreigabe.
Ich erinnere mich, dass das Konzept des „Staatsmanagements“ in den letzten zwei Jahren aufgrund der Popularität zu einem unverzichtbaren Bestandteil der Anwendungsentwicklung geworden zu sein schien. Am Beispiel von Vue führt die Erstellung eines Projekts zwangsläufig zur Einführung von Vuex für die staatliche Verwaltung. Viele Menschen wissen jedoch nicht, warum, wann und wie sie die staatliche Verwaltung nutzen sollen, und folgen dem Trend einfach blind. Infolgedessen gab es viele Beispiele für den Missbrauch der staatlichen Verwaltung. Wenn Sie dies sehen, sollten Sie wissen, dass eine staatliche Verwaltung nicht erforderlich ist. Warum es auftritt und welche Probleme es löst, wird im Wesentlichen oben erläutert. Wenn Sie es nicht verstehen, halten Sie inne und lesen Sie es noch einmal von Anfang an. Denken Sie nicht, dass der Hintergrund, vor dem eine technische Lösung entsteht, unwichtig ist. Wenn Sie nicht verstehen, welches Problem sie lösen soll, können Sie ihre Rolle nicht wirklich spielen. Der Autor von Redux hat ein berühmtes Sprichwort:Wenn Sie nicht wissen, ob Sie Redux (Zustandsverwaltung) brauchen, dann brauchen Sie es nicht.
Okay, wenn Sie die Statusverwaltung verwenden oder die Statusverwaltung zur Lösung von Problemen verwenden müssen, lesen Sie weiter. VuexVue wird in China häufig verwendet, insbesondere für kleine und mittlere Teams. Daher sollte Vuex die erste staatliche Verwaltungslösung sein, mit der die meisten Menschen in Kontakt kommen. Wie löst Vuex also das Problem der komponentenübergreifenden Zustandsfreigabe? Lassen Sie es uns gemeinsam erkunden. Erstellen Sie einen ShopWie oben erwähnt lautet die offizielle Empfehlung für den allgemeinen Komponentenfreigabestatus: „Extrahieren Sie den Status in die nächstgelegene übergeordnete Komponente“. Vuex geht noch einen Schritt weiter und extrahiert alle Zustände in die Root-Komponente, sodass jede Komponente darauf zugreifen kann.
Vielleicht fragen Sie sich: Stellt dies nicht den Status der Gesamtsituation dar? Würden dadurch die Vorteile der Modularität nicht völlig zunichte gemacht? Tatsächlich ist es das nicht. Der Hauptzweck von Vuex besteht darin, allen Komponenten den Zugriff auf diese Zustände zu ermöglichen und die Situation vollständig zu vermeiden, in der nicht auf den Zustand von Unterkomponenten zugegriffen werden kann. Vuex speichert alle Zustandsdaten in einem Objekt und folgt dabei dem Prinzip der „einzelnen Datenquelle“. Dies bedeutet jedoch nicht, dass Vuex eine eigene modulare Lösung auf diesem einzelnen Statusbaum implementiert.Keine Sorge, lassen Sie uns zunächst Schritt für Schritt vorgehen und sehen, wie man Vuex verwendet.
Vuex existiert als Plug-in für Vue. Installieren Sie es zunächst mit npm:$ npm install --save vuexNach der Installation erstellen wir einen neuen Ordner
src/store
und legen den gesamten Vuex-bezogenen Code hier ab. Erstellen Sie eine neue index.js
und schreiben Sie den folgenden Code. Die Hauptfunktion dieses Codes besteht darin, das Vuex-Plug-in mit der Methode Vue.use
zu laden und dann die konfigurierte Vuex.Store
-Instanz zu exportieren.
import Vue from 'vue' import Vuex from 'vuex' // 安装插件 Vue.use(Vuex) export default new Vuex.Store({ state: {}, mutations: {}, actions: {}, modules: {} })
src/store
文件夹,在这里放所有 Vuex 相关的代码。新建 index.js
并写入如下代码。这段代码主要的作用就是用 Vue.use
方法加载 Vuex 这个插件,然后将配置好的 Vuex.Store
实例导出。
import store from './store' new Vue({ el: '#app', store: store })
上面导出的实例我们通常称之为 store
。一个 store 中包含了存储的状态(state
)和修改状态的函数(mutation
)等,所有状态和相关操作都在这里定义。
最后一步,在入口文件将上面导出的 store 实例挂载到 Vue 上:
new Vuex.Store({ state: { app_version: '0.1.1' } }
注意:挂载这一步不是必须的。挂载这一步的作用只是为了方便在 .vue 组件中通过 this.$store
访问我们导出的 store 实例。如果不挂载,直接导入使用也是一样的。
上一步我们用构造函数 Vuex.Store
创建了 store 实例,大家至少知道该怎么用 Vuex 了。这一步我们来看看 Vuex.Store 构造函数的具体配置。
首先是 state
配置,他的值是一个对象,用来存储状态。Vuex 使用 单一状态树
原则,将所有的状态都放在这个对象上,便于后续的状态定位和调试。
比如说我们有一个初始状态 app_version
表示版本,如下:
this.$store.state.app_version
现在要在组件中获取,可以这样:
import store from '@/store' // @ 表示 src 目录 store.state.app_version
但这并不是唯一的获取方式,也可以这样:
import { mapState } from 'vuex' export default { computed: { ... // 其他计算属性 ...mapState({ version: state => state.app_version }) } }
为什么要强调这一点呢?因为很多小伙伴以为 Vuex 只能通过 this.$store
操作。到了非组件内,比如在请求函数中要设置某一个 Vuex 的状态,就不知道该怎么办了。
事实上组件中获取状态还有更优雅的方法,比如 mapState
Das oben exportierte Beispiel heißt normalerweise store
. Ein Speicher enthält gespeicherte Zustände (state
) und Funktionen, die den Zustand ändern (mutation
). Alle Zustände und zugehörigen Operationen werden hier definiert.
new Vuex.Store({ state: { count: 1 }, mutations: { increment(state, count) { // 变更状态 state.count += count } } })🎜Hinweis: 🎜Dieser Montageschritt ist nicht notwendig🎜. Der Zweck dieses Montageschritts besteht lediglich darin, den Zugriff auf unsere exportierte Store-Instanz über
this.$store
in der .vue-Komponente zu erleichtern. Wenn es nicht gemountet ist, entspricht es dem Direktimport. 🎜🎜Einzelne Datenquelle (Status)🎜🎜Im vorherigen Schritt haben wir den Konstruktor Vuex.Store
verwendet, um eine Store-Instanz zu erstellen. Jeder weiß zumindest, wie man Vuex verwendet. Werfen wir in diesem Schritt einen Blick auf die spezifische Konfiguration des Vuex.Store-Konstruktors. 🎜🎜Die erste ist die state
-Konfiguration. Ihr Wert ist ein Objekt, das zum Speichern des Status verwendet wird. Vuex verwendet das Single State Tree
-Prinzip, um alle Zustände auf diesem Objekt zu platzieren, um die nachfolgende Zustandslokalisierung und das Debuggen zu erleichtern. 🎜🎜Zum Beispiel haben wir einen Anfangszustand app_version
, der die Version wie folgt darstellt: 🎜this.$store.commit('increment', 2)🎜Jetzt wollen wir es in die Komponente bekommen, Sie können Folgendes tun: 🎜
new Vuex.Store({ state: { count: 1 }, mutations: { add(state) { state.count++ }, reduce(state) { state.count-- } }, actions: { increment(context, data) { axios.get('**').then(res => { if (data.iscan) { context.commit('add') } else { context.commit('reduce') } }) } } })🎜Aber das ist nicht der Fall Der einzige Weg, es zu bekommen, ist, dass Sie es auch so bekommen können:🎜
this.$store.dispatch('increment', { iscan: true })🎜Warum sollte ich diesen Punkt betonen? Weil viele Freunde denken, dass Vuex nur über
this.$store
bedient werden kann. Wenn es um Nicht-Komponenten geht, wenn Sie beispielsweise einen bestimmten Vuex-Status in der Anforderungsfunktion festlegen möchten, wissen Sie nicht, was Sie tun sollen. 🎜🎜Tatsächlich gibt es elegantere Möglichkeiten, Zustände in Komponenten abzurufen, wie zum Beispiel die Funktion mapState
, die es einfacher macht, mehrere Zustände abzurufen. 🎜import { mapState } from 'vuex' export default { computed: { ... // 其他计算属性 ...mapState({ version: state => state.app_version }) } }
Vuex 中的状态与组件中的状态不同,不能直接用 state.app_version='xx'
这种方式修改。Vuex 规定修改状态的唯一方法是提交 mutation
。
Mutation 是一个函数,第一个参数为 state,它的作用就是更改 state 的状态。
下面定义一个名叫 increment 的 mutation,在函数内更新 count 这个状态:
new Vuex.Store({ state: { count: 1 }, mutations: { increment(state, count) { // 变更状态 state.count += count } } })
然后在 .vue 组件中触发 increment:
this.$store.commit('increment', 2)
这样绑定了 count 的视图就会自动更新。
虽然 mutation 是更新状态的唯一方式,但实际上它还有一个限制:必须是同步更新。
为什么必须是同步更新?因为在开发过程中,我们常常会追踪状态的变化。常用的手段就是在浏览器控制台中调试。而在 mutation 中使用异步更新状态,虽然也会使状态正常更新,但是会导致开发者工具有时无法追踪到状态的变化,调试起来就会很困难。
再有 Vuex 给 mutation 的定位就是更改状态,只是更改状态,别的不要参与。所谓专人干专事儿,这样也帮助我们避免把更改状态和自己的业务逻辑混起来,同时也规范了函数功能。
那如果确实需要异步更新,该怎么办呢?
异步更新状态是一个非常常见的场景,比如接口请求回来的数据要存储,那就是异步更新。
Vuex 提供了 action
用于异步更新状态。与 mutation 不同的是,action 不直接更新状态,而是通过触发 mutation 间接更新状态。因此即便使用 action 也不违背 “修改状态的唯一方法是提交 mutation” 的原则。
Action 允许在实际更新状态前做一些副作用的操作,比如上面说的异步,还有数据处理,按条件提交不同的 mutation 等等。看一个例子:
new Vuex.Store({ state: { count: 1 }, mutations: { add(state) { state.count++ }, reduce(state) { state.count-- } }, actions: { increment(context, data) { axios.get('**').then(res => { if (data.iscan) { context.commit('add') } else { context.commit('reduce') } }) } } })
在组件中触发 action:
this.$store.dispatch('increment', { iscan: true })
这些就是 action 的使用方法。其实 action 最主要的作用就是请求接口,拿到需要的数据,然后触发 mutation 修改状态。
其实这一步在组件中也可以实现。我看过一些方案,常见的是在组件内写一个请求方法,当请求成功,直接通过 this.$store.commit
方法触发 mutation 来更新状态,完全用不到 action。
难道 action 可有可无吗?
也不是,在特定场景下确实需要 action 的,这个会在下一篇说。
前面讲过,Vuex 是单一状态树,所有状态存放在一个对象上。同时 Vuex 有自己的模块化方案
,可以避免状态堆砌到一起,变的臃肿。
Vuex 允许我们将 store 分割成模块(module),每个模块拥有自己的 state、mutation、action。虽然状态注册在根组件,但是支持模块分割,相当于做到了与页面组件平级的“状态组件”。
为了区分,我们将被分割的模块称为子模块,暴露在全局的称为全局模块。
我们来看基础用法:
new Vuex.Store({ modules: { user: { state: { uname: 'ruims' }, mutation: { setName(state, name) { state.name = name } } } } })
上面定义了 user
模块,包含了一个 state 和一个 mutation。在组件中使用方法如下:
// 访问状态 this.$store.state.user.uname // 更新状态 this.$store.commit('setName')
大家发现了,访问子模块的 state 要通过 this.$store.state.[模块名称]
这种方式去访问,触发 mutation 则与全局模块一样,没有区别。
action 与 mutation 原理一致,不细说。
上面说到,子模块触发 mutation 和 action 与全局模块一致,那么假设全局模块和子模块中都有一个名为 setName
的 mutation。在组件中触发,哪个 mutation 会执行呢?
经过试验,都会执行。官方的说法是:为了多个模块能够对同一 mutation 或 action 作出响应。
其实官方做的这个兼容,我一直没遇到实际的应用场景,反而因为同名 mutation 导致误触发带来了不少的麻烦。可能官方也意识到了这个问题,索引后来也为 mutation 和 action 做了模块处理方案。
这个方案,就是命名空间。
命名空间也很简单,在子模块中加一个 namespaced: true
的配置即可开启,如:
new Vuex.Store({ modules: { user: { namespaced: true, state: {} } } })
开启命名空间后,触发 mutation 就变成了:
this.$store.commit('user/setName')
可见提交参数由 '[mutation]'
变成了 '[模块名称]/[mutation]'
。
上面我们介绍了 Vuex 的模块化方案,将单一状态树 store 分割成多个 module,各自负责本模块状态的存储和更新。
模块化是必要的,但是这个模块的方案,用起来总觉得有点别扭。
比如,总体的设计是将 store 先分模块,模块下在包含 state,mutation,action。
那么按照正常理解,访问 user 模块下 state 应该是这样的:
this.$store.user.state.uname
但是实际 API 却是这样的:
this.$store.state.user.uname
这个 API 仿佛是在 state 中又各自分了模块。我没看过源码,但从使用体验上来说,这是别扭一。
除 state 外,mutation,action 默认注册在全局的设计,也很别扭。
首先,官方说的多个模块对同一 mutation 或 action 作出响应,这个功能暂无找到应用场景。并且未配 namespace 时还要保证命名唯一,否则会导致误触发。
其次,用 namespace 后,触发 mutation 是这样的:
this.$store.commit('user/setName')
这个明显是将参数单独处理了,为什么不是这样:
this.$store.user.commit('setName')
总体感受就是 Vuex 模块化做的还不够彻底。
上面说的槽点,并不是为了吐槽而吐槽。主要是感觉还有优化空间。
比如 this.$store.commit
函数可以触发任何 mutation 来更改状态。如果一个组件复杂,需要操作多个子模块的状态,那么就很难快速的找出当前组件操作了哪些子模块,当然也不好做权限规定。
我希望的是,比如在 A 组件要用到 b, c
两个子模块的状态,不允许操作其他子模块,那么就可以先将要用到模块导入,比如这样写:
import { a, b } from this.$store export default { methods: { test() { alert(a.state.uname) // 访问状态 a.commit('setName')// 修改状态 } } }
这样按照模块导入,查询和使用都比较清晰。
前面我们详细介绍了状态管理的背景以及 Vuex 的使用,分享了关于官方 API 的思考。相信看到这里,你已经对状态管理和 Vuex 有了更深刻的认识和理解。
然而本篇我们只介绍了 Vuex 这一个方案,状态管理的其他方案,以及上面我们的吐槽点,能不能找到更优的实现方法,这些都等着我们去尝试。
下一篇文章我们继续深挖状态管理,对比 Vuex 和 React,Fluter 在状态管理实现上的差异,然后在 Vue 上集成 Mobx,打造我们优雅的应用。
Das obige ist der detaillierte Inhalt vonNehmen Sie Vuex als Beispiel, um das Geheimnis der Staatsverwaltung aufzudecken. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!