代码之家  ›  专栏  ›  技术社区  ›  Sasha Kos

在Vue/Vuex中是否存在类似于mapstatetrops的react/redux方式

  •  2
  • Sasha Kos  · 技术社区  · 7 年前

    在React/Redux中映射状态和操作的常用方法如下所示,因此映射函数与组件代码分开放置:

    import React, { Component } from 'react';
    import { bindActionCreators } from 'redux';
    import { connect } from 'react-redux';
    
    import myAction from 'actions/request';
    
    class MyComponent extends Component {
      /* BODY */
    }
    
    function mapStateToProps(state) {
      return {
        myComponentProp: state.myReducer.myReducerProp
      };
    }
    
    function mapDispatchToProps(dispatch) {
      return {
        myComponentPropAction: bindActionCreators(myAction, dispatch),
      }
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
    

    我在Vue中找到的映射状态和操作的唯一描述方法如下

    import { mapState, mapActions } from 'vuex';
    
    export default {
      computed: {
        ...mapState('myReducer', {
          myComponentProp: (state) => state.myReducerProp,
        }),
        ...{
          /* aditional manipulations with this.myComponentProp */
        }
      },
      methods: {
        ...mapActions('myReducer', [
          'myReducerAction'
        ]),
        ...{
          myEventHandler: function() {
            /* checke conditions before action call */
            this.myReducerAction();
          },
        }
      }
    }
    

    由于扩散的数量,代码看起来很模糊,所以问题是: 有办法搬家吗 mapState mapActions 外部组件,如通常的in-react/redux方法。

    谢谢你的帮助!

    1 回复  |  直到 7 年前
        1
  •  1
  •   li x    7 年前

    好的,除了对typescript的支持,他们还添加了一个vue类组件装饰器,可以用来实现您的after。可以在这里找到指向此存储库的链接,但我建议您改为通过CLI创建一个新项目,然后在v3中添加该项目 Vue Class Component Github Repository .

    <script>
    
    function Getter (getterType) {
      return createDecorator((options, key) => {
        if (!options.computed) options.computed = {}
        options.computed[key] = function () {
          return this.$store.getters[getterType]
        }
      })
    }
    
    import Vue from 'vue'
    import Component from 'vue-class-component'
    
        @Component({
          props: {
            propMessage: String
          }
        })
        export default class App extends Vue {
        @Getter('foo') bar
        @Setter('psu') psi
    
          // computed
          get computedMsg () {
            return 'computed ' + this.msg
          }
    
          // method
          greet () {
            alert('greeting: ' + this.msg)
          }
        }
        </script>
    

    如您所见,我们在getter和setter中调用了一个函数,这个函数不是最优的,但更接近于一个多汁的答案。现在,vuex类绑定包将抽象所有这些模糊函数: vuex class

    import Vue from 'vue'
    import Component from 'vue-class-component'
    import {
      State,
      Getter,
      Action,
      Mutation,
      namespace
    } from 'vuex-class'
    
    const someModule = namespace('path/to/module')
    
    @Component
    export class MyComp extends Vue {
      @State('foo') stateFoo
      @State(state => state.bar) stateBar
      @Getter('foo') getterFoo
      @Action('foo') actionFoo
      @Mutation('foo') mutationFoo
      @someModule.Getter('foo') moduleGetterFoo
    
      // If the argument is omitted, use the property name
      // for each state/getter/action/mutation type
      @State foo
      @Getter bar
      @Action baz
      @Mutation qux
    
      created () {
        this.stateFoo // -> store.state.foo
        this.stateBar // -> store.state.bar
        this.getterFoo // -> store.getters.foo
        this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
        this.mutationFoo({ value: true }) // -> store.commit('foo', { value: true })
        this.moduleGetterFoo // -> store.getters['path/to/module/foo']
      }
    }
    

    这是一个很好的例子,因为我们可以使用一个命名的模块,调用它的所有getter和setter,而不需要任何讨厌的自定义函数,我们可以将所有这些都导入到 const 就像上面一样。现在您只需使用decorator就可以访问所有模块功能这已经非常接近于能够将您的功能不幸地分配到组件中了,但是一旦您完成了所有的设置,它看起来就相当不错了。我认为,不管有没有TS,您都可以做到这一点,但我一直在TS中做到这一点,因为它对vue类组件有一流的支持,而这些组件仍然是相对较新的。