mirror of
https://gitee.com/vuejs/vue.git
synced 2024-12-02 12:07:39 +08:00
transition wip
This commit is contained in:
parent
79e164084b
commit
52ac04d235
@ -92,8 +92,8 @@ function genData (el) {
|
|||||||
data += `style:${el.styleBinding},`
|
data += `style:${el.styleBinding},`
|
||||||
}
|
}
|
||||||
// transition
|
// transition
|
||||||
if (el.transition) {
|
if (el.transition != null) {
|
||||||
data += `transition:${el.transition},`
|
data += `transition:__resolveTransition__(${el.transition}),`
|
||||||
}
|
}
|
||||||
// props
|
// props
|
||||||
if (el.props) {
|
if (el.props) {
|
||||||
|
@ -49,7 +49,7 @@ export function addHandler (el, name, value, modifiers) {
|
|||||||
|
|
||||||
export function getBindingAttr (el, name, getStatic) {
|
export function getBindingAttr (el, name, getStatic) {
|
||||||
const staticValue = getStatic !== false && getAndRemoveAttr(el, name)
|
const staticValue = getStatic !== false && getAndRemoveAttr(el, name)
|
||||||
return staticValue
|
return staticValue || staticValue === ''
|
||||||
? JSON.stringify(staticValue)
|
? JSON.stringify(staticValue)
|
||||||
: (getAndRemoveAttr(el, ':' + name) || getAndRemoveAttr(el, 'v-bind:' + name))
|
: (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 attrs from './modules/attrs'
|
||||||
import events from './modules/events'
|
import events from './modules/events'
|
||||||
import directives from './modules/directives'
|
import directives from './modules/directives'
|
||||||
|
import transition from './modules/transition'
|
||||||
|
|
||||||
export const patch = createPatchFunction({
|
export const patch = createPatchFunction({
|
||||||
nodeOps,
|
nodeOps,
|
||||||
@ -15,6 +16,7 @@ export const patch = createPatchFunction({
|
|||||||
attrs,
|
attrs,
|
||||||
style,
|
style,
|
||||||
events,
|
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) {
|
function updateClass (oldVnode, vnode) {
|
||||||
let dynamicClass = vnode.data.class
|
let dynamicClass = vnode.data.class
|
||||||
let staticClass = vnode.data.staticClass
|
let staticClass = vnode.data.staticClass
|
||||||
if (staticClass || dynamicClass) {
|
const el = vnode.elm
|
||||||
|
const activeClass = el._activeClass
|
||||||
|
if (staticClass || dynamicClass || activeClass) {
|
||||||
dynamicClass = genClass(dynamicClass)
|
dynamicClass = genClass(dynamicClass)
|
||||||
let cls = staticClass
|
const cls = concatClass(concatClass(staticClass, dynamicClass), activeClass)
|
||||||
? staticClass + (dynamicClass ? ' ' + dynamicClass : '')
|
|
||||||
: dynamicClass
|
|
||||||
if (cls !== oldVnode.class) {
|
if (cls !== oldVnode.class) {
|
||||||
setClass(vnode.elm, cls)
|
setClass(el, cls)
|
||||||
}
|
}
|
||||||
vnode.class = cls
|
vnode.class = cls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function concatClass (a, b) {
|
||||||
|
return a ? b ? (a + ' ' + b) : a : (b || '')
|
||||||
|
}
|
||||||
|
|
||||||
function genClass (data) {
|
function genClass (data) {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return ''
|
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 {
|
export default {
|
||||||
create: updateClass,
|
create: updateClass,
|
||||||
update: updateClass
|
update: updateClass
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
export default {
|
export default {
|
||||||
create: function (oldVnode, vnode) {
|
create: function bindDirectives (oldVnode, vnode) {
|
||||||
applyDirectives(oldVnode, vnode, 'bind')
|
applyDirectives(oldVnode, vnode, 'bind')
|
||||||
},
|
},
|
||||||
update: function (oldVnode, vnode) {
|
update: function updateDirectives (oldVnode, vnode) {
|
||||||
applyDirectives(oldVnode, vnode, 'update', true)
|
applyDirectives(oldVnode, vnode, 'update', true)
|
||||||
},
|
},
|
||||||
destroy: function (vnode) {
|
destroy: function unbindDirectives (vnode) {
|
||||||
applyDirectives(null, vnode, 'unbind')
|
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) {
|
export function createElement (tagName) {
|
||||||
return document.createElement(tagName)
|
return document.createElement(tagName)
|
||||||
|
@ -34,6 +34,13 @@ export function renderMixin (Vue) {
|
|||||||
return resolveAsset(this.$options, 'directives', id, true)
|
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
|
// toString for mustaches
|
||||||
Vue.prototype.__toString__ = function (val) {
|
Vue.prototype.__toString__ = function (val) {
|
||||||
return val == null
|
return val == null
|
||||||
|
Loading…
Reference in New Issue
Block a user