javascript - 如何使用 Vue.js 在选择选项上使用转换
问题描述
我有一个关于 Vue.js 转换的快速问题。
在我的 boostrap 模板中,我试图根据所选选项再添加一个选择选项下拉列表。所以,我在第一个选择选项上添加了更改事件。因此,如果我选择“第一项”,则更改类并在行中添加下拉列表,否则将其隐藏。
像这样的东西:
selectTodo: function(e) { let selectValue = e.target.options[e.target.selectedIndex].text if (selectValue === 'Learn Vue') { this.styleObject.display = 'unset'; this.col_md = 'form-group col-md-4'; this.showCropStageList = true; } else { this.showCropStageList = false; this.styleObject.display = 'none'; this.col_md = 'form-group col-md-6'; this.cropStageList = null; } }
我设法做到了,但我希望前两个下拉菜单的过渡更平滑。
我设法设置了一些小提琴,您可以在其中看到第三个选择下拉菜单的平滑滑动过渡,但是如果我将选择从“Learn Vue”更改为其他内容,第三个下拉菜单会隐藏它,但也没有任何动画。
您也可以在下面的片段中看到它!
new Vue({
el: "#app",
data: {
todos: [
{ id:1 ,text: "Learn JavaScript", done: false },
{ id:2 ,text: "Learn Vue", done: false },
{ id:3 ,text: "Play around in JSFiddle", done: true },
{ id:4 ,text: "Build something awesome", done: true }
],
col_md: 'form-group col-md-6',
styleObject: {
display: 'none'
},
showCropStageList: false,
},
methods: {
toggle: function(todo){
todo.done = !todo.done
},
selectTodo: function(e) {
let selectValue = e.target.options[e.target.selectedIndex].text
if (selectValue === 'Learn JavaScript') {
this.styleObject.display = 'unset';
this.col_md = 'form-group col-md-4';
this.showCropStageList = true;
}
else {
this.showCropStageList = false;
this.styleObject.display = 'none';
this.col_md = 'form-group col-md-6';
this.cropStageList = null;
}
}
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.fade-enter {
opacity: 0;
}
.fade-enter-active {
transition: opacity 1s;
}
.fade-leave {}
.fade-leave-active {
transition: opacity 1s;
opacity: 0;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div class="container">
<!-- Content here -->
<div id="app">
<div class="form-row">
<transition name="fade" appear>
<div v-bind:class=col_md>
<label for="cropType" class="col-form-label-sm font-weight-bold">Select Learn Javascript </label>
<select class="form-control" v-on:change="selectTodo" id="cropType" v-model="pickedCropType" @change="getCropsByType()">
<option v-for="(todo, index) in todos" :key="index" :value="todo.id" >
{{todo.text}}
</option>
</select>
</div>
</transition>
<div v-bind:class=col_md>
<label for="cropCulture" class="col-form-label-sm font-weight-bold">2. Second</label>
<select class="form-control" id="cropCulture">
<option v-for="(todo, index) in todos" :key="index" :value="todo.id" >
{{todo.text}}
</option>
</select>
</div>
<transition
enter-active-class="animated fadeInLeft"
leave-active-class="animated fadeOutLeft"
>
<div class="form-group col-md-4" v-if="showCropStageList" v-bind:class="{styleObject }">
<label for="cropStage" class="col-form-label-sm font-weight-bold">3. Third</label>
<select class="form-control" id="cropStage">
<option v-for="(todo, index) in todos" :key="index" :value="todo.id" >
{{todo.text}}
</option>
</select>
</div>
</transition>
</div>
</div>
</div>
您可以看到前两个下拉列表的更改类,但没有任何转换。那么,是否可以为前两个下拉菜单添加一些转换?
编辑 :
如您所见,我正在将课程从 *form-group col-md-6* 更改为 *form-group col-md-4* 并且我想知道是否有可能从 md-6 过渡到 md-4可以更流畅一些。
解决方案
在您的代码中,您直接将类从更新col-md-4
为col-md-6
in selectTodo
。这将导致前两个在第三个 div 完成动画之前<div>
占据该行的全宽。
解决方案、用途this.$nextTick
和setTimeout
。
添加第三个 div 时,延迟执行在前两个<div>
完成动画之前显示第三个 div。
删除第三个 div 时,延迟适用col-md-6
于前两个<div>
,然后第三个<div>
完成动画。
下面是一个示例:(PS :我在这里使用了转换组,因为它对于可重用的转换会更好)
警告:请在整页下测试下面的demo,否则bootstrap会将其视为超小屏幕(<div>
每行放置一个),尽管我认为小屏幕的效果仍然不错。
new Vue({
el: "#app",
data: {
todos: [
{ id:1 ,text: "Learn JavaScript", done: false },
{ id:2 ,text: "Learn Vue", done: false },
{ id:3 ,text: "Play around in JSFiddle", done: true },
{ id:4 ,text: "Build something awesome", done: true }
],
col_md: 'form-group col-md-6',
styleObject: {
display: 'none'
},
showCropStageList: false,
pickedCropType: ''
},
methods: {
getCropsByType: function () {},
toggle: function(todo){
todo.done = !todo.done
},
selectTodo: function(e) {
let selectValue = e.target.options[e.target.selectedIndex].text
if (selectValue === 'Learn Vue') {
this.col_md = 'form-group col-md-4';
this.$nextTick(() => { //delay display the third div before first two div finish animation
setTimeout(()=>{
this.styleObject.display = 'unset';
this.showCropStageList = true;
}, 500)
})
}
else {
this.showCropStageList = false;
this.styleObject.display = 'none';
this.$nextTick(() => { //delay apply `md-6` to first two div before 3rd div finish animation
setTimeout(()=>{
this.col_md = 'form-group col-md-6';
}, 1000)
})
this.cropStageList = null;
}
}
}
})
.sample {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
.fade-item {
transition: all 0.5s;
display:inline-block;
}
.fade-enter {
opacity: 0;
transform: translateX(-130px);
}
.fade-enter-active {
transition: all 1.5s;
}
.fade-leave-to {
transform: translateX(130px);
opacity: 0;
flex: 0 0 20%;
}
.fade-leave-active {
transition: all 1s;
}
#app {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<!-- Content here -->
<div id="app">
<div class="container">
<div class="sample">
<transition-group name="fade" tag="div" class="form-row">
<div v-bind:class="col_md" :key="1" class="fade-item">
<label for="cropType" class="col-form-label-sm font-weight-bold">Select Learn Javascript </label>
<select class="form-control" v-on:change="selectTodo" id="cropType" v-model="pickedCropType" @change="getCropsByType()">
<option v-for="(todo, index) in todos" :key="index" :value="todo.id" >
{{todo.text}}
</option>
</select>
</div>
<div v-bind:class="col_md" :key="2" class="fade-item">
<label for="cropCulture" class="col-form-label-sm font-weight-bold">2. Second</label>
<select class="form-control" id="cropCulture">
<option v-for="(todo, index) in todos" :key="index" :value="todo.id" >
{{todo.text}}
</option>
</select>
</div>
<div class="form-group col-md-4 fade-item" v-if="showCropStageList" v-bind:class="{styleObject }" :key="3">
<label for="cropStage" class="col-form-label-sm font-weight-bold">3. Third</label>
<select class="form-control" id="cropStage">
<option v-for="(todo, index) in todos" :key="index" :value="todo.id" >
{{todo.text}}
</option>
</select>
</div>
</transition-group>
</div>
</div>
</div>
推荐阅读
- json - 没有看到所有的帖子对象?
- xml - 架构检查错误:必须声明元素
- python - 如何在 Python 和 RobotFramework 之间传递在 Python 函数中创建的变量
- powershell - 可以通过 ExpandProperty 获取属性值,但不能通过直接访问
- c# - 当我将 Task.Run 包装在单独的 async/await 方法中时引发 TaskCanceledException
- linker - 与 macOS Mojave 上的框架链接
- git - 如何在同一目录中将 2 个 repos 分组
- shift-register - 移位寄存器中的 CLKCTRL
- angular - Get Tags Value click method in Angular
- java - Hibernate @GenericGenerator(name = "uuid2", strategy = "uuid2") 取出连字符 '-' 到 32 个长度的字符