mirror of
https://gitee.com/vuejs/vue.git
synced 2024-12-02 20:17:52 +08:00
support binding DOM properties with .prop modifier and :: shorthand
This commit is contained in:
parent
472b8975ed
commit
154e17abae
@ -3,5 +3,7 @@
|
||||
import { addHook } from '../helpers'
|
||||
|
||||
export default function bind (el: ASTElement, dir: ASTDirective) {
|
||||
addHook(el, 'construct', `_b(n1,${dir.value})`)
|
||||
addHook(el, 'construct', `_b(n1,${dir.value}${
|
||||
dir.modifiers && dir.modifiers.prop ? ',true' : ''
|
||||
})`)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
import { decodeHTML } from 'entities'
|
||||
import { parseHTML } from './html-parser'
|
||||
import { parseText } from './text-parser'
|
||||
import { cached, no } from 'shared/util'
|
||||
import { cached, no, camelize } from 'shared/util'
|
||||
import {
|
||||
pluckModuleFunction,
|
||||
getAndRemoveAttr,
|
||||
@ -324,7 +324,7 @@ function processComponent (el) {
|
||||
|
||||
function processAttrs (el) {
|
||||
const list = el.attrsList
|
||||
let i, l, name, value, arg, modifiers
|
||||
let i, l, name, value, arg, modifiers, isProp
|
||||
for (i = 0, l = list.length; i < l; i++) {
|
||||
name = list[i].name
|
||||
value = list[i].value
|
||||
@ -336,7 +336,12 @@ function processAttrs (el) {
|
||||
}
|
||||
if (bindRE.test(name)) { // v-bind
|
||||
name = name.replace(bindRE, '')
|
||||
if (platformMustUseProp(name)) {
|
||||
if (name.charAt(0) === ':' || (modifiers && modifiers.prop)) {
|
||||
isProp = true
|
||||
name = camelize(name.replace(bindRE, ''))
|
||||
if (name === 'innerHtml') name = 'innerHTML'
|
||||
}
|
||||
if (isProp || platformMustUseProp(name)) {
|
||||
addProp(el, name, value)
|
||||
} else {
|
||||
addAttr(el, name, value)
|
||||
|
@ -148,7 +148,10 @@ export function renderMixin (Vue: Class<Component>) {
|
||||
}
|
||||
|
||||
// apply v-bind object
|
||||
Vue.prototype._b = function bindProps (vnode: VNodeWithData, value: any) {
|
||||
Vue.prototype._b = function bindProps (
|
||||
vnode: VNodeWithData,
|
||||
value: any,
|
||||
asProp?: boolean) {
|
||||
if (value) {
|
||||
if (!isObject(value)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
@ -161,7 +164,7 @@ export function renderMixin (Vue: Class<Component>) {
|
||||
}
|
||||
const data = vnode.data
|
||||
for (const key in value) {
|
||||
const hash = config.mustUseProp(key)
|
||||
const hash = asProp || config.mustUseProp(key)
|
||||
? data.domProps || (data.domProps = {})
|
||||
: data.attrs || (data.attrs = {})
|
||||
hash[key] = value[key]
|
||||
|
@ -109,6 +109,18 @@ describe('Directive v-bind', () => {
|
||||
}).then(done)
|
||||
})
|
||||
|
||||
it('bind as prop', () => {
|
||||
const vm = new Vue({
|
||||
template: '<div><span v-bind:text-content.prop="foo"></span><span ::inner-html="bar"></span></div>',
|
||||
data: {
|
||||
foo: 'hello',
|
||||
bar: '<span>qux</span>'
|
||||
}
|
||||
}).$mount()
|
||||
expect(vm.$el.children[0].textContent).toBe('hello')
|
||||
expect(vm.$el.children[1].innerHTML).toBe('<span>qux</span>')
|
||||
})
|
||||
|
||||
it('bind object', done => {
|
||||
const vm = new Vue({
|
||||
template: '<input v-bind="test">',
|
||||
@ -132,6 +144,30 @@ describe('Directive v-bind', () => {
|
||||
}).then(done)
|
||||
})
|
||||
|
||||
it('bind object as prop', done => {
|
||||
const vm = new Vue({
|
||||
template: '<input v-bind.prop="test">',
|
||||
data: {
|
||||
test: {
|
||||
id: 'test',
|
||||
className: 'ok',
|
||||
value: 'hello'
|
||||
}
|
||||
}
|
||||
}).$mount()
|
||||
expect(vm.$el.id).toBe('test')
|
||||
expect(vm.$el.className).toBe('ok')
|
||||
expect(vm.$el.value).toBe('hello')
|
||||
vm.test.id = 'hi'
|
||||
vm.test.className = 'okay'
|
||||
vm.test.value = 'bye'
|
||||
waitForUpdate(() => {
|
||||
expect(vm.$el.id).toBe('hi')
|
||||
expect(vm.$el.className).toBe('okay')
|
||||
expect(vm.$el.value).toBe('bye')
|
||||
}).then(done)
|
||||
})
|
||||
|
||||
it('bind array', done => {
|
||||
const vm = new Vue({
|
||||
template: '<input v-bind="test">',
|
||||
|
Loading…
Reference in New Issue
Block a user