前端开发工程师-第7章 VUE进阶

前端开发工程师-第6章 VUE基础

第一阶段B(前端框架)11天 64学时

第7章 VUE进阶(6)

[学习课时] 本章共需要学习  18  课时

[目的要求] 

  1. 掌握VUE组件的使用

[教学内容]

VUE组件

  1. 创建组件

语法:

 

Vue.component( id, [definition] )

 

参数

  • {string} id
  • {Function | Object} [definition]

 

用法

 

注册或获取全局组件。注册还会自动使用给定的id设置组件的名称

 

// 注册组件,传入一个扩展过的构造器

Vue.component('my-component', Vue.extend({ /* ... */ }))

// 注册组件,传入一个选项对象 (自动调用 Vue.extend)

Vue.component('my-component', { /* ... */ })

// 获取注册的组件 (始终返回构造器)

var MyComponent = Vue.component('my-component')

 

 

注册局部组件

 

通过一个普通的 JavaScript 对象来定义组件:

 

var ComponentA = { /* ... */ }

var ComponentB = { /* ... */ }

var ComponentC = { /* ... */ }

 

然后在 components 选项中定义你想要使用的组件:

 

new Vue({

el: '#app'

components: {

'component-a': ComponentA,

'component-b': ComponentB

}

})

 

对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。

 

 

案例:demo01

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            {{ message }}

                            <button-counter></button-counter>

                            <button-counter></button-counter>

                   </div>

         </body>

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('button-counter', {

                            data: function() {

                                     return {

                                               count: 0

                                     }

                            },

                            template: '<button v-on:click="count++">点击数字加一 {{ count }}</button>'

                   })

                   var app = new Vue({

                            el: '#app',

                            data: {

                                     message: '你好呀,这是vue绑定的数据!'

                            }

                   })

         </script>

 

</html>

效果图

 

当我们定义这个 <button-counter> 组件时,你可能会发现它的 data 并不是像这样直接提供一个对象:

data: {
  count:
0
}

 

取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

data: function () {
 
return {
    count:
0
  }
}

 

如果 Vue 没有这条规则,点击一个按钮就可能会像如下代码一样影响到其它所有实例

 

  1. 通过 Props 向模版内传递数据

Props可以理解为组件的自定义属性,就像html元素的属性。

 

Vue.component('msg', {

  props: ['title'],

  template: '<h3>{{ title }}</h3>'

})

 

 

案例:demo02

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            {{message}}

                            <ul>

                                     <msg count="123"></msg>

                                     <msg count="456"></msg>

                            </ul>

                   </div>

         </body>

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('msg', {

                             props: ['count'],

                            template: '<li> {{count}} </li>'

                   })

                   var app = new Vue({

                            el: '#app',

                            data: {

                                     message: '你好呀,这是vue绑定的数据!'

                            }

                   })

         </script>

 

</html>

效果图

 

使用 v-bind 来动态传递 prop,

 

v-bind:自定义属性名

 

