草庐IT

javascript - vuex- 状态作为函数或对象文字返回

coder 2024-05-16 原文

前几天我遇到了一个问题,并向伟大的堆栈社区寻求解决方案。

问题:

我在其他模块中嵌套了相同的模块,但我是这样定义状态的:

state: {
  // some state here
}

发生的事情是我的所有模块,尽管它们看起来嵌套在不同的模块下,但都共享相同的状态。

解决方案

state() {
  return {
    // state here instead
  }
}

解决方案是让函数返回状态,而不是将其定义为对象字面量。为什么有点道理。这是我的问题

新问题

  1. 当状态被定义为对象字面量而不是函数返回对象字面量时,存储的幕后发生了什么?

  2. 您为什么不使用函数版本?这似乎很容易成为默认选择,但即使在 vuex docs for modules 中也是如此,他们选择将状态显示为对象文字。

最佳答案

tl;dr 使用函数的原因是 Module Reuse .


What is happening under the hood of the store when state is defined as an object literal versus a function returning an object literal?

为此,更好 check under the hood :

var Store = function Store (options) {
  // ...
  var state = options.state; if ( state === void 0 ) state = {};
  if (typeof state === 'function') {
    state = state() || {};
  }

如您所见,上面的代码检查是否提供了 state。如果不是,它会分配一个空对象 ({}) 作为初始 state

接下来它检查 state 是否是一个 function。如果是,则执行它并将返回的内容分配给 state。如果它返回 undefined(或任何 falsy 值),它再次将空对象 {} 分配给 state .

所以这就是将 state 作为对象或函数提供的区别:如果提供了,就会执行。如果提供了一个对象,它会被直接赋值。


Why would you ever not use the function version? It seems like easily the default choice, but even in vuex docs for modules, they opt to show state as an object literal.

一般来说,是的,对象版本可能更常见,因为您通常只声明 store 对象(及其 state)一次,然后在您的Vue 实例。

state 函数 otoh 的一个用例是 Module Reuse :

Module Reuse

Sometimes we may need to create multiple instances of a module, for example:

  • Creating multiple stores that use the same module (e.g. To avoid stateful singletons in the SSR when the runInNewContext option is false or 'once');
  • Register the same module multiple times in the same store.

另一种可能的情况是,如果您声明了一个 Vuex 模块仅一次,并试图在不同的命名空间下多次使用它

由于上面的例子类似,这里有一个(模块案例的)演示来说明问题:

const personModule = {
  namespaced: true,
  state: {name: "name"},
  mutations: {
  	changeName(state, data) { state.name = data }
  }
}
const myStore = new Vuex.Store({
  strict: true,
  modules: {
    aliceNamespace: personModule,
    bobNamespcace: personModule
  }
});
new Vue({
  store: myStore,
  el: '#app',
  mounted() {
    this.changeAlicesName("Alice");
    this.changeBobsName("Bob");
  },
  computed: {
    ...Vuex.mapState('aliceNamespace', {alicesName: 'name'}),
    ...Vuex.mapState('bobNamespcace', {bobsName: 'name'})
  },
  methods: {
    ...Vuex.mapMutations('aliceNamespace', {changeAlicesName: 'changeName'}),
    ...Vuex.mapMutations('bobNamespcace', {changeBobsName: 'changeName'})
  }
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
  <p>Alice's name: {{ alicesName }}</p>
  <hr>
  <p>Bob's name: {{ bobsName }}</p>
  <hr>
  <button @click="changeAlicesName('Eve')">Change Alice's Name</button>
</div>

如您所见,当我们使用状态时,同一个对象被分配为两个模块的 state。这样做的效果是当我们编辑一个模块时,另一个会受到影响。实际上,它们可能是两个不同的模块,但它们的state只是同一个对象

另一方面,在下面的示例中,当我们将 state 声明为函数时,我们可以自由地重用模块声明,任意多次:

const personModule = {
  namespaced: true,
  state() {                     // changed to a function
    return {name: "name"}       // changed to a function
  },                            // changed to a function
  mutations: {
  	changeName(state, data) { state.name = data }
  }
}
const myStore = new Vuex.Store({
  strict: true,
  modules: {
    aliceNamespace: personModule,
    bobNamespcace: personModule
  }
});
new Vue({
  store: myStore,
  el: '#app',
  mounted() {
    this.changeAlicesName("Alice");
    this.changeBobsName("Bob");
  },
  computed: {
    ...Vuex.mapState('aliceNamespace', {alicesName: 'name'}),
    ...Vuex.mapState('bobNamespcace', {bobsName: 'name'})
  },
  methods: {
    ...Vuex.mapMutations('aliceNamespace', {changeAlicesName: 'changeName'}),
    ...Vuex.mapMutations('bobNamespcace', {changeBobsName: 'changeName'})
  }
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
  <p>Alice's name: {{ alicesName }}</p>
  <hr>
  <p>Bob's name: {{ bobsName }}</p>
  <hr>
  <button @click="changeAlicesName('Eve')">Change Alice's Name</button>
</div>

因为state是一个函数,它会为每个模块生成一个不同的state实例,一路按预期工作。

关于javascript - vuex- 状态作为函数或对象文字返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49557177/

有关javascript - vuex- 状态作为函数或对象文字返回的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  4. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  5. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

  6. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  7. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  8. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  9. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  10. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

随机推荐