javascript - 如何使用 Vue.js 在选择选项上使用转换

标签 javascript css vue.js css-transitions vue-component

我有一个关于 Vue.js 转换的快速问题。

在我的 boostrap 模板中,我尝试根据所选选项再添加一个选择选项下拉列表。因此,我在第一个选择选项上添加了更改事件。因此,如果我选择“第一项”,则更改类并在行中添加下拉列表,否则将其隐藏。

Something like this:

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;
  }
}

我设法做到了这一点,但我希望前两个下拉菜单有更多更平滑的过渡。

我已经成功设置了一些fiddle您可以在其中看到第三个选择下拉列表的平滑幻灯片过渡,但如果我将选择从“学习 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 可能会更平滑一些。

https://jsfiddle.net/Loque/akt0su98/

最佳答案

在您的代码中,您直接从 col-md-4 更新类至col-md-6selectTodo 。它将导致前两个 <div>在第 3 个 div 完成其动画之前,获取该行的全宽

解决方案,使用 this.$nextTicksetTimeout .

添加第三个div时,延迟执行在前两个div之前显示第三个div <div>完成他们的动画。

删除第三个div时,延迟应用col-md-6到前两个<div>第三个之前<div>完成动画。

下面是一个示例:(PS:我在这里使用了transition-group,因为它对于 Reusable Transitions 会更好)

警告:请在全屏下测试下面的演示,否则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>

关于javascript - 如何使用 Vue.js 在选择选项上使用转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51720162/

相关文章:

javascript - 使用 Repeat None,如何使页脚背景适合 100% 宽度

css - Typo3 列宽不协调

html - 如何在所有浏览器和所有移动设备中居中表单

vue.js - 使用 vue-datetime 的 Directus 界面

node.js - 使用 Cypress ,我将如何编写一个简单的测试来检查页面上是否存在 Logo 图像

javascript - 如何从对象数组中的嵌套数组中获取数组值的组合

for 循环中的 Javascript WebSQL 查询。如何知道何时完成?

javascript - JSON.stringify 使对象数组为空

javascript - 为什么我必须包含 JS 文件才能在每个 View 中使用 jquery?

javascript - 使用 Node 和 Discord.js 运行小 While 循环会导致 fatal error