Skip to content

Commit

Permalink
fix: mark props as reactive (#359)
Browse files Browse the repository at this point in the history
  • Loading branch information
pikax committed Jun 9, 2020
1 parent 9f18edf commit bc78428
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 23 deletions.
6 changes: 5 additions & 1 deletion src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { resolveSlots, createSlotProxy } from './helper';
import { hasOwn, isPlainObject, assert, proxy, warn, isFunction } from './utils';
import { ref } from './apis/state';
import vmStateManager from './vmStateManager';
import { markReactive } from './reactivity/reactive';

function asVmProperty(vm: ComponentInstance, propName: string, propValue: Ref<unknown>) {
const props = vm.$options.props;
Expand Down Expand Up @@ -164,6 +165,9 @@ export function mixin(Vue: VueConstructor) {
const setup = vm.$options.setup!;
const ctx = createSetupContext(vm);

// mark props as reactive
markReactive(props);

// resolve scopedSlots and slots to functions
resolveScopedSlots(vm, ctx.slots);

Expand Down Expand Up @@ -194,7 +198,7 @@ export function mixin(Vue: VueConstructor) {
bindingValue = ref(bindingValue);
} else {
// bind function to the vm, this will make `this` = vm
if (isFunction(bindingValue)){
if (isFunction(bindingValue)) {
bindingValue = bindingValue.bind(vm);
}
// a non-reactive should not don't get reactivity
Expand Down
81 changes: 59 additions & 22 deletions test/setup.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const Vue = require('vue/dist/vue.common.js');
const { ref, computed, createElement: h, provide, inject } = require('../src');
const { ref, computed, createElement: h, provide, inject, toRefs } = require('../src');

describe('setup', () => {
beforeEach(() => {
Expand Down Expand Up @@ -51,7 +51,7 @@ describe('setup', () => {
expect(vm.b).toBe(1);
});

it('should work with `methods` and `data` options', done => {
it('should work with `methods` and `data` options', (done) => {
let calls = 0;
const vm = new Vue({
template: `<div>{{a}}{{b}}{{c}}</div>`,
Expand Down Expand Up @@ -215,7 +215,7 @@ describe('setup', () => {
expect(vm.$refs.test.b).toBe(1);
});

it('props should not be reactive', done => {
it('props should not be reactive', (done) => {
let calls = 0;
const vm = new Vue({
template: `<child :msg="msg"></child>`,
Expand Down Expand Up @@ -247,6 +247,43 @@ describe('setup', () => {
}).then(done);
});

it('toRefs(props) should not warn', async () => {
let a;

const child = {
template: `<div/>`,

props: {
r: Number,
},
setup(props) {
a = toRefs(props).r;
},
};

const vm = new Vue({
template: `<child :r="r"/>`,
components: {
child,
},

data() {
return {
r: 1,
};
},
}).$mount();

expect(a.value).toBe(1);
vm.r = 3;

await Vue.nextTick();

expect(a.value).toBe(3);

expect(warn).not.toHaveBeenCalled();
});

it('this should be undefined', () => {
const vm = new Vue({
template: '<div></div>',
Expand All @@ -256,7 +293,7 @@ describe('setup', () => {
}).$mount();
});

it('should not make returned non-reactive object reactive', done => {
it('should not make returned non-reactive object reactive', (done) => {
const vm = new Vue({
setup() {
return {
Expand Down Expand Up @@ -285,8 +322,8 @@ describe('setup', () => {
});

it("should put a unenumerable '__ob__' for non-reactive object", () => {
const clone = obj => JSON.parse(JSON.stringify(obj));
const componentSetup = jest.fn(props => {
const clone = (obj) => JSON.parse(JSON.stringify(obj));
const componentSetup = jest.fn((props) => {
const internalOptions = clone(props.options);
return { internalOptions };
});
Expand Down Expand Up @@ -329,7 +366,7 @@ describe('setup', () => {
name: 'child',
props: ['msg'],
setup() {
return props => {
return (props) => {
p = props;
return null;
};
Expand All @@ -340,7 +377,7 @@ describe('setup', () => {
expect(p).toBe(undefined);
});

it('inline render function should work', done => {
it('inline render function should work', (done) => {
// let createElement;
const vm = new Vue({
props: ['msg'],
Expand Down Expand Up @@ -383,44 +420,44 @@ describe('setup', () => {
});

describe('Methods', () => {
it('binds methods when calling with parenthesis', async ()=>{
it('binds methods when calling with parenthesis', async () => {
let context = null;
const contextFunction = jest.fn(function (){
context = this
const contextFunction = jest.fn(function () {
context = this;
});

const vm = new Vue({
template: '<div><button @click="contextFunction()"/></div>',
setup() {
return {
contextFunction
}
}
contextFunction,
};
},
}).$mount();

await vm.$el.querySelector('button').click();
expect(contextFunction).toBeCalled();
expect(context).toBe(vm);
});

it('binds methods when calling without parenthesis', async () => {
let context = null;
const contextFunction = jest.fn(function (){
context = this
const contextFunction = jest.fn(function () {
context = this;
});

const vm = new Vue({
template: '<div><button @click="contextFunction"/></div>',
setup() {
return {
contextFunction
}
}
contextFunction,
};
},
}).$mount();

await vm.$el.querySelector('button').click();
expect(contextFunction).toBeCalled();
expect(context).toBe(vm);
});
})
});
});

0 comments on commit bc78428

Please sign in to comment.