mirror of
https://gitee.com/vuejs/vue.git
synced 2024-11-30 11:07:51 +08:00
transition wip
This commit is contained in:
parent
79e164084b
commit
52ac04d235
@ -92,8 +92,8 @@ function genData (el) {
|
||||
data += `style:${el.styleBinding},`
|
||||
}
|
||||
// transition
|
||||
if (el.transition) {
|
||||
data += `transition:${el.transition},`
|
||||
if (el.transition != null) {
|
||||
data += `transition:__resolveTransition__(${el.transition}),`
|
||||
}
|
||||
// props
|
||||
if (el.props) {
|
||||
|
@ -49,7 +49,7 @@ export function addHandler (el, name, value, modifiers) {
|
||||
|
||||
export function getBindingAttr (el, name, getStatic) {
|
||||
const staticValue = getStatic !== false && getAndRemoveAttr(el, name)
|
||||
return staticValue
|
||||
return staticValue || staticValue === ''
|
||||
? JSON.stringify(staticValue)
|
||||
: (getAndRemoveAttr(el, ':' + name) || getAndRemoveAttr(el, 'v-bind:' + name))
|
||||
}
|
||||
|
79
src/runtime/dom-backend/class-util.js
Normal file
79
src/runtime/dom-backend/class-util.js
Normal file
@ -0,0 +1,79 @@
|
||||
import { isIE9 } from '../util/index'
|
||||
import { svgNS } from './node-ops'
|
||||
|
||||
/**
|
||||
* In IE9, setAttribute('class') will result in empty class
|
||||
* if the element also has the :class attribute; However in
|
||||
* PhantomJS, setting `className` does not work on SVG elements...
|
||||
* So we have to do a conditional check here.
|
||||
*
|
||||
* @param {Element} el
|
||||
* @param {String} cls
|
||||
*/
|
||||
|
||||
export function setClass (el, cls) {
|
||||
/* istanbul ignore else */
|
||||
if (!isIE9 || el.namespaceURI === svgNS) {
|
||||
el.setAttribute('class', cls)
|
||||
} else {
|
||||
el.className = cls
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add class with compatibility for IE & SVG
|
||||
*
|
||||
* @param {Element} el
|
||||
* @param {String} cls
|
||||
*/
|
||||
|
||||
export function addClass (el, cls) {
|
||||
if (el.classList) {
|
||||
el.classList.add(cls)
|
||||
} else {
|
||||
let cur = ' ' + getClass(el) + ' '
|
||||
if (cur.indexOf(' ' + cls + ' ') < 0) {
|
||||
setClass(el, (cur + cls).trim())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove class with compatibility for IE & SVG
|
||||
*
|
||||
* @param {Element} el
|
||||
* @param {String} cls
|
||||
*/
|
||||
|
||||
export function removeClass (el, cls) {
|
||||
if (el.classList) {
|
||||
el.classList.remove(cls)
|
||||
} else {
|
||||
let cur = ' ' + getClass(el) + ' '
|
||||
let tar = ' ' + cls + ' '
|
||||
while (cur.indexOf(tar) >= 0) {
|
||||
cur = cur.replace(tar, ' ')
|
||||
}
|
||||
setClass(el, cur.trim())
|
||||
}
|
||||
if (!el.className) {
|
||||
el.removeAttribute('class')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For IE9 compat: when both class and :class are present
|
||||
* getAttribute('class') returns wrong value... but className
|
||||
* on SVG elements returns an object.
|
||||
*
|
||||
* @param {Element} el
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function getClass (el) {
|
||||
var classname = el.className
|
||||
if (typeof classname === 'object') {
|
||||
classname = classname.baseVal || ''
|
||||
}
|
||||
return classname
|
||||
}
|
@ -6,6 +6,7 @@ import props from './modules/props'
|
||||
import attrs from './modules/attrs'
|
||||
import events from './modules/events'
|
||||
import directives from './modules/directives'
|
||||
import transition from './modules/transition'
|
||||
|
||||
export const patch = createPatchFunction({
|
||||
nodeOps,
|
||||
@ -15,6 +16,7 @@ export const patch = createPatchFunction({
|
||||
attrs,
|
||||
style,
|
||||
events,
|
||||
directives
|
||||
directives,
|
||||
transition
|
||||
]
|
||||
})
|
||||
|
@ -1,20 +1,25 @@
|
||||
import { isIE9, isArray, isObject } from '../../util/index'
|
||||
import { isArray, isObject } from '../../util/index'
|
||||
import { setClass } from '../class-util'
|
||||
|
||||
function updateClass (oldVnode, vnode) {
|
||||
let dynamicClass = vnode.data.class
|
||||
let staticClass = vnode.data.staticClass
|
||||
if (staticClass || dynamicClass) {
|
||||
const el = vnode.elm
|
||||
const activeClass = el._activeClass
|
||||
if (staticClass || dynamicClass || activeClass) {
|
||||
dynamicClass = genClass(dynamicClass)
|
||||
let cls = staticClass
|
||||
? staticClass + (dynamicClass ? ' ' + dynamicClass : '')
|
||||
: dynamicClass
|
||||
const cls = concatClass(concatClass(staticClass, dynamicClass), activeClass)
|
||||
if (cls !== oldVnode.class) {
|
||||
setClass(vnode.elm, cls)
|
||||
setClass(el, cls)
|
||||
}
|
||||
vnode.class = cls
|
||||
}
|
||||
}
|
||||
|
||||
function concatClass (a, b) {
|
||||
return a ? b ? (a + ' ' + b) : a : (b || '')
|
||||
}
|
||||
|
||||
function genClass (data) {
|
||||
if (!data) {
|
||||
return ''
|
||||
@ -38,25 +43,6 @@ function genClass (data) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In IE9, setAttribute('class') will result in empty class
|
||||
* if the element also has the :class attribute; However in
|
||||
* PhantomJS, setting `className` does not work on SVG elements...
|
||||
* So we have to do a conditional check here.
|
||||
*
|
||||
* @param {Element} el
|
||||
* @param {String} cls
|
||||
*/
|
||||
|
||||
export function setClass (el, cls) {
|
||||
/* istanbul ignore if */
|
||||
if (isIE9 && !/svg$/.test(el.namespaceURI)) {
|
||||
el.className = cls
|
||||
} else {
|
||||
el.setAttribute('class', cls)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
create: updateClass,
|
||||
update: updateClass
|
||||
|
@ -1,11 +1,11 @@
|
||||
export default {
|
||||
create: function (oldVnode, vnode) {
|
||||
create: function bindDirectives (oldVnode, vnode) {
|
||||
applyDirectives(oldVnode, vnode, 'bind')
|
||||
},
|
||||
update: function (oldVnode, vnode) {
|
||||
update: function updateDirectives (oldVnode, vnode) {
|
||||
applyDirectives(oldVnode, vnode, 'update', true)
|
||||
},
|
||||
destroy: function (vnode) {
|
||||
destroy: function unbindDirectives (vnode) {
|
||||
applyDirectives(null, vnode, 'unbind')
|
||||
}
|
||||
}
|
||||
|
60
src/runtime/dom-backend/modules/transition.js
Normal file
60
src/runtime/dom-backend/modules/transition.js
Normal file
@ -0,0 +1,60 @@
|
||||
import { addClass, removeClass } from '../class-util'
|
||||
import {
|
||||
isIE9,
|
||||
inBrowser,
|
||||
transitionProp,
|
||||
transitionEndEvent,
|
||||
animationProp,
|
||||
animationEndEvent
|
||||
} from '../../util/index'
|
||||
|
||||
export default isIE9 ? {} : {
|
||||
create: function applyEnterTransition (_, vnode) {
|
||||
let data = vnode.data.transition
|
||||
const el = vnode.elm
|
||||
if (data != null) {
|
||||
if (typeof data === 'string') {
|
||||
// pure CSS
|
||||
data = cssTransition(data)
|
||||
}
|
||||
// apply enter class
|
||||
const enterClass = data.enterClass
|
||||
if (enterClass) {
|
||||
addClass(el, enterClass)
|
||||
nextFrame(() => {
|
||||
removeClass(el, enterClass)
|
||||
})
|
||||
}
|
||||
const enterActiveClass = data.enterActiveClass
|
||||
if (enterActiveClass) {
|
||||
el._activeClass = enterActiveClass
|
||||
addClass(el, enterActiveClass)
|
||||
el.addEventListener(transitionEndEvent, () => {
|
||||
el._activeClass = null
|
||||
removeClass(el, enterActiveClass)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
remove: function applyLeaveTransition (vnode, rm) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const raf = (inBrowser && window.requestAnimationFrame) || setTimeout
|
||||
function nextFrame (fn) {
|
||||
raf(() => {
|
||||
raf(fn)
|
||||
})
|
||||
}
|
||||
|
||||
function cssTransition (name) {
|
||||
name = name || 'v'
|
||||
return {
|
||||
enterClass: `${name}-enter`,
|
||||
leaveClass: `${name}-leave`,
|
||||
enterActiveClass: `${name}-enter-active`,
|
||||
leaveActiveClass: `${name}-leave-active`
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
const svgNS = 'http://www.w3.org/2000/svg'
|
||||
export const svgNS = 'http://www.w3.org/2000/svg'
|
||||
|
||||
export function createElement (tagName) {
|
||||
return document.createElement(tagName)
|
||||
|
@ -34,6 +34,13 @@ export function renderMixin (Vue) {
|
||||
return resolveAsset(this.$options, 'directives', id, true)
|
||||
}
|
||||
|
||||
// resolve transition
|
||||
Vue.prototype.__resolveTransition__ = function (id) {
|
||||
return id && typeof id === 'string'
|
||||
? resolveAsset(this.$options, 'transitions', id) || id
|
||||
: id
|
||||
}
|
||||
|
||||
// toString for mustaches
|
||||
Vue.prototype.__toString__ = function (val) {
|
||||
return val == null
|
||||
|
Loading…
Reference in New Issue
Block a user