案例:demo03

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

                   <style type="text/css">

                            ul {

                                     list-style-type: none;

                                     padding: 0;

                                     margin: 0;

                            }

                           

                            .item {

                                     height: 100px;

                                     background-color: rgba(255,255,0,0.06);

                                     padding: 10px 10px;

                                     margin: 10px 0px;

                                     box-shadow: 2px 3px 2px 1px gainsboro,

                                     1px 1px 0px 1px gainsboro inset;

                            }

                            .item:hover{

                                     background-color: rgba(255,0,0,0.06);

                            }

                            .avatar {

                                     width: 100px;

                                     height: 100px;

                                     text-align: center;

                                     float: left;

                            }

                           

                            .avatar img {

                                     width: 100%;

                            }

                           

                            .content {

                                     height: 100px;

                                     padding-left: 100px;

                            }

                           

                            .title {

                                     height: 30px;

                                     line-height: 30px;

                                     font-size: 25px;

                                     border-bottom: 1px solid gainsboro;

                                     white-space: nowrap;

                                     text-overflow: ellipsis;

                                     overflow: hidden;

                                     padding: 0px 10px;

                            }

                           

                            .desc {

                                     height: 50px;

                                     overflow: hidden;

                                     color: grey;

                                     padding: 10px 10px;

                            }

                   </style>

         </head>

 

         <body>

                   <div id="app">

                            <ul>

                                     <msg v-for="n in news" v-bind:n="n"></msg>

                            </ul>

                   </div>

         </body>

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('msg', {

                             props: ['n'],

                            template: '<li> <div class="item"> <div class="avatar"> <img v-bind:src="n.img" /> </div> <div class="content"> <div class="title">{{n.title}}</div> <div class="desc">{{n.desc}}</div> </div> </div> </li>'

                   })

                   // 数据对象

                   var data = {

                            news: [{

                                     img: 'img/avatar-1.jpg',

                                     title: '拆解高岭之花十元女神的妆容小心机',

                                     desc: '日剧《高岭之花》自从开播就收视不俗,剧中石原里美不停穿插时装与和服造型,让粉丝看得非常过瘾!'

                            }, {

                                     img: 'img/avatar-2.jpg',

                                     title: '一双乐福鞋 搞定秋季所有搭配',

                                     desc: '天气转凉,夏天的各种露脚趾和露脚背的鞋都要准备收起来了,再也不用兢兢业业、精精致致地涂好每一颗脚趾甲(是不是松了一口气?)是时候提前把适合秋天的鞋子准备起来了,而单凭一己之力就能撑过整个秋天的鞋子非Loafer莫属。'

                            }, {

                                     img: 'img/avatar-3.jpg',

                                     title: '又不知道做什么样的美甲?莫兰迪色调了解一下',

                                     desc: '因《延禧攻略》而爆红的「莫兰迪色调」最近成为热搜,挑选了「莫兰迪色」指甲油,做出五种美甲变化,其中有单色跳色的搭配,女孩可以直接模仿,或从中挑选出喜欢的颜色买回家自己擦'

                            }]

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data

                   })

         </script>

 

</html>

效果图

 

  1. 在组件中绑定事件$emit

$emit用在组件模版中,可以定义组件模版内自定义事件。

 

案例:demo04

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <ul>

                                     <!--v-on:test="count++"——访问组件内的自定义事件test,并且让count自增-->

                                     <!--v-bind:count——向组件内传入count变量-->

                                     <msg v-on:test="count++" v-bind:count="count"></msg>

                            </ul>

                   </div>

                  

         </body>

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('msg', {

                             props: ['count'],

                            //v-on:click="$emit(\'test\')"——通过$emit将自定义属性绑定到click事件上

                            template: '<button v-on:click="$emit(\'test\')">点击次数{{count}}</button>'

                   })

                   // 数据对象

                   var data = {

                            count: 0

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data

                   })

         </script>

 

</html>

效果图

 

还可以使用 $emit 的第二个参数来提供一个值,然后通过$event 访问到这个值。

 

案例:demo05

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <ul>

                                     <!--v-on:test="fun"——访问组件内的自定义事件test,并且调用抛出的变量10-->

                                     <!--v-bind:count——向组件内传入count变量-->

                                     <msg v-on:test="count += $event" v-bind:count="count"></msg>

                            </ul>

                   </div>

                  

         </body>

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('msg', {

                             props: ['count'],

                             //v-on:click="$emit(\'test\',10)"——通过$emit将自定义属性绑定到click事件上

                            template: '<button v-on:click="$emit(\'test\',10)">点击次数{{count}}</button>'

                   })

                   // 数据对象

                   var data = {

                            count: 0

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data

                   })

         </script>

 

</html>

效果图

 

也可以直接调用某个方法

 

案例:demo06

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <ul>

                                     <!--v-on:test="fun"——访问组件内的自定义事件test,并且调用fun方法-->

                                     <!--v-bind:count——向组件内传入count变量-->

                                     <msg v-on:test="fun" v-bind:count="count"></msg>

                            </ul>

                   </div>

 

         </body>

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('msg', {

                            props: ['count'],

                            //v-on:click="$emit(\'test\',10)"——通过$emit将自定义属性绑定到click事件上

                            template: '<button v-on:click="$emit(\'test\',10)">点击次数{{count}}</button>'

                   })

                   // 数据对象

                   var data = {

                            count: 0

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data,

                            methods: {

                                     fun: function(enlargeAmount) {

                                               alert(enlargeAmount);

                                     }

                            }

                   })

         </script>

 

