vuejs / vue-class-component

ES / TypeScript decorator for class-style Vue components.
MIT License
5.81k stars 429 forks source link

8.0.0-rc1 继承了Vue的类,其成员在初始化时,获取到的this的指向是装饰器修饰前的实例 #577

Open d00427179 opened 2 years ago

d00427179 commented 2 years ago

export defalut mixin { data() { return {a: 1} } }

@Options({ mixins: [mixin] }) export default class ToolBox extends Vue { logA = () => { console.log(this.a) } constructor(args) { super(args) // this.a 打印出 undifined console.log(this.a) } created() { // this.a 打印出 undifined this.logA() // this.a 打印出 1 console.log(this.a) } }

通过mixin和provide/inject注入的属性,为什么不在constructor期间完成, 这样导致没有办法直接用注入的属性来初始化成员类方法了, 设计就是这样的吗? 以后是否可能修改?

因为这个库很久没有更新过官方文档, 未来是否会有更多的break change? 现在是否适合使用于生产环境?

msebi commented 2 years ago

ENGLISH PLEASE!!!!!!!!!!!!!!!!!!!

chennh commented 2 years ago

遇到同样问题,问题来自 collectDataFromConstructor(vm, Component) 函数,plainData[key] = data[key]赋值方式导致,data[key]若是包含了箭头函数是不会变更为vue实例的上下文的

function collectDataFromConstructor(vm, Component) { // override _init to prevent to init as Vue instance var originalInit = Component.prototype._init; Component.prototype._init = function () { var _this = this; // proxy to actual vm var keys = Object.getOwnPropertyNames(vm); // 2.2.0 compat (props are no longer exposed as self properties) 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) { vm[key] = value; }, configurable: true }); } }); }; // should be acquired class property values var data = new Component(); // restore original _init to avoid memory leak (#209) Component.prototype._init = originalInit; // create plain data object var plainData = {}; Object.keys(data).forEach(function (key) { if (data[key] !== undefined) { plainData[key] = data[key]; } }); if (process.env.NODE_ENV !== 'production') { if (!(Component.prototype instanceof Vue) && Object.keys(plainData).length > 0) { warn('Component class must inherit Vue or its descendant class ' + 'when class property is used.'); } } return plainData; }

d00427179 commented 2 years ago

来信已收到,谢谢!