我爱编程

Vue知识点

2018-04-15  本文已影响0人  db366da20578

Vue起步

Axios:ajax数据的获取。
Vue Router:多页面之间的路由。
Vuex:各个组件之间的数据共享。
异步组件:让我们的代码上线性能更优。
递归组件:实现组件自身调用组件自己的效果。
.js、ES6、webpack:项目打包工具、npm:node包管理工具,安装依赖包

Vue在线测试:https://jsfiddle.net/chrisvfritz/50wL7mdz/
Vue不支持IE8以下的版本,因为Vue使用IE8无法模拟的ECMAScript特性。
React 和 Vue 有许多相似之处:https://cn.vuejs.org/v2/guide/comparison.html
数组:arr:['apple','banana','orange','pear']
json:{a:'apple',b:'banana','pear'}

MVVM模式

Vue是一个数据驱动页面的一个框架,基于MVVM模式,M指的是数据,V值得是视图,VM是视图模型,将数据绑定视图上(双向绑定),这个框架着重于VM部分,MVVM有助于将图形用户界面的开发与业务逻辑或后端逻辑(数据模型)的开发分离开来.
对Vue的认识:http://www.mamicode.com/info-detail-1886655.html
M:数据逻辑
V:模板标签
VM:数据变化页面对应的V层也通过改变

MVP:对DOM的操作


image.png

导入Vue包

<!-- 开发环境版本,包含了用帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

下载链接:https://cn.vuejs.org/v2/guide/installation.html#直接用-lt-script-gt-引入

指令

v-是Vue的特殊特性,扩展html标签功能属性
v-model:表单输入和应用状态之间的双向绑定。
v-bind v-bind:title 属性绑定,简写: :title
v-textv-html指令都是插入内容,v-text纯文本,v-html插入html
单向绑定:数据决定页面的显示,页面无法决定数据的内容
双向数据绑定:
例如:根据input选择的不同值而显示不同的内容。
vue内置指令与自定义指令:https://www.cnblogs.com/ilovexiaoming/p/6840383.html

# 组件化应用构建