</html>

效果图

 

  1. 在组件中使用v-model

为了让它正常工作,这个组件内的 <input> 必须:

 

  1. 将其 value 特性绑定到一个名叫 value 的 prop 上
  2. 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出

 

案例:demo07

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <ul>

                                     <msg v-model="searchText"></msg>

                                     <span>{{searchText}}</span>

                            </ul>

                   </div>

 

         </body>

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('msg', {

                            props: ['searchText'],

                            //v-on:input="$emit(\'input\', $event.target.value)"——通过$emit将输入框的值传入input事件内

                            template: '<input v-bind:value="searchText" v-on:input="$emit(\'input\', $event.target.value)"></input>'

                   })

                   // 数据对象

                   var data = {

                            searchText: '默认文字'

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data

                   })

         </script>

 

</html>

效果图

 

  1. 模版内容slot

<slot></slot>用于在模版内将模版标签的内容添加到模版内的元素内容中

 

案例:demo08

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

                                                   </head>     

 

         <body>

                   <div id="app">

                            <ul>

                                     <!--模版内的内容会通过<slot></slot>标签添加到模版内-->

                                     <msg>添加的文字</msg>

                      <msg>

                                               <div>

                                                        <img src="avatar.jpg" width="100"/>

                                               </div>

                                     </msg>

                                     <span>{{searchText}}</span>

                            </ul>

                   </div>

 

         </body>

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('msg', {

                            props: ['searchText'],

                            template: '<span><slot></slot></span>'

                   })

                   // 数据对象

                   var data = {

                            searchText: '默认文字'

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data

                   })

         </script>

 

</html>

效果图

 

  1. 动态组件

动态组件就是可以在需要的时候动态的切换组件。

 

  1. 需要使用<component>组件
  2. 再在<component>上添加v-bind:is属性动态绑定组件名

 

 

案例:demo09

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                             <button

                                v-for="tab in tabs"

                                v-bind:key="tab"

                                v-on:click="currentTab = tab">{{ tab }}</button>

                            <component

                       v-bind:is="currentTabComponent"></component>

                   </div>

 

         </body>

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('tab-page-1', {

                            template: '<div>第一个组件</div>'

                   })

                   Vue.component('tab-page-2', {

                            template: '<div>第二个组件</div>'

                   })

                   Vue.component('tab-page-3', {

                            template: '<div>第三个组件</div>'

                   })

                   // 数据对象

                   var data = {

                            currentTab: 'page-1',

                       tabs: ['page-1', 'page-2', 'page-3']

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data,

                            computed: {

                                     currentTabComponent: function() {

                                               //必须使用this.currentTab

                                               return 'tab-' + this.currentTab.toLowerCase();

                                     }

                            }

                   })

         </script>

 

</html>

效果图

VUE过度

Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡

  1. 条件渲染 (使用 v-if)
  2. 条件展示 (使用 v-show)
  3. 动态组件
  4. 组件根节点

 

案例:demo10

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <button v-on:click="show = !show">显示/隐藏</button>

                            <transition name="fade">

                                     <p v-if="show">使用transition来实现fade属性</p>

                            </transition>

                   </div>

         </body>

 

         <script type="text/javascript">

                   // 数据对象

                   var data = {

                            show: true

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data

                   })

         </script>

 

</html>

效果图

 

  1. 自定义过渡效果

在进入/离开的过渡中,会有 6 个 class 切换。

 

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
  4. v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

 

https://cn.vuejs.org/images/transition.png

 

对于这些在过渡中切换的类名来说,如果你使用一个没有名字的<transition>,则 v-是这些类名的默认前缀。如果你使用了<transition name="my-transition">,那么v-enter 会替换为 my-transition-enter

 

 

v-enter-active  v-leave-active 可以控制进入/离开过渡的不同的缓和曲线

 

