vue

vue路由配合transition过渡

"vue"

Posted by ZWW on April 1, 2017

“vue路由”

Vue.js的一大特色就是构建单页面应用十分方便,既然要方便构建单页面应用那么自然少不了路由,vue-router就是vue官方提供的一个路由框架。总体来说,vue-router设计得简单好用。

一个demo:

    <!-- html部分,省略head -->
    <div id="app">
        <div class="content">
            <router-link to="/goods">商品</router-link>
            <router-link to="/ratings">评论</router-link>
            <router-link to="/seller">商家</router-link>
    </div>
    <router-view></router-view>
    </div>
    <script src="https://segmentfault.com/a/path-to-vue"></script>
    <script src="https://segmentfault.com/a/path-to-vue-router"></script>

    // 首先定义或者引入路由的组件
    // 方法一:直接定义路由组件
    const goods = { template: '<p>goods</p>' };
    const ratings = { template: '<p>ratings</p>' };
    const seller = { template: '<p>seller</p>' };
    // 方法二:import引入路由组件
    import goods from 'components/goods/goods';
    import ratings from 'components/ratings/ratings';
    import seller from 'components/seller/seller';
    // 然后定义路由(routes),components还可以是Vue.extend()创建的
    const routes = [
        { path: '/goods', component: goods },
        { path: '/ratings', component: ratings },
        { path: '/seller', component: seller }
    ];
    // 接着创建路由实例
    const router = new VueRouter({
    // ES6缩写语法,相当于routes:routes
    routes  
    });
    // 最后创建vue实例并挂载
    const app = new Vue({
        el: '#app',
        router
    });
    // 或者
    const app = new Vue({
    router
    }).$mount('#app')

“router-link和router-view”

<p style=”color:blue” font-size:16px;>router-link</p> 从上面例子中的书写形式就可以看出,router-link是一个组件,它默认会被渲染成一个带有链接的a标签,通过to属性指定链接地址。 注意:被选中的router-link将自动添加一个class属性值.router-link-active。这个类可以在路由全局配置的时候修改。

linkActiveClass: 'active'

router-link属性配置

to

这是一个必须设置的属性,否则路由无法生效。它表示路由的链接,可以是一个字符串也可以是一个描述目标位置的对象。

<router-link to="goods"></router-link>
<router-link to="{path='goods'}"></router-link>

replace

一个布尔类型,默认为false。如果replace设置为true,那么导航不会留下history记录,点击浏览器回退按钮不会再回到这个路由。

<router-link to="goods" replace></router-link>

tag

router-link默认渲染成a标签,也有方法让它渲染成其他标签,tag属性就用来设置router-link渲染成什么标签的。

<!-- 渲染成li标签 -->
<router-link to="goods" tag="li"></router-link>

active-class

上面说了被选中的router-link将自动添加一个class属性值.router-link-active,这个属性就是来修改这个class值的。
linkActiveClass: 'active'

<p style=”color:blue” font-size:16px;>router-view</p>

这个组件十分关键,它就是用来渲染匹配到的路由的。 可以给router-view组件设置transition过渡,具体用法见Vue2.0 Transition常见用法全解惑。 还可以配合keep-alive使用,keep-alive可以缓存数据,这样不至于重新渲染路由组件的时候,之前那个路由组件的数据被清除了。比如对当前的路由组件a进行了一些DOM操作之后,点击进入另一个路由组件b,再回到路由组件a的时候之前的DOM操作还保存在,如果不加keep-alive再回到路由组件a时,之前的DOM操作就没有了,得重新进行。如果你的应用里有一个购物车组件,就需要用到keep-alive。

    <transition>
      <keep-alive>
        <router-view></router-view>
      </keep-alive>
    </transition>

小需求?

多页面应用我们可以给每一个页面都设置一个不同的标题,但是如果是单页面应用的路由呢?其实也是可以实现的,实现的方法不止一种,我之前用的是结合命名路由和导航钩子函数的方法。如下:

// 定义路由的时候如下定义,name也可为中文
const routes = [
{ path: '/goods', component: goods, name: 'goods' },
{ path: '/ratings', component: ratings, name: 'ratings' },
{ path: '/seller', component: seller, name: 'seller' }
];
// 创建路由实例
const router = new VueRouter({
routes: routes
})
// 关键在这里,设置afterEach钩子函数
router.afterEach((to, from, next) => {
document.title = to.name;
}) 命名路由

既然用到了命名路由,这里就提一下吧。命名路由就是用一个名称来标识一个路由,在定义路由的时候设置一个name属性即可。在router-link中也可以用路由的名字来链接到一个路由。

