refactor(runtime-core): adjust attr fallthrough behavior

BREAKING CHANGE: attribute fallthrough behavior has been adjusted
according to https://github.com/vuejs/rfcs/pull/154
This commit is contained in:
Evan You
2020-04-02 21:51:01 -04:00
parent 2103a485d7
commit 21bcdec943
5 changed files with 144 additions and 27 deletions

View File

@@ -15,7 +15,7 @@ import { mockWarn } from '@vue/shared'
describe('attribute fallthrough', () => {
mockWarn()
it('should allow whitelisted attrs to fallthrough', async () => {
it('should allow attrs to fallthrough', async () => {
const click = jest.fn()
const childUpdated = jest.fn()
@@ -30,12 +30,12 @@ describe('attribute fallthrough', () => {
return () =>
h(Child, {
foo: 1,
foo: count.value + 1,
id: 'test',
class: 'c' + count.value,
style: { color: count.value ? 'red' : 'green' },
onClick: inc,
'data-id': 1
'data-id': count.value + 1
})
}
}
@@ -47,7 +47,6 @@ describe('attribute fallthrough', () => {
h(
'div',
{
id: props.id, // id is not whitelisted
class: 'c2',
style: { fontWeight: 'bold' }
},
@@ -62,8 +61,8 @@ describe('attribute fallthrough', () => {
const node = root.children[0] as HTMLElement
expect(node.getAttribute('id')).toBe('test') // id is not whitelisted, but explicitly bound
expect(node.getAttribute('foo')).toBe(null) // foo is not whitelisted
expect(node.getAttribute('id')).toBe('test')
expect(node.getAttribute('foo')).toBe('1')
expect(node.getAttribute('class')).toBe('c2 c0')
expect(node.style.color).toBe('green')
expect(node.style.fontWeight).toBe('bold')
@@ -71,6 +70,121 @@ describe('attribute fallthrough', () => {
node.dispatchEvent(new CustomEvent('click'))
expect(click).toHaveBeenCalled()
await nextTick()
expect(childUpdated).toHaveBeenCalled()
expect(node.getAttribute('id')).toBe('test')
expect(node.getAttribute('foo')).toBe('2')
expect(node.getAttribute('class')).toBe('c2 c1')
expect(node.style.color).toBe('red')
expect(node.style.fontWeight).toBe('bold')
expect(node.dataset.id).toBe('2')
})
it('should only allow whitelisted fallthrough on functional component with optional props', async () => {
const click = jest.fn()
const childUpdated = jest.fn()
const count = ref(0)
function inc() {
count.value++
click()
}
const Hello = () =>
h(Child, {
foo: count.value + 1,
id: 'test',
class: 'c' + count.value,
style: { color: count.value ? 'red' : 'green' },
onClick: inc
})
const Child = (props: any) => {
childUpdated()
return h(
'div',
{
class: 'c2',
style: { fontWeight: 'bold' }
},
props.foo
)
}
const root = document.createElement('div')
document.body.appendChild(root)
render(h(Hello), root)
const node = root.children[0] as HTMLElement
// not whitelisted
expect(node.getAttribute('id')).toBe(null)
expect(node.getAttribute('foo')).toBe(null)
// whitelisted: style, class, event listeners
expect(node.getAttribute('class')).toBe('c2 c0')
expect(node.style.color).toBe('green')
expect(node.style.fontWeight).toBe('bold')
node.dispatchEvent(new CustomEvent('click'))
expect(click).toHaveBeenCalled()
await nextTick()
expect(childUpdated).toHaveBeenCalled()
expect(node.getAttribute('id')).toBe(null)
expect(node.getAttribute('foo')).toBe(null)
expect(node.getAttribute('class')).toBe('c2 c1')
expect(node.style.color).toBe('red')
expect(node.style.fontWeight).toBe('bold')
})
it('should allow all attrs on functional component with declared props', async () => {
const click = jest.fn()
const childUpdated = jest.fn()
const count = ref(0)
function inc() {
count.value++
click()
}
const Hello = () =>
h(Child, {
foo: count.value + 1,
id: 'test',
class: 'c' + count.value,
style: { color: count.value ? 'red' : 'green' },
onClick: inc
})
const Child = (props: { foo: number }) => {
childUpdated()
return h(
'div',
{
class: 'c2',
style: { fontWeight: 'bold' }
},
props.foo
)
}
Child.props = ['foo']
const root = document.createElement('div')
document.body.appendChild(root)
render(h(Hello), root)
const node = root.children[0] as HTMLElement
expect(node.getAttribute('id')).toBe('test')
expect(node.getAttribute('foo')).toBe(null) // declared as prop
expect(node.getAttribute('class')).toBe('c2 c0')
expect(node.style.color).toBe('green')
expect(node.style.fontWeight).toBe('bold')
node.dispatchEvent(new CustomEvent('click'))
expect(click).toHaveBeenCalled()
await nextTick()
expect(childUpdated).toHaveBeenCalled()
expect(node.getAttribute('id')).toBe('test')