案例:demo11

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <link rel="stylesheet" type="text/css" href="css/animate.min.css"/>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <style type="text/css">

                            .name-enter{

                                     font-size: 0px;

                            }

                            .name-enter-to{

                                     font-size: 30px;

                                     color: red;

                            }

                            .name-enter-active{

                                     transition-duration: 3s;

                            }

                            .name-leave{

                                     font-size: 30px;

                            }

                            .name-leave-to{

                                     font-size: 0px;

                            }

                            .name-leave-active{

                                     transition-duration: 3s;

                            }

                   </style>

                   <div id="app">

                            <button v-on:click="show = !show">显示/隐藏</button>

                            <transition name="name">

                                     <p v-if="show">使用transition来实现fade属性</p>

                            </transition>

                   </div>

         </body>

 

         <script type="text/javascript">

                   // 数据对象

                   var data = {

                            show: true

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data

                   })

         </script>

 

</html>

效果图

 

  1. 自定义过渡的类名

我们可以通过以下特性来自定义过渡类名:

enter-class

enter-active-class

enter-to-class (2.1.8+)

leave-class

leave-active-class

leave-to-class (2.1.8+)

 

他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。

 

案例:demo12

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <link rel="stylesheet" type="text/css" href="css/animate.min.css"/>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <button v-on:click="show = !show">显示/隐藏</button>

                            <transition name="name"

                                     enter-active-class="animated bounceInDown"

                                     leave-active-class="animated bounceOutRight">

                                     <p v-if="show">使用transition来实现fade属性</p>

                            </transition>

                   </div>

         </body>

 

         <script type="text/javascript">

                   // 数据对象

                   var data = {

                            show: true

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data

                   })

         </script>

 

</html>

效果图

 

  1. 过度事件

可以使用下面的如下如下这些事件:

 

当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。

 

<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"  leaveCancelled 只用于 v-show 中
>
</transition>

 

案例:demo13

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <link rel="stylesheet" type="text/css" href="css/animate.min.css"/>

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <button v-on:click="show = !show">显示/隐藏</button>

                            <transition

                                     v-on:before-enter="beforeEnter"

                                     v-on:enter="enter"

                                     v-on:after-enter="afterEnter"

                                    

                                     v-on:before-leave="beforeLeave"

                                     v-on:leave="leave"

                                     v-on:after-leave="afterLeave">

                                     <p v-if="show">使用transition来实现fade属性</p>

                            </transition>

                   </div>

         </body>

 

         <script type="text/javascript">

                   // 数据对象

                   var data = {

                            show: true

                   };

                   // 事件对象

                   var methods = {

                            beforeEnter: function(el) {

                                     console.log('进入过度前');

                            },

                            // 当与 CSS 结合使用时

                            // 回调函数 done 是可选的

                            enter: function(el, done) {

                                     console.log('开始进入过度');

                            },

                            afterEnter: function(el) {

                                     console.log('进入过度后');

                            },

                           

 

                            beforeLeave: function(el) {

                                     console.log('退出过度前');

                            },

                            // 当与 CSS 结合使用时

                            // 回调函数 done 是可选的

                            leave: function(el, done) {

                                     console.log('开始退出过度');

                            },

                            afterLeave: function(el) {

                                     console.log('退出过度后');

                            }

                   };

                   var app = new Vue({

                                               el:'#app',

                            data: data,

                            methods:methods

                   })

         </script>

 

</html>

效果图

 

 

  1. 多个按钮状态切换

原理:

使用多个 v-if 的多个元素的过渡可以重写为绑定了动态属性的单个元素过渡。例如:

<transition>
  <button v-if="docState === 'saved'" key="saved">
    编辑
  </button>
  <button v-if="docState === 'edited'" key="edited">
    保存
  </button>
  <button v-if="docState === 'editing'" key="editing">
    取消
  </button>
</transition>

 

可以重写为:

<transition>
  <button v-bind:key="docState">
    {{buttonMessage}}
 
</button>
</transition>

 

然后VUE会自动在多个按钮状态之间切换,当然也可以添加自定义的动画等

 

过渡模式有两种:

  1. in-out:新元素先进行过渡,完成之后当前元素过渡离开。
  2. out-in:当前元素先进行过渡,完成之后新元素过渡进入。

 

 

