Vue知识点

作者: db366da20578 | 来源:发表于2018-04-15 12:07 被阅读0次

    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>
    

    相关文章

      网友评论

        本文标题:Vue知识点

        本文链接:https://www.haomeiwen.com/subject/eualkftx.html