Bläddra i källkod

fix(compiler): fix v-bind dynamic arguments on slot outlets

fix #9444
Evan You 7 år sedan
förälder
incheckning
96a09aad99

+ 8 - 1
src/compiler/codegen/index.js

@@ -501,7 +501,14 @@ function genSlot (el: ASTElement, state: CodegenState): string {
   const slotName = el.slotName || '"default"'
   const children = genChildren(el, state)
   let res = `_t(${slotName}${children ? `,${children}` : ''}`
-  const attrs = el.attrs && `{${el.attrs.map(a => `${camelize(a.name)}:${a.value}`).join(',')}}`
+  const attrs = el.attrs || el.dynamicAttrs
+    ? genProps((el.attrs || []).concat(el.dynamicAttrs || []).map(attr => ({
+        // slot props are camelized
+        name: camelize(attr.name),
+        value: attr.value,
+        dynamic: attr.dynamic
+      })))
+    : null
   const bind = el.attrsMap['v-bind']
   if ((attrs || bind) && !children) {
     res += `,null`

+ 25 - 0
test/unit/features/component/component-scoped-slot.spec.js

@@ -1027,4 +1027,29 @@ describe('Component scoped slot', () => {
       expect(vm.$el.textContent).toBe(`2`)
     }).then(done)
   })
+
+  it('dynamic v-bind arguments on <slot>', done => {
+    const Foo = {
+      data() {
+        return {
+          key: 'msg'
+        }
+      },
+      template: `<div><slot :[key]="'hello'"/></div>`
+    }
+
+    const vm = new Vue({
+      components: { Foo },
+      template: `
+        <foo ref="foo" v-slot="props">{{ props }}</foo>
+      `
+    }).$mount()
+
+    expect(vm.$el.textContent).toBe(JSON.stringify({ msg: 'hello' }, null, 2))
+
+    vm.$refs.foo.key = 'changed'
+    waitForUpdate(() => {
+      expect(vm.$el.textContent).toBe(JSON.stringify({ changed: 'hello' }, null, 2))
+    }).then(done)
+  })
 })