组件:相当于用xml标签来自定义的实例
prop:把数据传给子组件,props的值是一个数组,代表的意思是获取和设置标签上的属性值
v-bind:todov-bind:key的理解:https://segmentfault.com/q/1010000012226071
v-bind:vue的一个用于绑定html属性的指令,可以绑定已有属性,也可以绑定自定义属性,v-bind:id即表示绑定已有属性id,v-bind:key是为了在v-for循环中给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。
v-on:click 相当于 @click
v-on:click/mouseout/ouuseover/dblclick
[v-once](https://cn.vuejs.org/v2/api/#v-once) v-once
v-once 当数据改变时,插值处的内容不会更新,<span v-once>这个将不会改变: {{ msg }}</span>

一个Vue实例其实是一个MVVM模式中的ViewModel,因此在文档中经常会使用app这个变量名。
API:https://cn.vuejs.org/v2/api/#实例属性
示例属性例如:el、data、computed的属性都是需要看API

#数据与方法

当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。

window.onload=function(){
    var data={
        name:"test",
        age:28
    }
    var app=new Vue({
        data: data
    });
    
    console.log("data.name==app.name "+(data.name==app.name));//data.name==app.name true
    console.log("data.age==app.age "+(data.age==app.age));//data.age==app.age true
    console.log("-----------------------");
    data.name="bin";
    data.age=35;
    console.log("data.name==app.name "+(data.name==app.name));//data.name==app.name true
    console.log("data.age==app.age "+(data.age==app.age)); //data.age==app.age true
    console.log("-----------------------");
    app.name="xu";
    app.age=49;
    console.log("data.name==app.name "+(data.name==app.name)); //data.name==app.name true
    console.log("data.age==app.age "+(data.age==app.age)); //data.age==app.age true
}

Vue 实例暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来。

window.onload=function(){
    var data={
        name:"test",
        age:28
    }
    var app=new Vue({
        el:'#app',
        data: data
    });
    console.log(app.$el==document.getElementById("app"));//true
    console.log(app.$data==data); //true
}

#生命周期

https://segmentfault.com/a/1190000008570622
生命周期函数就是Vue实例在某一个时间点会自动执行的函数。

image.png

beforeCreate:创建实例初始化后会自动执行beforeCreate函数
created:当处理外部的注入,包括双向绑定等相关内容后执行created函数。
beforeMount:模板和数据相结合,即将挂载到页面上的一瞬间,之前的这个时间点执行beforeMount函数。
mounted:dom元素挂载到页面上后执行mounted函数。

#计算属性的getter和setter

# 原始 HTML

双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令:

<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
image.png
# v-bind 缩写
<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>
# v-on 缩写
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>

为了输出真的HTML字符串,需要用三个花括号标签:
<div>{{{ raw_html }}}</div>
过滤器:Filter
{{ message| capitalize }} 不能在表达式内使用过滤器,只能添加到表达式的后面。

# 计算属性:
<div id="app">
  <input v-model="FirstName"/>
  <input v-model="LastName"/>
  <div>{{FullName}}</div>
 <!-- 如果没有FullName的情况下,应该写成{{FirstName}}{{LastName}}而computed也不存在
</div>
new Vue({
  el: '#app',
  data: {
    FirstName: '',
    LastName:''
  },
  computed: {  //计算属性,把FirstName和LastName加起来
    FullName: function(){
        return this.FirstName + '' + this.LastName
    }
  }
})
# 侦听器:侦听某一数据的变化,一旦数据变化,就可以在侦听做一些逻辑。
<div id="app">
  <input v-model="FirstName"/>
  <input v-model="LastName"/>
  <div>{{FullName}}</div>
  <div>{{count}}
</div>
new Vue({
  el: '#app',
  data: {
    FirstName: '',
    LastName:'',
    count:0,
  },
  computed: { 
    FullName: function(){
        return this.FirstName + '' + this.LastName
    }
  },
  watch:{ //只要在input输入框输入一次值就会统计数量
    FullName:function(){
        this.count++
    }
  }
})

加了<keep-alive>之后,要让页面每次加载都请求一个ajax,除了加activated钩子,也可以在<keep-alive>标签上写exclude="",除了Detail外

<keep-alive exclude="Detail">
  <router-view/>
</keep-alive>

每个组件的name有什么用:
1、做递归组件的时候需要调用
2、对某个页面取消缓存
3、使用Vue devtools时可看到

scroll多个页面互相影响,https://router.vuejs.org/guide/advanced/scroll-behavior.html#async-scrolling
放在router里面的index.js

export default new Router({
  routes: [{
    path: '/',
    name: 'Home',
    component: Home
  }, {
    path: '/city',
    name: 'City',
    component: City
  }, {
    path: '/detail/:id',
    name: 'Detail',
    component: Detail
  }],
  scrollBehavior (to, from, savedPosition) {
    return { x: 0, y: 0 }
  }
})
# 组件
#todolist功能开发
<div id="app">
  <input v-model="inputValue"/>
  <button @click="handleSubmit">提交</button>
  <ul>
    <li v-for="(item,index) of msgList" :key="index">
    <!-- 如果有index需要用of,如果就一个item就用in即可 -->
      {{item}}
    </li>
  </ul>
</div>
new Vue({
  el: '#app',
  data: {
    inputValue: '',
    msgList:[]
  },
  methods: {
    handleSubmit: function(){
        this.msgList.push(this.inputValue);
      this.inputValue='';
    }
  }
})
# component

component的另一个写法,局部组件

<div id="app">
  <input v-model="inputValue"/>
  <button @click="handleSubmit">提交</button>
  <ul>
    <todo-item v-for="item in msgList" :content="item"></todo-item>
  </ul>
</div>
var todoItem  = {
    props:['content'],
    template:"<li>{{content}}</li>"
}
new Vue({
    components: {
    'todo-item': todoItem
  },
  el: '#app',
  data: {
    inputValue:'',
    msgList:[]
  },
  methods: {
    handleSubmit: function(){
        this.msgList.push(this.inputValue)
      this.inputValue=''
    }
  }
})

每个component都是Vue的实例,父组件传给子组件都是通过属性的来传递的。

<div id="app">
  <input v-model="inputValue"/>
  <button @click="handleSubmit">提交</button>
  <ul>
    <todo-item v-for="item in msgList" :content="item">
    </todo-item>
  </ul>
</div>
Vue.component('todo-item',{
    props:['content'],//接收父组件的值
    template:'<li>{{content}}</li>'
})
new Vue({
  el: '#app',
  data: {
    inputValue: '',
    msgList:[]
  },
  methods: {
    handleSubmit: function(){
        this.msgList.push(this.inputValue);
      this.inputValue='';
    }
  }
})

在父组件里面,通过属性的形式给子组件传递内容,如果想实现子组件的删除,必须在父组件里面,把渲染子组件的那条数据删除,当我们点击子组件的时候,必须子组件跟父组件通信,子组件要告诉父组件说,你帮我把我对应的条目删除掉。
$emit触发一个事件

Array数组的splice()方法之删除:
语法: array.splice(starti,n);
starti 指的是从哪个位置开始(不包含starti)
n指的是需要删除的个数

# 删除当前li的数据项
<div id="app">
  <input v-model="inputValue"/>
  <button @click="handleSubmit">提交</button>
  <ul>
    <todo-item 
      v-for="(item, index) of msgList" 
      :key="index"
      :index="index" 
      :content="item" 
      @delete="handleDelete"
    >
    </todo-item>
  </ul>
</div>
Vue.component('todo-item',{
    props:['content','index'],
    template:'<li @click="handleClick">{{content}}<li/>',
  methods:{
    handleClick:function(){
        //删除当前li的数据需要删除父组件的msgList的数组值,所有需要跟父组件通信,
        //用$emit触发事件,父组件接收
      this.$emit('delete',this.index)
    }
  }
})
new Vue({
  el: '#app',
  data: {
    inputValue:'',
    msgList:[]
  },
  methods:{
    handleSubmit:function(){
        this.msgList.push(this.inputValue)
      this.inputValue=''
    },
    handleDelete:function(index){
      /* 需要删除父组件的msgList内容子组件的内容就会删掉了 */
        /* alert(1) */
        this.msgList.splice(index,1)//找到下标的位置删除一项
    }
  }
})

Vue提供了7个遍历数组的方法:
pop():把数组最后一项删除。
push():往数组里增加一条。
shift():把数组的第一项删除。
unshift():往数组的第一项加内容。
splice():数组的截取

# 深入理解 Vue 组件

1、在table中,加上一个tr的component,并不是直接加上去,而且在tr上加is=“row”比如,<tr is="row"> ,row是组件名称,select,ul,ol也是一样的写法。
bugs:


image.png
<!DOCTYPE html>
<html>
<head>
    <title>4-1 使用组件的细节点</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="vm">
        <table>
            <tbody>
                <tr is="row"></tr>
                <tr is="row"></tr>
                <tr is="row"></tr>
            </tbody>
        </table>
    </div>
    <script>
        Vue.component('row',{
            template: '<tr>使用组件的细节点</tr>'
        })
        var vm=new Vue({
            el: '#vm'
        })
    </script>
</body>
</html>

2、在子组件定义data的时候,data必须是一个函数,而不是对象,因为子组件会多次被调用。

<!DOCTYPE html>
<html>
<head>
    <title>子组件调用data须是个函数</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="root">
        <table>
            <tbody>
                <tr is="row"></tr>
                <tr is="row"></tr>
                <tr is="row"></tr>
            </tbody>
        </table>
    </div>
    <script>
        Vue.component('row',{
            data: function(){
                return {
                    message: '使用组件的细节点'
                }
            },
            template: '<tr>{{message}}</tr>'
        })
        var vm=new Vue({
            el: '#root'
        })
    </script>
</body>
</html>

3、ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素; 如果用在子组件上,引用就指向组件实例。
Dom:

<!DOCTYPE html>
<html>
<head>
    <title>$refs的引用</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="root">
        <div ref="hello" @click="handleClick">hello world!</div>
        <!-- 定义一个hello的rel名称 -->
    </div>
    <script>
        var vm=new Vue({
            el: '#root',
            methods: {
                handleClick: function(){
                    alert(this.$refs.hello.innerHTML)
                    //$refs.hello是所有的引用,找到hello的引用
                    // innerText也是获取dom的值
                }
            }
        })
    </script>
</body>
</html>

组件:

<!DOCTYPE html>
<html>
<head>
    <title>$refs的引用求和</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="root">
        <counter ref="one" @change="handleChange"></counter>
        <counter ref="two" @change="handleChange"></counter>
        <div>求和:{{total}}</div>
    </div>
    <script>
        Vue.component('counter', {
            template: '<div @click="handleClick">{{number}}</div>',
            data: function(){
                return {
                    number: 0
                }
            },
            methods: {
                handleClick: function(){
                    this.number++
                    this.$emit('change')
                }
            }
        })
        var vm=new Vue({
            el: '#root',
            data: {
                total: 0
            },
            methods: {
                handleChange: function(){
                    this.total = this.$refs.one.number +this.$refs.two.number
                }
            }
        })
    </script>
</body>
</html>

单向数据流:父组件可以通过属性向子组件传递参数,传递的参数可以随意改,子组件不能改父组件传递的参数。
警告:
vue.js:597 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "content"

found in

---> <Child>
<Root>

父组件通过属性(:content="1")给子组件传值,子组件通过事件$emit()

<!DOCTYPE html>
<html>
<head>
    <title>4-2 父子组件间的数据传递</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="root">
        <counter :count="1" @change="handleChange"></counter>
        <counter :count="2" @change="handleChange"></counter>
        <div>{{total}}</div>
    </div>
    <script>
        var counter = {
            props: ['count'],
            template: '<div @click="handleClick">{{number}}</div>',
            data: function() {
                return {
                    number: this.count
                }
            },
            methods: {
                handleClick: function() {
                    // this.count++  //子组件不能改父组件传递的参数,会报错
                    //正确写法是在子组件定义一个data,然后把父组件的参数传给子组件操作
                    this.number = this.number + 2
                    this.$emit('change', 2)
                }
            }
        }
        var vm=new Vue({
            components: {counter: counter},
            el: '#root',
            data: {
                total: 3
            },
            methods: {
                handleChange: function(step) {
                    this.total += step //step是$emit触发的布长等于2
                }
            }
        })
    </script>
</body>
</html>

vue 组件开发 props 验证
https://www.cnblogs.com/exhuasted/p/7250452.html

<!DOCTYPE html>
<html>
<head>
    <title>4-2 父子组件间的数据传递</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="root">
        <child content="hello world"></child>
        <!-- 传字符串content="hello world",传数字:content="hello world",因为加上:里面是js表达式 -->
    </div>
    <script>
        Vue.component('child', {
            props: {
                //content: [ Number, String ] //只能传Number和String,可以跟数组和对象
                content: {
                    type: String,
                    required: false, 
                    //required: true必须穿content="hello world",不写就会报错
                    default: 'default value', 
                    //如果required: false,content="hello world"没有写,页面上默认会显示default value
                    validator: function(value) { //validator:效验器
                        return (value.length>5)
                        //如果hello world写成hell少于5位就会报错
                    }
                }
            },
            template: '<div>{{content}}</div>'
        })
        var vm=new Vue({
            el: '#root'
        })
    </script>
</body>
</html>

给组件绑定原生事件: @click.native

<!DOCTYPE html>
<html>
<head>
    <title>4-4 给组件绑定原生事件</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<!--    <div id="root">
        <child @change="handleChange"></child>
    </div> -->
    <div id="root">
        <child @click.native="handleChange"></child>
        <!-- 直接写native,给组件绑定原生事件 -->
    </div>
    <script>
        // Vue.component('child', {
        //  template: '<div @click="handleClick">child</div>',
        //  methods: {
        //      handleClick: function() {
        //          this.$emit('change')
        //      }
        //  }
        // })
        // var vm=new Vue({
        //  el: '#root',
        //  methods: {
        //      handleChange: function() {
        //          alert('handleChange')
        //      }
        //  }
        // })

        Vue.component('child', {
            template: '<div>child</div>'
        })
        var vm=new Vue({
            el: '#root',
            methods: {
                handleChange: function() {
                    alert('handleChange')
                }
            }
        })
    </script>
</body>
</html>

# vue slot插槽的使用方法

https://www.cnblogs.com/yesyes/p/6838671.html

<!DOCTYPE html>
<html>
<head>
    <title>4-6 在Vue中使用插槽(slot)</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="root">
        <child>
            <!-- slot="header"是具名slot -->
            <div class="header" slot="header">header</div>
            <div class="footer" slot="footer">footer</div>
        </child>
    </div>
    <script>
        Vue.component('child', {
            //如果html不写slot和js不写name的话会显示整个child里面的内容
            //default header是设置slot的默认值
            template: `<div>
                            <slot name="header">default header</slot>
                            <span>content</span>
                            <slot name="footer">default header</slot>
                       </div>`
        })
        var vm=new Vue({
            el: '#root'
        })
    </script>
</body>
</html>

slot插槽的作用域
参考:https://segmentfault.com/a/1190000012996217

<!DOCTYPE html>
<html>
<head>
    <title>4-6 在Vue中使用插槽(作用域)</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="root">
        <child>
            <template slot-scope="props">
                <ul>
                    <li>
                        {{props.item}}
                    </li>
                </ul>
            </template>
        </child>
    </div>
    <script>
        Vue.component('child', {
            data: function() {
                return {
                    list: ['张三', '李四', '王五', '赵六']
                }
            },
            template: `<div>
                            <slot 
                                v-for="item of list" 
                                :item=item
                            >
                            </slot>
                       </div>`
        })
        var vm=new Vue({
            el: '#root'
        })
    </script>
</body>
</html>
# Vue中CSS动画原理
image.png
image.png

隐藏到显示的过程: enter到enter-to
显示到隐藏的过程: leave到leave-to

<!DOCTYPE html>
<html>
<head>
    <title>5-1 Vue动画 - Vue中CSS动画原理</title>
    <script src="./js/vue.js"></script>
    <style>
        .fade-enter,
        .fade-leave {
            opacity: 0;
        }
        .fade-enter-active,
        .fade-leave-active {
            transition: opacity 3s;
        }
    </style>
</head>
<body>
    <div id="root">
        <button @click="handleClick">显示/隐藏</button>
        <transition name="fade">
            <div v-if="show">hello world!</div>
        </transition>
    </div>
    <script>
        var vm=new Vue({
            el: '#root',
            data: {
                show: false
            },
            methods: {
                handleClick: function() {
                    this.show = !this.show
                }
            }
        })
    </script>
</body>
</html>
# Vue中使用 animate.css 库

下载animate.css:https://daneden.github.io/animate.css/
使用animate.css动画库,直接在需要应用动画的标签外的transition标签里添加对应属性,比如enter-active-class=“animated swing”,leave-active-class=“animated shake”

想要用animate.css库:

1、需要自定义的class,例:enter-active-class
2、需要用animated class,例:enter-active-class="animated"
3、需要动画名字,例:enter-active-class="animated swing"

<!DOCTYPE html>
<html>
<head>
    <title>5-1 Vue动画 - Vue中CSS动画原理</title>
    <script src="./js/vue.js"></script>
    <link rel="stylesheet" type="text/css" href="./css/animate.css">
</head>
<body>
    <div id="root">
        <button @click="handleClick">显示/隐藏</button>
        <!-- enter-active-class是自定义的class -->
        <transition
            name="fade"
            enter-active-class="animated swing"
            leave-active-class="animated shake"
        >
            <div v-if="show">hello world!</div>
        </transition>
    </div>
    <script>
        var vm=new Vue({
            el: '#root',
            data: {
                show: false
            },
            methods: {
                handleClick: function() {
                    this.show = !this.show
                }
            }
        })
    </script>
</body>
</html>

在<transition></transition>标签加以下属性的意义:
1、appear 是页面刚开始刷新出现的动画
2、type="transition" 是按照transition的时间来执行,因为animate.css默认是1s
3、:duration自定义时间,可设置显示和隐藏的时间

<!DOCTYPE html>
<html>
<head>
    <title>5-3 在Vue中同时使用过渡和动画</title>
    <script src="./js/vue.js"></script>
    <link rel="stylesheet" type="text/css" href="./css/animate.css">
    <style>
        .fade-enter,
        .fade-leave-to {
            opacity: 0;
        }
        .fade-enter-active,
        .fade-leave-active {
            transition: opacity 10s;
        }
    </style>
</head>
<body>
    <div id="root">
        <button @click="handleClick">显示/隐藏</button>
        <!-- appear意思是页面刚开始刷新出现的动画
             type="transition"是按照transition的时间来执行,animate.css默认是1s
             :duration自定义时间
        -->
        <transition
            name="fade"
            :duration="{enter: 10000, leave: 5000}"
            appear
            enter-active-class="animated swing fade-enter-active"
            leave-active-class="animated shake fade-leave-active"
            appear-active-class="animated swing"
        >
            <div v-if="show">hello world!</div>
        </transition>
    </div>
    <script>
        var vm=new Vue({
            el: '#root',
            data: {
                show: true
            },
            methods: {
                handleClick: function() {
                    this.show = !this.show
                }
            }
        })
    </script>
</body>
</html>

Vue中的 Js 动画

<!DOCTYPE html>
<html>
<head>
    <title>5-4 Vue中的 Js 动画与 Velocity.js 的结合</title>
    <script src="./js/vue.js"></script>
    <link rel="stylesheet" type="text/css" href="./css/animate.css">
</head>
<body>
    <div id="root">
        <button @click="handleClick">toggle</button>
        <!-- @before-enter @enter @after-enter  @before-leave @leave @after-leave属于钩子-->
        <transition
            name="fade"
            @before-enter="handleBeforeEnter"
            @enter="handleEnter"
            @after-enter="handleAfterEnter"
        >
            <div v-if="show">hello world!</div>
        </transition>
    </div>
    <script>
        var vm=new Vue({
            el: '#root',
            data: {
                show: true
            },
            methods: {
                handleClick: function() {
                    this.show = !this.show
                },
                // el是指transition下面的el元素
                handleBeforeEnter: function(el) {
                    el.style.color = 'red'
                },
                handleEnter: function(el, done) {
                    //done是回调函数
                    setTimeout(()=> {
                        el.style.color = 'blue'
                        //done(); 结束当前的动画,如果下面没有多一个setTimeout方法就在这里加done();
                        //done:动画执行后调用回调函数,告诉vue动画已经执行
                    },2000);
                    setTimeout(()=>{
                        done();
                    },4000);
                },
                handleAfterEnter: function(el) {
                    el.style.color = 'yellow'
                }
            }
        })
    </script>
</body>
</html>

Vue和Velocity.js 的结合
Velocity.js官网:http://velocityjs.org/

<!DOCTYPE html>
<html>
<head>
    <title>5-4 Vue中的 Js 动画与 Velocity.js 的结合</title>
    <script src="./js/vue.js"></script>
    <script src="./js/velocity.min.js"></script>
    <link rel="stylesheet" type="text/css" href="./css/animate.css">
</head>
<body>
    <div id="root">
        <button @click="handleClick">toggle</button>
        <transition
            name="fade"
            @before-enter="handleBeforeEnter"
            @enter="handleEnter"
            @after-enter="handleAfterEnter"
        >
            <div v-if="show">hello world!</div>
        </transition>
    </div>
    <script>
        var vm=new Vue({
            el: '#root',
            data: {
                show: true
            },
            methods: {
                handleClick: function() {
                    this.show = !this.show
                },
                handleBeforeEnter: function(el) {
                    el.style.opacity = 0;
                },
                handleEnter: function(el, done) {
                    Velocity(el, {
                        opacity: 1
                    } ,{
                        duration: 2000,
                        complete: done
                        // 执行回调函数
                    });
                },
                handleAfterEnter: function(el) {
                    alert("动画执行结束")
                }
            }
        })
    </script>
</body>
</html>

# Vue中多个元素的过渡

<!DOCTYPE html>
<html>
<head>
    <title>5-5 Vue中多个元素的过渡</title>
    <script src="./js/vue.js"></script>
    <style>
        .fade-enter,
        .fade-leave-to {
            opacity: 0
        }
        .fade-enter-active,
        .fade-leave-acitve {
            transition: opacity 1s;
        }
    </style>
</head>
<body>
    <div id="root">
        <button @click="handleClick">toggle</button>
        <!-- mode="in-out"先显示在隐藏,mode="out-in"先隐藏在显示 -->
        <transition name="fade" mode="in-out">
            <div v-if="show" key="hello">hello world!</div>
            <div v-else key="bye">bye world!</div>
        </transition>
    </div>
    <script>
        var vm = new Vue({
            el: '#root',
            data: {
                show: true
            },
            methods: {
                handleClick: function() {
                    this.show = !this.show
                }
            }
        })
    </script>
</body>
</html>

# Vue中组件的过渡

<!DOCTYPE html>
<html>
<head>
    <title>5-5 Vue中组件的过渡</title>
    <script src="./js/vue.js"></script>
    <style>
        .fade-enter,
        .fade-leave-to {
            opacity: 0
        }
        .fade-enter-active,
        .fade-leave-acitve {
            transition: opacity 1s;
        }
    </style>
</head>
<body>
    <div id="root">
        <button @click="handleClick">toggle</button>
        <transition name="fade">
            <child-one v-if="show"></child-one>
            <child-two v-else></child-two>
        </transition>
    </div>
    <script>
        Vue.component('child-one', {
            template: '<div>child-one</div>'
        })
        Vue.component('child-two', {
            template: '<div>child-two</div>'
        })
        var vm = new Vue({
            el: '#root',
            data: {
                show: true
            },
            methods: {
                handleClick: function() {
                    this.show = !this.show
                }
            }
        })
    </script>
</body>
</html>

# Vue中动态组件的过渡

<!DOCTYPE html>
<html>
<head>
    <title>5-5 Vue中动态组件的过渡</title>
    <script src="./js/vue.js"></script>
    <style>
        .fade-enter,
        .fade-leave-to {
            opacity: 0
        }
        .fade-enter-active,
        .fade-leave-acitve {
            transition: opacity 1s;
        }
    </style>
</head>
<body>
    <div id="root">
        <button @click="handleClick">toggle</button>
        <transition name="fade">
            <component :is="type"></component>
        </transition>
    </div>
    <script>
        Vue.component('child-one', {
            template: '<div>child-one</div>'
        })
        Vue.component('child-two', {
            template: '<div>child-two</div>'
        })
        var vm = new Vue({
            el: '#root',
            data: {
                type: 'child-one'
            },
            methods: {
                handleClick: function() {
                    this.type = this.type == 'child-one' ? 'child-two' : 'child-one'
                }
            }
        })
    </script>
</body>
</html>

# Vue中的列表过渡

如果是列表过度需要用<transition-group></transition-group>如果用<transition></transition>只会显示第一个类别的动画

<!DOCTYPE html>
<html>
<head>
    <title>5-6 Vue中的列表过渡</title>
    <script src="./js/vue.js"></script>
    <style>
        .fade-enter,
        .fade-leave-to {
            opacity: 0;
        }
        .fade-enter-active,
        .fade-leave-active {
            transition: opacity 3s;
        }
    </style>
</head>
<body>
    <div id="root">
        <button @click="handleClick">Add a Message</button>
        <transition-group name="fade">
            <div 
                v-for="(item ,index) of list"
                :key="item.id"
            >
                第{{item.id}}个:{{item.title}}
            </div>
        </transition-group>
    </div>
    <script>
        var vm = new Vue({
            el: '#root',
            data: {
                count: 0,
                list: []
            },
            methods: {
                handleClick: function() {
                    this.list.push({
                        id: this.count++,
                        title: 'hello world!'
                    })
                }
            }
        })
    </script>
</body>
</html>
上一篇下一篇

猜你喜欢

热点阅读