Vue js bootstrap在崩溃时添加动画

时间:2018-03-31 14:45:49

标签: css vue.js vuejs2 bootstrap-4

我正在制作带有折叠显示/隐藏的侧栏菜单。随着我目前的css崩溃并不顺利,似乎力量充满或看起来有些奇怪。

当项目关闭时,我想要一张平滑过渡的幻灯片。但在我的情况下,发生的事情是当某个项目已经打开并且下一个项目被点击(打开)时。在那里看起来像是强有力的切换,它似乎没有顺利地折叠列表。

有什么可能是更好的方法,请提出一些更好的方法。

Fiddle Implementation.

我不知道我的方法是否正确或我在这里遗漏了什么?



new Vue({
  el: '#app',
  methods: {
    setActiveItemId(itemIndex) {
      if (itemIndex === this.activeItemId) {
        this.activeItemId = ''
        return
      }
      this.activeItemId = itemIndex
    }
  },
  data() {
    return {
      message: 'Hello Vue.js!',
      activeItemId: '',
      sideBar: [{
          name: "Dashboard",
          url: "/dashboard",
          icon: "ti-world",
          children: [{
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            },
            {
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            }
          ]
        },
        {
          name: "Components",
          url: "/components",
          icon: "ti-pencil-alt",
          children: [{
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            },
            {
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            }
          ]
        },
        {
          name: "Validation",
          url: "/components",
          icon: "ti-pencil-alt",
          children: [{
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            },
            {
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            }
          ]
        }
      ]
    }
  },
  computed: {
    isActive() {
      return this.activeItemId !== ''
    }
  }
})

.collapse.show {
  display: block;
}

.collapse {
  display: none;
}

.list-unstyled {
  padding-left: 0;
  list-style: none;
}

.collapse.list-unstyled {
  padding-left: 15px;
}

nav.side-navbar {
  background: #fff;
  min-width: 250px;
  max-width: 250px;
  color: #000;
  -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
  z-index: 999;
}

nav.side-navbar ul a:hover {
  background: orange;
  color: #fff !important;
}

nav.side-navbar ul a {
  padding: 10px 15px;
  text-decoration: none;
  display: block;
  font-weight: 300;
  border-left: 4px solid transparent;
}

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <nav class="side-navbar">
    <ul class="list-unstyled">
      <li>
        <a>
          <i class="ti-home"></i>Home</a>
      </li>
      <li v-for="(x, itemIndex) in sideBar" :key="itemIndex">
        <a @click="setActiveItemId(itemIndex)">
          <i class="fa" :class="x.icon"></i>{{x.name}}
        </a>
        <ul :id="x.id" class="collapse list-unstyled" :class="{'show':activeItemId === itemIndex  && isActive}">
          <li v-for="y in x.children" :key="y.id">
            <a>{{y.name}}</a>
          </li>
        </ul>
      </li>
    </ul>
  </nav>
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:3)

您可以使用Vue's List Transitions<transition-group>标记)。

将子列表ul更改为:

<ul :id="x.id" class="collapse list-unstyled show">
  <transition-group name="list">
    <li v-for="y in (activeItemId === itemIndex  && isActive ? x.children : [])" :key="y.name">
      <a>{{y.name}}</a>
    </li>
  </transition-group>
</ul>

主要是代替隐藏<ul>我们正在将v-for数组更改为/从空。请注意,我还更改了il的键,因为您使用了无效的道具。

为过渡添加以下CSS:

.list-enter {
  opacity: 0;
}
.list-enter-active {
  animation: slide-in .5s ease-out forwards;
}
.list-leave-to, .list-leave-active {
  opacity: 0;
  animation: slide-out .5s ease-out forwards;
}
@keyframes slide-in {
  from { height: 0; } to { height: 40px; }
}
@keyframes slide-out {
  from { height: 40px; } to { height: 0; }
}

更新了JSFiddle here。下面的演示。

new Vue({
  el: '#app',
  methods: {
    setActiveItemId(itemIndex) {
      if (itemIndex === this.activeItemId) {
        this.activeItemId = ''
        return
      }
      this.activeItemId = itemIndex
    }
  },
  data() {
    return {
      message: 'Hello Vue.js!',
      activeItemId: '',
      sideBar: [{
          name: "Dashboard",
          url: "/dashboard",
          icon: "ti-world",
          children: [{
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            },
            {
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            }
          ]
        },
        {
          name: "Components",
          url: "/components",
          icon: "ti-pencil-alt",
          children: [{
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            },
            {
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            }
          ]
        },
        {
          name: "Validation",
          url: "/components",
          icon: "ti-pencil-alt",
          children: [{
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            },
            {
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            }
          ]
        }
      ]
    }
  },
  computed: {
    isActive() {
      return this.activeItemId !== ''
    }
  }
})
.collapse.show {
  display: block;
}

.collapse {
  display: none;
}

.list-unstyled {
  padding-left: 0;
  list-style: none;
}

.collapse.list-unstyled {
  padding-left: 15px;
}

nav.side-navbar {
  background: #fff;
  min-width: 250px;
  max-width: 250px;
  color: #000;
  -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
  z-index: 999;
}

nav.side-navbar ul a:hover {
  background: orange;
  color: #fff !important;
}

nav.side-navbar ul a {
  padding: 10px 15px;
  text-decoration: none;
  display: block;
  font-weight: 300;
  border-left: 4px solid transparent;
}

.list-enter {
  opacity: 0;
}
.list-enter-active {
  animation: slide-in .5s ease-out forwards;
}
.list-leave-to, .list-leave-active {
  opacity: 0;
  animation: slide-out .5s ease-out forwards;
}
@keyframes slide-in {
  from { height: 0; } to { height: 40px; }
}
@keyframes slide-out {
  from { height: 40px; } to { height: 0; }
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <nav class="side-navbar">
    <ul class="list-unstyled">
      <li>
        <a>
          <i class="ti-home"></i>Home</a>
      </li>
      <li v-for="(x, itemIndex) in sideBar" :key="itemIndex">
        <a @click="setActiveItemId(itemIndex)">
          <i class="fa" :class="x.icon"></i>{{x.name}}
        </a>
        <ul :id="x.id" class="collapse list-unstyled show">
          <transition-group name="list">
            <li v-for="y in (activeItemId === itemIndex  && isActive ? x.children : [])" :key="y.name">
              <a>{{y.name}}</a>
            </li>
          </transition-group>
        </ul>
      </li>
    </ul>
  </nav>
</div>

答案 1 :(得分:-1)

有一个更简单的解决方案,请尝试将这部分CSS添加到您的样式中。

.show {
  transition: width 0.5s, height 0.5s, transform 0.5s;
}