Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend options should not be confused with the super options #4767

Closed
z-ZYS-s opened this issue Jan 22, 2017 · 0 comments
Closed

Extend options should not be confused with the super options #4767

z-ZYS-s opened this issue Jan 22, 2017 · 0 comments
Labels

Comments

@z-ZYS-s
Copy link

z-ZYS-s commented Jan 22, 2017

A simple case:

const Base = Vue.extend({
  computed: {
    a () { return 'aa' }
  }
})
const Sub = Base.extend()
Sub.options.computed.b = () => 'bb'

console.log(Base.options.computed.b()) // 'bb'
console.log(Base.options.computed === Sub.options.computed) // true

The reason has been found, in line 181, vue/src/core/util/options.js

strats.props =
strats.methods =
strats.computed = function (parentVal: ?Object, childVal: ?Object): ?Object {
  if (!childVal) return parentVal

It just return the parent object. Maybe it should be replaced by code like this

strats.props =
strats.methods =
strats.computed = function (parentVal: ?Object, childVal: ?Object): ?Object {
  if (!childVal) return extend({}, parentVal)

There is a same problem for strats.watch in line 158.
There is no need to change strats.data in line 69 because the type is function.

I'd like to submit a PR but I'm not familiar with the code, like that props could be a Array so more things should be done after `extend({}, parentVal)...

Hope someone can fix this bug, Thanks!


Actually, it is not commonly used to set Sub.options.computed directly, but I met this bug when using vue-loader with css module. For example:

base.vue

<template>
<div :class="$style.base">base<div>
</template>
<script>
import Vue from 'vue';

export default Vue.extend({
  name: 'my-base',
});
</script>
<style module>
.base {
  color: red;
}
</style>

sub.vue

<template>
<div :class="$style.sub">sub<div>
</template>
<script>
import Base from './base.vue';

export default Vue.extend({
  name: 'my-sub',
});
</script>
<style module>
.sub {
  color: blue;
}
</style>

And finally, you will find that the computed property $style of <my-base> has been replaced by the one of <my-sub>. They share the same $style in fact.

The following lines using options directly are in vue-loader:

  • __vue_options__ = __vue_options__.options in line 254, vue-loader/lib/loader.js
  • __vue_options__.computed[key] = function () { return module } in line 285

And with the mentioned bug above in vue cause the final problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants