uTools-Manuals/docs/vue/guide/transitioning-state.html
2019-04-21 11:50:48 +08:00

478 lines
25 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="content guide with-sidebar transitioning-state-guide">
<h1>状态过渡</h1>
<p>Vue 的过渡系统提供了非常多简单的方法设置进入、离开和列表的动效。那么对于数据元素本身的动效呢,比如:</p>
<ul>
<li>数字和运算</li>
<li>颜色的显示</li>
<li>SVG 节点的位置</li>
<li>元素的大小和其他的属性</li>
</ul>
<p>这些数据要么本身就以数值形式存储,要么可以转换为数值。有了这些数值后,我们就可以结合 Vue 的响应式和组件系统,使用第三方库来实现切换元素的过渡状态。</p>
<h2 id="状态动画与侦听器"><a class="headerlink" href="#状态动画与侦听器" title="状态动画与侦听器"></a>状态动画与侦听器</h2><p>通过侦听器我们能监听到任何数值属性的数值更新。可能听起来很抽象,所以让我们先来看看使用 <a href="https://greensock.com/" rel="noopener" target="_blank">GreenSock</a> 一个例子:</p>
<pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"animated-number-demo"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">v-model.number</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">step</span>=<span class="hljs-string">"20"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{{ animatedNumber }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></code></pre>
<pre><code class="hljs js"><span class="hljs-keyword">new</span> Vue({
<span class="hljs-attr">el</span>: <span class="hljs-string">'#animated-number-demo'</span>,
<span class="hljs-attr">data</span>: {
<span class="hljs-attr">number</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">tweenedNumber</span>: <span class="hljs-number">0</span>
},
<span class="hljs-attr">computed</span>: {
<span class="hljs-attr">animatedNumber</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.tweenedNumber.toFixed(<span class="hljs-number">0</span>);
}
},
<span class="hljs-attr">watch</span>: {
<span class="hljs-attr">number</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">newValue</span>) </span>{
TweenLite.to(<span class="hljs-keyword">this</span>.$data, <span class="hljs-number">0.5</span>, { <span class="hljs-attr">tweenedNumber</span>: newValue });
}
}
})</code></pre>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<div class="demo" id="animated-number-demo">
<input step="20" type="number" v-model.number="number"/>
<p>{{ animatedNumber }}</p>
</div>
<script>
new Vue({
el: '#animated-number-demo',
data: {
number: 0,
tweenedNumber: 0
},
computed: {
animatedNumber: function() {
return this.tweenedNumber.toFixed(0);
}
},
watch: {
number: function(newValue) {
TweenLite.to(this.$data, 0.5, { tweenedNumber: newValue });
}
}
})
</script>
<p>当你把数值更新时,就会触发动画。这个是一个不错的演示,但是对于不能直接像数字一样存储的值,比如 CSS 中的 color 的值,通过下面的例子我们来通过 <a href="https://github.com/tweenjs/tween.js" rel="noopener" target="_blank">Tween.js</a><a href="https://github.com/brehaut/color-js" rel="noopener" target="_blank">Color.js</a> 实现一个例子:</p>
<pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/tween.js@16.3.4"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/color-js@1.0.3"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"example-7"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span>
<span class="hljs-attr">v-model</span>=<span class="hljs-string">"colorQuery"</span>
<span class="hljs-attr">v-on:keyup.enter</span>=<span class="hljs-string">"updateColor"</span>
<span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter a color"</span>
&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">v-on:click</span>=<span class="hljs-string">"updateColor"</span>&gt;</span>Update<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Preview:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">span</span>
<span class="hljs-attr">v-bind:style</span>=<span class="hljs-string">"{ backgroundColor: tweenedCSSColor }"</span>
<span class="hljs-attr">class</span>=<span class="hljs-string">"example-7-color-preview"</span>
&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{{ tweenedCSSColor }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></code></pre>
<pre><code class="hljs js"><span class="hljs-keyword">var</span> Color = net.brehaut.Color
<span class="hljs-keyword">new</span> Vue({
<span class="hljs-attr">el</span>: <span class="hljs-string">'#example-7'</span>,
<span class="hljs-attr">data</span>: {
<span class="hljs-attr">colorQuery</span>: <span class="hljs-string">''</span>,
<span class="hljs-attr">color</span>: {
<span class="hljs-attr">red</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">green</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">blue</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">alpha</span>: <span class="hljs-number">1</span>
},
<span class="hljs-attr">tweenedColor</span>: {}
},
<span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">this</span>.tweenedColor = <span class="hljs-built_in">Object</span>.assign({}, <span class="hljs-keyword">this</span>.color)
},
<span class="hljs-attr">watch</span>: {
<span class="hljs-attr">color</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">animate</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">if</span> (TWEEN.update()) {
requestAnimationFrame(animate)
}
}
<span class="hljs-keyword">new</span> TWEEN.Tween(<span class="hljs-keyword">this</span>.tweenedColor)
.to(<span class="hljs-keyword">this</span>.color, <span class="hljs-number">750</span>)
.start()
animate()
}
},
<span class="hljs-attr">computed</span>: {
<span class="hljs-attr">tweenedCSSColor</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Color({
<span class="hljs-attr">red</span>: <span class="hljs-keyword">this</span>.tweenedColor.red,
<span class="hljs-attr">green</span>: <span class="hljs-keyword">this</span>.tweenedColor.green,
<span class="hljs-attr">blue</span>: <span class="hljs-keyword">this</span>.tweenedColor.blue,
<span class="hljs-attr">alpha</span>: <span class="hljs-keyword">this</span>.tweenedColor.alpha
}).toCSS()
}
},
<span class="hljs-attr">methods</span>: {
<span class="hljs-attr">updateColor</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">this</span>.color = <span class="hljs-keyword">new</span> Color(<span class="hljs-keyword">this</span>.colorQuery).toRGB()
<span class="hljs-keyword">this</span>.colorQuery = <span class="hljs-string">''</span>
}
}
})</code></pre>
<pre><code class="hljs css"><span class="hljs-selector-class">.example-7-color-preview</span> {
<span class="hljs-attribute">display</span>: inline-block;
<span class="hljs-attribute">width</span>: <span class="hljs-number">50px</span>;
<span class="hljs-attribute">height</span>: <span class="hljs-number">50px</span>;
}</code></pre>
<script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>
<script src="https://cdn.jsdelivr.net/npm/color-js@1.0.3"></script>
<div class="demo" id="example-7">
<input placeholder="Enter a color" v-model="colorQuery" v-on:keyup.enter="updateColor"/>
<button v-on:click="updateColor">Update</button>
<p>Preview:</p>
<span class="example-7-color-preview" v-bind:style="{ backgroundColor: tweenedCSSColor }"></span>
<p>{{ tweenedCSSColor }}</p>
</div>
<script>
var Color = net.brehaut.Color
new Vue({
el: '#example-7',
data: {
colorQuery: '',
color: {
red: 0,
green: 0,
blue: 0,
alpha: 1
},
tweenedColor: {}
},
created: function () {
this.tweenedColor = Object.assign({}, this.color)
},
watch: {
color: function () {
function animate () {
if (TWEEN.update()) {
requestAnimationFrame(animate)
}
}
new TWEEN.Tween(this.tweenedColor)
.to(this.color, 750)
.start()
animate()
}
},
computed: {
tweenedCSSColor: function () {
return new Color({
red: this.tweenedColor.red,
green: this.tweenedColor.green,
blue: this.tweenedColor.blue,
alpha: this.tweenedColor.alpha
}).toCSS()
}
},
methods: {
updateColor: function () {
this.color = new Color(this.colorQuery).toRGB()
this.colorQuery = ''
}
}
})
</script>
<style>
.example-7-color-preview {
display: inline-block;
width: 50px;
height: 50px;
}
</style>
<h2 id="动态状态过渡"><a class="headerlink" href="#动态状态过渡" title="动态状态过渡"></a>动态状态过渡</h2><p>就像 Vue 的过渡组件一样,数据背后状态过渡会实时更新,这对于原型设计十分有用。当你修改一些变量,即使是一个简单的 SVG 多边形也可实现很多难以想象的效果。</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.5/TweenLite.min.js"></script>
<div class="demo" id="svg-polygon-demo">
<svg class="demo-svg" height="200" width="200">
<polygon :points="points" class="demo-polygon"></polygon>
<circle class="demo-circle" cx="100" cy="100" r="90"></circle>
</svg>
<label>Sides: {{ sides }}</label>
<input class="demo-range-input" max="500" min="3" type="range" v-model.number="sides"/>
<label>Minimum Radius: {{ minRadius }}%</label>
<input class="demo-range-input" max="90" min="0" type="range" v-model.number="minRadius"/>
<label>Update Interval: {{ updateInterval }} milliseconds</label>
<input class="demo-range-input" max="2000" min="10" type="range" v-model.number="updateInterval"/>
</div>
<script>
new Vue({
el: '#svg-polygon-demo',
data: function () {
var defaultSides = 10
var stats = Array.apply(null, { length: defaultSides })
.map(function () { return 100 })
return {
stats: stats,
points: generatePoints(stats),
sides: defaultSides,
minRadius: 50,
interval: null,
updateInterval: 500
}
},
watch: {
sides: function (newSides, oldSides) {
var sidesDifference = newSides - oldSides
if (sidesDifference > 0) {
for (var i = 1; i <= sidesDifference; i++) {
this.stats.push(this.newRandomValue())
}
} else {
var absoluteSidesDifference = Math.abs(sidesDifference)
for (var i = 1; i <= absoluteSidesDifference; i++) {
this.stats.shift()
}
}
},
stats: function (newStats) {
TweenLite.to(
this.$data,
this.updateInterval / 1000,
{ points: generatePoints(newStats) }
)
},
updateInterval: function () {
this.resetInterval()
}
},
mounted: function () {
this.resetInterval()
},
methods: {
randomizeStats: function () {
var vm = this
this.stats = this.stats.map(function () {
return vm.newRandomValue()
})
},
newRandomValue: function () {
return Math.ceil(this.minRadius + Math.random() * (100 - this.minRadius))
},
resetInterval: function () {
var vm = this
clearInterval(this.interval)
this.randomizeStats()
this.interval = setInterval(function () {
vm.randomizeStats()
}, this.updateInterval)
}
}
})
function valueToPoint (value, index, total) {
var x = 0
var y = -value * 0.9
var angle = Math.PI * 2 / total * index
var cos = Math.cos(angle)
var sin = Math.sin(angle)
var tx = x * cos - y * sin + 100
var ty = x * sin + y * cos + 100
return { x: tx, y: ty }
}
function generatePoints (stats) {
var total = stats.length
return stats.map(function (stat, index) {
var point = valueToPoint(stat, index, total)
return point.x + ',' + point.y
}).join(' ')
}
</script>
<style>
.demo-svg { display: block; }
.demo-polygon { fill: #41B883; }
.demo-circle {
fill: transparent;
stroke: #35495E;
}
.demo-range-input {
display: block;
width: 100%;
margin-bottom: 15px;
}
</style>
<p>上述 demo 背后的代码可以通过<a href="https://jsfiddle.net/chrisvfritz/65gLu2b6/" rel="noopener" target="_blank">这个 fiddle</a> 进行详阅。</p>
<h2 id="把过渡放到组件里"><a class="headerlink" href="#把过渡放到组件里" title="把过渡放到组件里"></a>把过渡放到组件里</h2><p>管理太多的状态过渡会很快的增加 Vue 实例或者组件的复杂性,幸好很多的动画可以提取到专用的子组件。<br/>我们来将之前的示例改写一下:</p>
<pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/tween.js@16.3.4"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"example-8"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">v-model.number</span>=<span class="hljs-string">"firstNumber"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">step</span>=<span class="hljs-string">"20"</span>&gt;</span> +
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">v-model.number</span>=<span class="hljs-string">"secondNumber"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">step</span>=<span class="hljs-string">"20"</span>&gt;</span> =
{{ result }}
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">animated-integer</span> <span class="hljs-attr">v-bind:value</span>=<span class="hljs-string">"firstNumber"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">animated-integer</span>&gt;</span> +
<span class="hljs-tag">&lt;<span class="hljs-name">animated-integer</span> <span class="hljs-attr">v-bind:value</span>=<span class="hljs-string">"secondNumber"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">animated-integer</span>&gt;</span> =
<span class="hljs-tag">&lt;<span class="hljs-name">animated-integer</span> <span class="hljs-attr">v-bind:value</span>=<span class="hljs-string">"result"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">animated-integer</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></code></pre>
<pre><code class="hljs js"><span class="hljs-comment">// 这种复杂的补间动画逻辑可以被复用</span>
<span class="hljs-comment">// 任何整数都可以执行动画</span>
<span class="hljs-comment">// 组件化使我们的界面十分清晰</span>
<span class="hljs-comment">// 可以支持更多更复杂的动态过渡</span>
<span class="hljs-comment">// 策略。</span>
Vue.component(<span class="hljs-string">'animated-integer'</span>, {
<span class="hljs-attr">template</span>: <span class="hljs-string">'&lt;span&gt;{{ tweeningValue }}&lt;/span&gt;'</span>,
<span class="hljs-attr">props</span>: {
<span class="hljs-attr">value</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-built_in">Number</span>,
<span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>
}
},
<span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">tweeningValue</span>: <span class="hljs-number">0</span>
}
},
<span class="hljs-attr">watch</span>: {
<span class="hljs-attr">value</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">newValue, oldValue</span>) </span>{
<span class="hljs-keyword">this</span>.tween(oldValue, newValue)
}
},
<span class="hljs-attr">mounted</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">this</span>.tween(<span class="hljs-number">0</span>, <span class="hljs-keyword">this</span>.value)
},
<span class="hljs-attr">methods</span>: {
<span class="hljs-attr">tween</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">startValue, endValue</span>) </span>{
<span class="hljs-keyword">var</span> vm = <span class="hljs-keyword">this</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">animate</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">if</span> (TWEEN.update()) {
requestAnimationFrame(animate)
}
}
<span class="hljs-keyword">new</span> TWEEN.Tween({ <span class="hljs-attr">tweeningValue</span>: startValue })
.to({ <span class="hljs-attr">tweeningValue</span>: endValue }, <span class="hljs-number">500</span>)
.onUpdate(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
vm.tweeningValue = <span class="hljs-keyword">this</span>.tweeningValue.toFixed(<span class="hljs-number">0</span>)
})
.start()
animate()
}
}
})
<span class="hljs-comment">// 所有的复杂度都已经从 Vue 的主实例中移除!</span>
<span class="hljs-keyword">new</span> Vue({
<span class="hljs-attr">el</span>: <span class="hljs-string">'#example-8'</span>,
<span class="hljs-attr">data</span>: {
<span class="hljs-attr">firstNumber</span>: <span class="hljs-number">20</span>,
<span class="hljs-attr">secondNumber</span>: <span class="hljs-number">40</span>
},
<span class="hljs-attr">computed</span>: {
<span class="hljs-attr">result</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.firstNumber + <span class="hljs-keyword">this</span>.secondNumber
}
}
})</code></pre>
<script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>
<div class="demo" id="example-8">
<input step="20" type="number" v-model.number="firstNumber"/> +
<input step="20" type="number" v-model.number="secondNumber"/> =
{{ result }}
<p>
<animated-integer v-bind:value="firstNumber"></animated-integer> +
<animated-integer v-bind:value="secondNumber"></animated-integer> =
<animated-integer v-bind:value="result"></animated-integer>
</p>
</div>
<script>
Vue.component('animated-integer', {
template: '<span>{{ tweeningValue }}</span>',
props: {
value: {
type: Number,
required: true
}
},
data: function () {
return {
tweeningValue: 0
}
},
watch: {
value: function (newValue, oldValue) {
this.tween(oldValue, newValue)
}
},
mounted: function () {
this.tween(0, this.value)
},
methods: {
tween: function (startValue, endValue) {
var vm = this
function animate () {
if (TWEEN.update()) {
requestAnimationFrame(animate)
}
}
new TWEEN.Tween({ tweeningValue: startValue })
.to({ tweeningValue: endValue }, 500)
.onUpdate(function () {
vm.tweeningValue = this.tweeningValue.toFixed(0)
})
.start()
animate()
}
}
})
new Vue({
el: '#example-8',
data: {
firstNumber: 20,
secondNumber: 40
},
computed: {
result: function () {
return this.firstNumber + this.secondNumber
}
}
})
</script>
<p>我们能在组件中结合使用这一节讲到各种过渡策略和 Vue <a href="transitions.html">内建的过渡系统</a>。总之,对于完成各种过渡动效几乎没有阻碍。</p>
<h2 id="赋予设计以生命"><a class="headerlink" href="#赋予设计以生命" title="赋予设计以生命"></a>赋予设计以生命</h2><p>只要一个动画就可以带来生命。不幸的是当设计师创建图标、logo 和吉祥物的时候,他们交付的通常都是图片或静态的 SVG。所以虽然 GitHub 的章鱼猫、Twitter 的小鸟以及其它许多 logo 类似于生灵,它们看上去实际上并不是活着的。</p>
<p>Vue 可以帮到你。因为 SVG 的本质是数据,我们只需要这些动物兴奋、思考或警戒的样例。然后 Vue 就可以辅助完成这几种状态之间的过渡动画,来制作你的欢迎页面、加载指示、以及更加带有情感的提示。</p>
<p>Sarah Drasner 展示了下面这个 demo这个 demo 结合了时间和交互相关的状态改变:</p>
<p></p><p class="codepen" data-default-tab="result" data-embed-version="2" data-height="265" data-pen-title="Vue-controlled Wall-E" data-slug-hash="YZBGNp" data-theme-id="light" data-user="sdras">查看 <a href="https://codepen.io" rel="noopener" target="_blank">CodePen</a> 上 Sarah Drasner (<a href="https://codepen.io/sdras" rel="noopener" target="_blank">@sdras</a>) 的例子 <a href="https://codepen.io/sdras/pen/YZBGNp/" rel="noopener" target="_blank">Vue-controlled Wall-E</a>.</p><p></p>
<script async="" src="https://production-assets.codepen.io/assets/embed/ei.js"></script>
<div class="guide-links">
<span><a href="transitions.html">进入/离开 &amp; 列表过渡</a></span>
<span style="float: right;"><a href="mixins.html">混入</a></span>
</div>
<div class="footer">
<script src="//m.servedby-buysellads.com/monetization.js" type="text/javascript"></script>
<div class="bsa-cpc"></div>
<script>
(function(){
if(typeof _bsa !== 'undefined' && _bsa) {
_bsa.init('default', 'CKYD62QM', 'placement:vuejsorg', {
target: '.bsa-cpc',
align: 'horizontal',
disable_css: 'true'
});
}
})();
</script>
发现错误?想参与编辑?
<a href="https://github.com/vuejs/cn.vuejs.org/blob/master/srctransitioning-state.md" target="_blank">
在 GitHub 上编辑此页!
</a>
</div>
</div>