uTools-Manuals/docs/vue/guide/state-management.html
2019-04-21 11:50:48 +08:00

74 lines
6.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="content guide with-sidebar state-management-guide">
<h1>状态管理</h1>
<h2 id="类-Flux-状态管理的官方实现"><a class="headerlink" href="#类-Flux-状态管理的官方实现" title="类 Flux 状态管理的官方实现"></a>类 Flux 状态管理的官方实现</h2><p>由于状态零散地分布在许多组件和组件之间的交互中大型应用复杂度也经常逐渐增长。为了解决这个问题Vue 提供 <a href="https://github.com/vuejs/vuex" rel="noopener" target="_blank">vuex</a>:我们有受到 Elm 启发的状态管理库。vuex 甚至集成到 <a href="https://github.com/vuejs/vue-devtools" rel="noopener" target="_blank">vue-devtools</a>,无需配置即可进行<a href="https://raw.githubusercontent.com/vuejs/vue-devtools/master/media/demo.gif" rel="noopener" target="_blank">时光旅行调试 (time travel debugging)</a></p>
<h3 id="React-的开发者请参考以下信息"><a class="headerlink" href="#React-的开发者请参考以下信息" title="React 的开发者请参考以下信息"></a>React 的开发者请参考以下信息</h3><p>如果你是来自 React 的开发者,你可能会对 Vuex 和 <a href="https://github.com/reactjs/redux" rel="noopener" target="_blank">Redux</a> 间的差异表示关注Redux 是 React 生态环境中最流行的 Flux 实现。Redux 事实上无法感知视图层,所以它能够轻松的通过一些<a href="https://yarnpkg.com/en/packages?q=redux%20vue&amp;p=1" rel="noopener" target="_blank">简单绑定</a>和 Vue 一起使用。Vuex 区别在于它是一个专门为 Vue 应用所设计。这使得它能够更好地和 Vue 进行整合,同时提供简洁的 API 和改善过的开发体验。</p>
<h2 id="简单状态管理起步使用"><a class="headerlink" href="#简单状态管理起步使用" title="简单状态管理起步使用"></a>简单状态管理起步使用</h2><p>经常被忽略的是Vue 应用中原始<code>数据</code>对象的实际来源 - 当访问数据对象时,一个 Vue 实例只是简单的代理访问。所以,如果你有一处需要被多个实例间共享的状态,可以简单地通过维护一份数据来实现共享:</p>
<pre><code class="hljs js"><span class="hljs-keyword">const</span> sourceOfTruth = {}
<span class="hljs-keyword">const</span> vmA = <span class="hljs-keyword">new</span> Vue({
<span class="hljs-attr">data</span>: sourceOfTruth
})
<span class="hljs-keyword">const</span> vmB = <span class="hljs-keyword">new</span> Vue({
<span class="hljs-attr">data</span>: sourceOfTruth
})</code></pre>
<p>现在当 <code>sourceOfTruth</code> 发生变化,<code>vmA</code><code>vmB</code> 都将自动的更新引用它们的视图。子组件们的每个实例也会通过 <code>this.$root.$data</code> 去访问。现在我们有了唯一的数据来源,但是,调试将会变为噩梦。任何时间,我们应用中的任何部分,在任何数据改变后,都不会留下变更过的记录。</p>
<p>为了解决这个问题,我们采用一个简单的 <strong>store 模式</strong></p>
<pre><code class="hljs js"><span class="hljs-keyword">var</span> store = {
<span class="hljs-attr">debug</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">state</span>: {
<span class="hljs-attr">message</span>: <span class="hljs-string">'Hello!'</span>
},
setMessageAction (newValue) {
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.debug) <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'setMessageAction triggered with'</span>, newValue)
<span class="hljs-keyword">this</span>.state.message = newValue
},
clearMessageAction () {
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.debug) <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'clearMessageAction triggered'</span>)
<span class="hljs-keyword">this</span>.state.message = <span class="hljs-string">''</span>
}
}</code></pre>
<p>需要注意,所有 store 中 state 的改变,都放置在 store 自身的 action 中去管理。这种集中式状态管理能够被更容易地理解哪种类型的 mutation 将会发生,以及它们是如何被触发。当错误出现时,我们现在也会有一个 log 记录 bug 之前发生了什么。</p>
<p>此外,每个实例/组件仍然可以拥有和管理自己的私有状态:</p>
<pre><code class="hljs js"><span class="hljs-keyword">var</span> vmA = <span class="hljs-keyword">new</span> Vue({
<span class="hljs-attr">data</span>: {
<span class="hljs-attr">privateState</span>: {},
<span class="hljs-attr">sharedState</span>: store.state
}
})
<span class="hljs-keyword">var</span> vmB = <span class="hljs-keyword">new</span> Vue({
<span class="hljs-attr">data</span>: {
<span class="hljs-attr">privateState</span>: {},
<span class="hljs-attr">sharedState</span>: store.state
}
})</code></pre>
<p><img src="https://cn.vuejs.org/images/state.png"/></p>
<p class="tip">重要的是,注意你不应该在 action 中 替换原始的状态对象 - 组件和 store 需要引用同一个共享对象mutation 才能够被观察</p>
<p>接着我们继续延伸约定,组件不允许直接修改属于 store 实例的 state而应执行 action 来分发 (dispatch) 事件通知 store 去改变,我们最终达成了 <a href="https://facebook.github.io/flux/" rel="noopener" target="_blank">Flux</a> 架构。这样约定的好处是,我们能够记录所有 store 中发生的 state 改变,同时实现能做到记录变更 (mutation)、保存状态快照、历史回滚/时光旅行的先进的调试工具。</p>
<p>说了一圈其实又回到了<a href="https://github.com/vuejs/vuex" rel="noopener" target="_blank">vuex</a>,如果你已经读到这儿,或许可以去尝试一下!</p>
<div class="guide-links">
<span><a href="routing.html">路由</a></span>
<span style="float: right;"><a href="ssr.html">服务端渲染</a></span>
</div>
<div class="footer">
<script src="//m.servedby-buysellads.com/monetization.js" type="text/javascript"></script>
<div class="bsa-cpc"></div>
<script>
(function(){
if(typeof _bsa !== 'undefined' && _bsa) {
_bsa.init('default', 'CKYD62QM', 'placement:vuejsorg', {
target: '.bsa-cpc',
align: 'horizontal',
disable_css: 'true'
});
}
})();
</script>
发现错误?想参与编辑?
<a href="https://github.com/vuejs/cn.vuejs.org/blob/master/srcstate-management.md" target="_blank">
在 GitHub 上编辑此页!
</a>
</div>
</div>