案例:demo14

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <link rel="stylesheet" type="text/css" href="css/animate.min.css" />

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <transition mode="in-out">

                                     <button v-bind:key="docState" @click="change">

                                               {{ buttonMessage }}

                                     </button>

                            </transition>

                            <br>

                            <transition mode="out-in"

                                     enter-active-class="animated bounceInDown"

                                     leave-active-class="animated bounceOutRight">

                                     <button v-bind:key="docState" @click="change">

                                               {{ buttonMessage }}

                                     </button>

                            </transition>

                   </div>

         </body>

 

         <script type="text/javascript">

                   // 数据对象

                   var data = {

                            index: 0,

                            isEditing: true,

                            arr: ['saved', 'edited', 'editing']

                   };

                   // 事件对象

                   var computed = {

                            docState: function() {

                                     return this.arr[this.index];

                            },

                            buttonMessage: function() {

                                     switch(this.docState) {

                                               case 'saved':

                                                        return '编辑'

                                               case 'edited':

                                                        return '保存'

                                               case 'editing':

                                                        return '取消'

                                     }

                            }

                   };

                   var methods = {

                            change:function() {

                                     this.index = (++this.index) % 3;

                            }

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data,

                            computed: computed,

                            methods: methods

                   })

         </script>

 

</html>

效果图

 

 

  1. 多个组件过度切换

多个组件也可以利用这个原理来实现相互切换。

 

案例:demo15

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <link rel="stylesheet" type="text/css" href="css/animate.min.css" />

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <button

                                v-for="tab in tabs"

                                v-bind:key="tab"

                                v-on:click="view = tab">{{ tab }}</button>

 

                            <transition

                                     mode="out-in"

                                     enter-active-class="animated bounceInDown"

                                     leave-active-class="animated bounceOutUp">

                                     <component v-bind:is="view"></component>

                            </transition>

                   </div>

         </body>

 

         <script type="text/javascript">

                   // 定义一个名为 button-counter 的新组件

                   Vue.component('tab-page-1', {

                            template: '<div>1个组件</div>'

                   })

                   Vue.component('tab-page-2', {

                            template: '<div>2个组件</div>'

                   })

                   Vue.component('tab-page-3', {

                            template: '<div>3个组件</div>'

                   })

 

                   // 数据对象

                   var data = {

                            view: 'tab-page-1',

              tabs: ['tab-page-1', 'tab-page-2', 'tab-page-3']

                   };

                   // 事件对象

                   var computed = {

                            currentTabComponent: function() {

                                     //必须使用this.currentTab

                                     return 'tab-' + this.currentTab.toLowerCase();

                            }

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data,

                            computed: computed

                   })

         </script>

 

</html>

效果图

 

 

  1. 列表过渡

列表需要显示所有的列表项,显然不能再使用<transition></transition>因为<transition></transition>在同一时间只会显示一个元素,

 

所有需要使用另一个过度<transition-group></transition-group>,这个组件过渡模式不可用。

 

案例:demo16

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <link rel="stylesheet" type="text/css" href="css/animate.min.css" />

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <button v-on:click="add">添加</button>

                            <button v-on:click="remove">删除</button>

                            <transition-group

                                     mode="out-in"

                                     enter-active-class="animated bounceInDown"

                                     leave-active-class="animated bounceOutRight">

                                     <div v-for="item in items" v-bind:key="item" class="list-item">

                                  {{ item }}

                                </div>

                            </transition-group>

                   </div>

         </body>

 

         <script type="text/javascript">

                   // 数据对象

                   var data = {

                            items: [1, 2, 3, 4, 5, 6, 7, 8, 9],

                            nextNum: 10

                   };

                   // 事件对象

                   var methods = {

                            randomIndex: function() {

                                     return Math.floor(Math.random() * this.items.length)

                            },

                            add: function() {

                                     //splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目

                                     //index   必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。

                                     //howmany    必需。要删除的项目数量。如果设置为 0,则不会删除项目。

                                     //item1, ..., itemX  可选。向数组添加的新项目。

                                     this.items.splice(this.randomIndex(), 0, this.nextNum++)

                            },

                            remove: function() {

                                     this.items.splice(this.randomIndex(), 1)

                            },

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data,

                            methods: methods

                   })

         </script>

 

