如何为测试禁用 vue.js 转换?
Posted
技术标签:
【中文标题】如何为测试禁用 vue.js 转换?【英文标题】:How do I disable vue.js transitions for tests? 【发布时间】:2017-12-03 06:09:03 【问题描述】:我有一个 vue.js 组件,它使用 <transition>
元素对隐藏/显示进行动画处理。
为了加快测试,我想禁用动画。我该怎么做?
这里建议* transition: none !important
:https://github.com/vuejs/vue/issues/463,但似乎没有什么不同。
我在这里创建了一个小提琴:https://jsfiddle.net/z11fe07p/2268/
运行“测试”最后输出是“3。显示应该是“无”,它是:块”。如果我将超时时间增加到 100,或者删除 <transition>
元素,我会得到“3。显示应该是“无”的预期输出,它是:无”
那么如何禁用动画以便摆脱setTimeout
调用?
编辑:
我尝试删除所有 css 样式,但仍然遇到同样的问题。因此,只需使用 <transition>
元素即可触发问题。
编辑 2:
将小提琴更新为没有样式,只有<transition>
元素。还包括对$nextTick()
的调用,以确保这不是它行为怪异的原因。
将wait100
的调用改为wait10
,你会看到测试开始失败
https://jsfiddle.net/z11fe07p/2270/
编辑 3:
将示例代码放在这里,这样每个人都可以更轻松地玩耍:)
new Vue(
el: '#app',
template: `
<span>
<button @click="test()">Run test</button>
<transition>
<p v-show="show">Hello, world!</p>
</transition>
</span>
`,
data()
return
show: false,
;
,
methods:
test()
const wait10 = _ => new Promise(resolve => setTimeout(resolve, 10));
const wait100 = _ => new Promise(resolve => setTimeout(resolve, 100));
const showParagraph = _ => this.show = true;
const hideParagraph = _ => this.show = false;
const p = document.querySelector('p');
showParagraph();
this.$nextTick()
.then(wait10)
.then(() =>
const display = getComputedStyle(p).display;
assertEqual(display, 'block');
)
.then(hideParagraph)
.then(this.$nextTick)
.then(wait100)
.then(() =>
const display = getComputedStyle(p).display;
assertEqual(display, 'none');
);
);
function assertEqual(a, b)
if (a !== b)
console.error('Expected "' + a + '" to equal "' + b + '"');
;
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app"></div>
【问题讨论】:
【参考方案1】:你可以在 Vue 上设置一个变量来表示测试,如果你正在测试,可以设置transition hooks 中止。
对于我的示例,您可以使用复选框来控制测试变量的值。第一个测试结果表示发生任何事情之前的状态,因此它与之前运行的第三个测试结果相同。除此之外,您每次都可以拨动测试开关并获得预期的结果。
我已经修改了我的代码以将fadeTransition 隔离为一个带有插槽的单独组件,但我还没有找到一种方法来消除模板中为其添加的标记。
new Vue(
el: '#app',
template: `
<span>
<input type="checkbox" v-model="Vue.testing"> Testing<br>
<button @click="test()">Run test</button>
<fade-transition>
<p id="transition" v-show="show">Hello, world!</p>
</fade-transition>
</span>
`,
components:
fadeTransition:
template: `
<transition name="fade"
@enter="killTransition"
@leave="killTransition"
><slot></slot>
</transition>
`,
methods:
killTransition(el, done)
if (Vue.testing) done();
,
data()
return
show: false,
testing: true
;
,
methods:
test()
const p = document.querySelector('#transition');
let display = getComputedStyle(p).display;
console.log('1. Display should be "none", it is:', display);
this.show = true;
this.$nextTick(() =>
display = getComputedStyle(p).display;
console.log('2. Display should be "block", it is:', display);
this.show = false;
this.$nextTick(() =>
display = getComputedStyle(p).display;
console.log('3. Display should be "none", it is:', display);
);
);
);
.fade-enter-active,
.fade-leave-active
transition: opacity .5s;
.fade-enter,
.fade-leave-to
opacity: 0
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app"></div>
【讨论】:
对我来说这每次都有效,这告诉我我们仍然不明白这里到底发生了什么。这就是我不想选择这个作为接受的答案的原因之一。对不起。 另外,我真的不喜欢用那些只是为了测试的东西弄脏我的模板。那么有什么方法可以从我的测试代码中添加这些道具? 更新了一些关于不同结果的说明。【参考方案2】:我在<transition-group>
遇到了这个问题。我的解决方案是在测试期间使用以下代码替换它。
Vue.component('transition-group',
props: ['tag'],
render(createElement)
return createElement(this.tag || this.$vnode.data.tag || 'span', this.$slots.default);
,
);
这是将<transition-group>
转换为<slot>
的镜像并带有可选的动态定义标记的最低要求。
我可能需要对<transition>
做同样的事情。如果是这样,它可能会更简单,因为<transition>
没有标签属性。
【讨论】:
【参考方案3】:当 env 为 testing
时,我基本上将所有 transition
和 transition-group
s 更改为具有渲染功能的 div。
if (process.env.NODE_ENV === 'testing')
const div =
functional: true,
render: (h, data, children ) => h('div', data, children),
Vue.component('transition', div)
Vue.component('transition-group', div)
【讨论】:
有没有办法扭转这种局面? (我正在尝试打开和关闭转换。) 您是在测试期间尝试切换还是允许用户通过(prefers-reduced-motion)
/ some toggle 之类的方式进行切换?在后一种情况下,我可能会将我的过渡持续时间与全局乘数挂钩。
Like: transition-duration: calc(1s * var(--transition-multiplier))
然后你可以用:root --transition-multiplier: 1 .no-transitions --transition-multiplier: 0
这样的类来切换它【参考方案4】:
也许不是最简单的测试方法,但对于其他场景,可以考虑使用 v-bind 绑定一个没有 CSS 转换关联的转换名称。
v-bind:name="my-var"
this.myVar = “无”
【讨论】:
请花点时间阅读help center 中的editing help。 Stack Overflow 上的格式与其他网站不同。【参考方案5】:我的用例略有不同,但要求相同:我想禁用移动屏幕的某些过渡效果。
我的解决方案是包装成一个组件。这也适用于测试(如果设置了“禁用”,例如 process.env.NODE_ENV === 'testing')。
<template>
<transition v-if="!disable" :name="name" :mode="mode">
<slot></slot>
</transition>
<div v-else>
<slot></slot>
</div>
</template>
<script>
export default
props:
disable: Boolean,
name: String,
mode: String,
,
;
</script>
纯粹为了测试,我认为 Bill Criswell 的回答可能是最干净的。
【讨论】:
以上是关于如何为测试禁用 vue.js 转换?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 std::vector 复制或使用隐式缩小转换禁用 Visual Studio 警告 C4244