Skip to content

Commit

Permalink
fix(reactivity): should add allowRecurse to the effect (#2213)
Browse files Browse the repository at this point in the history
So that the scheduler also respects effect's allowRecurse option.

fix #2200
  • Loading branch information
HcySunYang authored Oct 5, 2020
1 parent 28d5fd7 commit ea1f87e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 41 deletions.
4 changes: 3 additions & 1 deletion packages/reactivity/src/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface ReactiveEffect<T = any> {
raw: () => T
deps: Array<Dep>
options: ReactiveEffectOptions
allowRecurse: boolean
}

export interface ReactiveEffectOptions {
Expand Down Expand Up @@ -100,6 +101,7 @@ function createReactiveEffect<T = any>(
}
} as ReactiveEffect
effect.id = uid++
effect.allowRecurse = !!options.allowRecurse
effect._isEffect = true
effect.active = true
effect.raw = fn
Expand Down Expand Up @@ -180,7 +182,7 @@ export function trigger(
const add = (effectsToAdd: Set<ReactiveEffect> | undefined) => {
if (effectsToAdd) {
effectsToAdd.forEach(effect => {
if (effect !== activeEffect || effect.options.allowRecurse) {
if (effect !== activeEffect || effect.allowRecurse) {
effects.add(effect)
}
})
Expand Down
80 changes: 40 additions & 40 deletions packages/runtime-core/__tests__/rendererComponent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import {
VNode,
provide,
inject,
Ref
Ref,
watch,
SetupContext
} from '@vue/runtime-test'

describe('renderer: component', () => {
Expand Down Expand Up @@ -139,23 +141,21 @@ describe('renderer: component', () => {
})

// #2170
test('should have access to instance’s “$el” property in watcher when setting instance data', async () => {
test('should have access to instance’s “$el” property in watcher when rendereing with watched prop', async () => {
function returnThis(this: any) {
return this
}
const dataWatchSpy = jest.fn(returnThis)
const propWatchSpy = jest.fn(returnThis)
let instance: any
const Comp = {
data() {
return {
testData: undefined
}
props: {
testProp: String
},

watch: {
testData() {
testProp() {
// @ts-ignore
dataWatchSpy(this.$el)
propWatchSpy(this.$el)
}
},

Expand All @@ -170,50 +170,50 @@ describe('renderer: component', () => {

const root = nodeOps.createElement('div')
render(h(Comp), root)
await nextTick()
expect(propWatchSpy).not.toHaveBeenCalled()

expect(dataWatchSpy).not.toHaveBeenCalled()
instance.testData = 'data'

render(h(Comp, { testProp: 'prop ' }), root)
await nextTick()
expect(dataWatchSpy).toHaveBeenCalledWith(instance.$el)
expect(propWatchSpy).toHaveBeenCalledWith(instance.$el)
})

// #2170
test('should have access to instance’s “$el” property in watcher when rendereing with watched prop', async () => {
function returnThis(this: any) {
return this
}
const propWatchSpy = jest.fn(returnThis)
let instance: any
const Comp = {
props: {
testProp: String
},
// #2200
test('component child updating parent state in pre-flush should trigger parent re-render', async () => {
const outer = ref(0)
const App = {
setup() {
const inner = ref(0)

watch: {
testProp() {
// @ts-ignore
propWatchSpy(this.$el)
return () => {
return [
h('div', inner.value),
h(Child, {
value: outer.value,
onUpdate: (val: number) => (inner.value = val)
})
]
}
},
}
}

created() {
instance = this
},
const Child = {
props: ['value'],
setup(props: any, { emit }: SetupContext) {
watch(() => props.value, (val: number) => emit('update', val))

render() {
return h('div')
return () => {
return h('div', props.value)
}
}
}

const root = nodeOps.createElement('div')
render(h(App), root)
expect(serializeInner(root)).toBe(`<div>0</div><div>0</div>`)

render(h(Comp), root)
await nextTick()
expect(propWatchSpy).not.toHaveBeenCalled()

render(h(Comp, { testProp: 'prop ' }), root)
outer.value++
await nextTick()
expect(propWatchSpy).toHaveBeenCalledWith(instance.$el)
expect(serializeInner(root)).toBe(`<div>1</div><div>1</div>`)
})
})

0 comments on commit ea1f87e

Please sign in to comment.