</html>

效果图

 

  1. 列表打乱顺序

想打乱顺序只需要打乱原本数据的顺序,VUE就会自动更新数据,并且当数据变化后,数据交换的时候还会出发过度效果。

 

案例:demo16

<!DOCTYPE html>

<html>

 

         <head>

                   <meta charset="UTF-8">

                   <title></title>

                   <link rel="stylesheet" type="text/css" href="css/animate.min.css" />

                   <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>

                   <script src="lodash.js" type="text/javascript" charset="utf-8"></script>

         </head>

 

         <body>

                   <div id="app">

                            <button v-on:click="add">添加</button>

                            <button v-on:click="remove">删除</button>

                            <button v-on:click="shuffle">乱序</button>

                            <transition-group

                                     mode="out-in"

                                     enter-active-class="animated bounceInDown"

                                     leave-active-class="animated bounceOutRight">

                                     <div v-for="item in items" v-bind:key="item" class="list-item">

                                               {{ item }}

                                     </div>

                            </transition-group>

                   </div>

         </body>

 

         <script type="text/javascript">

                   // 数据对象

                   var data = {

                            items: [1, 2, 3, 4, 5, 6, 7, 8, 9],

                            nextNum: 10

                   };

                   // 事件对象

                   var methods = {

                            randomIndex: function() {

                                     return Math.floor(Math.random() * this.items.length)

                            },

                            add: function() {

                                     //splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目

                                     //index   必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。

                                     //howmany    必需。要删除的项目数量。如果设置为 0,则不会删除项目。

                                     //item1, ..., itemX  可选。向数组添加的新项目。

                                     this.items.splice(this.randomIndex(), 0, this.nextNum++)

                            },

                            remove: function() {

                                     this.items.splice(this.randomIndex(), 1)

                            },

                            shuffle: function() {

                                     this.items.sort(function(){

                                               return 0.5 - Math.random();

                                     });

                            }

                   };

                   var app = new Vue({

                            el: '#app',

                            data: data,

                            methods: methods

                   });

 

                   function shuffle(arr) {

                            var index = -1;

                            var length = arr.length;

                            var lastIndex = length - 1;

 

                            var size = size === undefined ? length : size;

                            while(++index < size) {

                                     var rand = index + Math.floor(Math.random() * (lastIndex - index + 1));

                                     var value = arr[rand];

                                     arr[rand] = arr[index];

                                     arr[index] = value;

                            }

                            arr.length = size;

                            return arr;

                   }

         </script>

 

</html>

效果图

 

[作业实验]

  1. 打乱矩阵


  1. HTML+CSS+JS精细化教程(新)适合学习和巩固基础(必掌握技能)
  2. JAVA语言(面向对象都不是事,重点是多线程、反射、网络编程、界面编程、设计模式、工程架构、文件系统)
  3. JAVA WEB(MySQL、JDBC、JSP、JSTL、EL、Servlet、Spring、Struts、MyBatis、SpringData等)
  4. Spring Boot2(新版2.X、底层原理深入剖析、更有点餐系统、大型博客系统、商铺平台等完整项目开始视频和源码)
  5. Python(小白基础语法、RESTfull API开发、爬虫、Django、Linux系统、制作小工具)
  6. Photoshop(CS5、CS6、CC2018视频教程、海量素材、酷炫特效制作、经典案例几百集)
  7. Unity2D/3D(手游开发、脚本开发、3D人物模型设计、3D动画、3D塔防游戏、第一人称游戏案例视频跟着做)
  8. Android原生开发(大型OA系统、游戏开发、物联网开发、3D模型显示、单机游戏开发)
  9. IOS原生开发(各种收费应用、游戏开发、工具开发、物联网开发)
  10. PHP(HTML+CSS+JS+PHP+MySQL+MVC+ThinkPHP+Linux+Nginx+Redis)

猜你喜欢

转载自blog.csdn.net/starzhangkiss/article/details/83010378