<router-link :to="{ name: 'seller'}">seller</router-link>

怎么刚进入应用就渲染某个路由组件?

重定向 和vue1.0有点却别,具体参见官方文档
const routes = [
{ path: '/', redirect: '/goods'}
]

const routes = [
{ path: '/', redirect: { name: 'goods' }}
]

“过渡”

什么是过渡?

Vue只有在插入,更新或者移除DOM元素时才会应用过渡效果,过渡效果的应用可以通过不同方式实现,官方文档中提到了如下几种:

在CSS过渡和动画中自动应用class; 配合使用第三方的CSS动画库,如Animate.css; 在过渡钩子函数中使用JavaScript直接操作DOM; 配合使用第三方JavaScript动画库,如Velocity; 上面四种方式其实主要就是两种,一个是利用CSS过渡或者动画,另一个是利用JavaScript钩子函数。

怎么应用过渡到元素/组件上?

要想使元素或者组件应用到我们所写的过渡动画,需要使用vue提供的transition来封装组件成为过渡组件,transition需要与如下情景中的任一种一起使用:

v-if(条件渲染) v-show(条件展示) 动态组件 在组建的根节点上,并且被vue实例DOM方法触发,如appendTo方法把组件添加到某个根节点上 当需要插入或者删除封装成过渡元素的元素时,vue将做如下事情:

查找目标元素是否有CSS过渡或者动画,如果有就在适当的时候进行处理; 如果过渡组件设置了JavaScript钩子函数,vue会在相应阶段调用钩子函数; 如果以上两者都没有,DOM操作(插入或者删除)就在下一帧立即执行。

CSS过渡

    <!-- 首先将要过渡的元素用transition包裹,并设置过渡的name,然后添加触发这个元素过渡的按钮(实际项目中不一定是按钮,任何能触发过渡组件的DOM操作的操作都可以) -->
<div>
  <button @click="show=!show">show</button>
  <transition name="fade">
     <p v-show="show">hello</p>
  </transition>
</div>

// 接着为过渡类名添加规则
&.fade-enter-active, &.fade-leave-active
transition: all 0.5s ease     
&.fade-enter, &.fade-leave-active
opacity: 0 

CSS过渡类名

组件过渡过程中,会有四个CSS类名进行切换,这四个类名与上面transition的name属性有关,比如name=”fade”,会有如下四个CSS类名:

fade-enter:进入过渡的开始状态,元素被插入时生效,只应用一帧后立即删除; fade-enter-active:进入过渡的结束状态,元素被插入时就生效,在过渡过程完成之后移除; fade-leave:离开过渡的开始状态,元素被删除时触发,只应用一帧后立即删除; fade-leave-active:离开过渡的结束状态,元素被删除时生效,离开过渡完成之后被删除; 从上面四个类名可以看出,fade-enter-active和fade-leave-active在整个进入或离开过程中都有效,所以CSS的transition属性在这两个类下进行设置。 上面示例中,fade-enter和fade-leave-active类设置CSS为opacity:0,说明过渡刚进入和离开的时候透明度为0,即不显示。当然还可以设置其他的CSS属性,transform属性是除了opacity之外经常在这里被用到的,

自定义过渡类名

上面的四个过渡类名都是根据transition的name属性自动生成的,那么能否自己定义这四个类名呢?答案是可以的,通过enter-class、enter-active-class、leave-class、leave-active-class这四个特性来定义。

JavaScript钩子函数

除了用CSS过渡的动画来实现vue的组件过渡,还可以用JavaScript的钩子函数来实现,在钩子函数中直接操作DOM。我们可以在属性中声明以下钩子:

<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
</transition>

methods: {
// 过渡进入
// 设置过渡进入之前的组件状态
beforeEnter: function (el) {
    // ...
},
// 设置过渡进入完成时的组件状态
enter: function (el, done) {
    // ...
    done()
},
// 设置过渡进入完成之后的组件状态
afterEnter: function (el) {
    // ...
},
enterCancelled: function (el) {
    // ...
},
// 过渡离开
// 设置过渡离开之前的组件状态
beforeLeave: function (el) {
    // ...
},
// 设置过渡离开完成时地组件状态
leave: function (el, done) {
    // ...
    done()
},
// 设置过渡离开完成之后的组件状态
afterLeave: function (el) {
    // ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
    // ...
}
}

此外可以根据this.$route.params进行业务逻辑的判断,例子用的第三方的动效库也是可以的。 router demo

Link: vue2官方:https://cn.vuejs.org/v2/guide/migration-vue-router.html