ktsn / vuex-class

Binding helpers for Vuex and vue-class-component
MIT License
1.73k stars 86 forks source link

Action with namespace: TypeError: Cannot redefine property #9

Closed clarkdo closed 7 years ago

clarkdo commented 7 years ago

When use Action with namespace, page will throw "TypeError: Cannot redefine property: ..."

Part of codes like blow:

import Vue from 'vue'
import Component, {Getter, Action, namespace } from 'class-component'
const DemoGetter = namespace('demo', Getter)
const DemoAction = namespace('demo', Action)

@Component
export default class Demo extends Vue {
  @DemoAction selectCity
  @Getter authUser
  @DemoGetter city
}

According to my research, after vuex-class defined the actions on vm, vue "initMethods" will define all methods onto vm.

function initMethods (vm, methods) {
  var props = vm.$options.props;
  console.log('methods: ' +JSON.stringify( methods))
  for (var key in methods) {
    vm[key] = methods[key] == null ? noop : bind(methods[key], vm);
    if (process.env.NODE_ENV !== 'production') {
      if (methods[key] == null) {
        warn(
          "method \"" + key + "\" has an undefined value in the component definition. " +
          "Did you reference the function correctly?",
          vm
        );
      }
      if (props && hasOwn(props, key)) {
        warn(
          ("method \"" + key + "\" has already been defined as a prop."),
          vm
        );
      }
    }
  }
}

And then vue-class-component method '_init' may redefine them again, so the error occurred.

Component.prototype._init = function () {
        var _this = this;
        var keys = Object.getOwnPropertyNames(vm);
        if (vm.$options.props) {
            for (var key in vm.$options.props) {
                if (!vm.hasOwnProperty(key)) {
                    keys.push(key);
                }
            }
        }
        keys.forEach(function (key) {
            if (key.charAt(0) !== '_') {
                Object.defineProperty(_this, key, {
                    get: function () { return vm[key]; },
                    set: function (value) { return vm[key] = value; }
                });
            }
        });
    };

Does this have any solution or pr?

kota65535 commented 7 years ago

Is there any plan to fix it?

dimamarksman commented 7 years ago

The same error. Actions do not work for me at all, no matter with namespace or without.

ktsn commented 7 years ago

Could you provide self-contained reproduction via jsfidde, codepen, github repo or so on?

dimamarksman commented 7 years ago

@ktsn I created repo https://github.com/dimamarksman/vue-vuex-class-test Please take a look.

ktsn commented 7 years ago

Fixed via vue-class-component v6.1.0

dimamarksman commented 7 years ago

@ktsn Thank you!