zoukankan      html  css  js  c++  java
  • VUE 入门基础(9)

    十一,深入响应式原理 

      声明响应式属性
        由于Vue不允许动态添加根级响应式属性,所以你必须在初始化实例钱声明根级响应式属性,哪怕只有一个空值。   

         var vm = new Vue({ 
              data:{ 
                // 声明 message 为一个空字符串
                message: ' '
              },
            template: '<div>{{ message }}</div>'
          })
          // vm.message = 'Hello!'
          vm.message = 'Hello!'

          如果你在data 选项中未声明 message,Vue 将警告你渲染函数早试图访问的属性不存在。

         异步更新队列

         <div id="example">{{message}}</div>
          var vm = new Vue({ 
            el:'#example',
            data: { 
              message: '123'
            }
          })
         vm.message = 'new message' // 更改数据
         vm.$el.textContent === 'new message' // false
         Vue.nextTick(function() { 
            vm.$el.textContent === 'new message' //true
          })

        在组件内使用 vm.$nextTick() 实例方法特别方便,应为它不需要全局Vue ,并且回调函数中 this
        将自动绑定到当前Vue

        Vue.component('example', { 
          template: '<span> {{ message }}</span>',
          data: function() { 
            return { 
                message: 'not updated'
              } 
          },
          methods: { 
          updateMessage: function() { 
          this.message = 'updated'
          console.log(this.$el.textContent) // => 'not updated'
          this.$nextTick(function () { 
              console.log(this.$el.textContent) // => 'updated'
          })
          }
           } 
        })

    十二,过度效果
       在插入,更新或者移除DOM 时,提供多种不同方式的应用过度效果。
          在css过度和动画中自动应用class
            可以配合使用第三方css 动画库,如Animate.css
            在过度钩子函数中使用JavaScript 直接操作DOM
            可以配合使用第三方JavaScript 动画库,如velocity.js

      

       单元素/组件的过度。
          vue提供l了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加entering/leaving过度
            条件渲染使用(使用 v-if)
            条件展示(使用 v-show)
       动态组件
         组件跟节点
            例子:

              <div id="demo">
                  <button v-on:click="show = !show">
                    Toggle
                  </button>
                  <transition name=fade>
                     <p v-if="show">hello</p>
                  </transition>
              </div>
              new Vue({ 
                  el:'#demo',
                  data: { 
                    show: true
                  }
              })
              .fade-enter-active, .fade-leave-active { 
                  transition:opacity .5s
               }
              .fade-enter, .fade-leave { 
                  opacity: 0
              }

        元素封装成过渡组件之后,在遇到插入或删除时,Vue 将
          1.自动嗅探目标元素是否有 CSS 过渡或动画,并在合适时添加/删除 CSS 类名。
          2.如果过渡组件设置了过渡的 JavaScript 钩子函数,会在相应的阶段调用钩子函数
          3.如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作(插入/删除)在下一帧中立即执行

       #过度的-css-类名
          会有4个css 类名在enter/leave 的过度中切换
              1. v-enter: 定义进入过度的开始状态,在元素被插入的时生效,在下一个帧移除。
              2.v-enter-actvie 定义进入过度的结束状态,在元素被插入时生效,在transition
                 /animation 完成之后移除。
              3.v-leave: 定义离开过度的开始状态,在离开过度被触发时生效,在下一个帧移除。
              4.v-leave-active: 定义离开过度的结束状态,在离开过度被处罚时生效,在transition/animation 完成之后移除。

         css 过渡
          常用的过度都是使用css 过渡
            例子

             <div id="example-1">
                <button @click="show= !show">
                  Toggle render
                </button>
                <transition name="slide-fade">
                  <p v-if="show">hello</p>
                </transition>
              </div>
                new Vue({ 
                  el: '#example-1,
                  data: { 
                      show:true
                    }
                })

            // 可以设置不同的进入和离开动画
            //设置持续时间和动画函数

             .slide-fade-enter-active{ 
                  transition: all .3s ease;
              }
              .slide-fade-leave-active{ 
                  transition: all .8s cubic-bezier(1.0,0.5,0.8,1.0);
              }
              .slide-fade-enter, .slide-fade-leave-active{ 
                  transition: translateX(10px);
                  opacity: 0;
              }

       css 动画

          css 动画用法同 css 过渡,区别是在动画中v-enter 类名节点插入DOM后
          会不会立即删除,而是在animationend 事件触发时删除。
           实例:

             <div id="example-2">
                  <button @click="show = !show">Toggle show</button>
                  <transition name="bounce">
                    <p v-if="show">Look at me!</p>
                  </transition>
              </div>
               new Vue({ 
                   el: '#example-2',
                   data: { 
                        show: true
                  }
              })
              .bounce-enter-active { 
                animation: bounce .5s;
              }
              .bounce-leave-active { 
                animation: bounce .5s;
              }
              @keyframes bounce-in { 
                  0%{ 
                    transeform: sceale(0);
                  }
                  50%{ 
                    transeform: sceale(1.5);
                  }
                  100%{ 
                    transeform: sceale(1);
                  }
                }
              @keyframes bounce-out { 
                  0%{ 
                    transeform: sceale(1);
                  }
                  50%{ 
                    transeform: sceale(1.5);
                }
                100%{ 
                    transeform: sceale(0);
                }
              }

        自定义过渡名
            我们可以通过以下特性来自定义过渡名:
              enter-class
              enter-active-class
              leave-class
              leace-active-class
            他们的优先级别高于普通的类名,对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用

              实例

              <div id="example-3">
                  <button @click="show = !show">
                    Toggle render
                  </button>
                  <transition
                      name="custom-classes-transititon"
                      enter-active-class="aniamated tada"
                      leave-active-class="animated bounceOutRight"
                    >
                    <p v-if="show">hello</p>
                  </transition>
               </div>    
                new Vue({ 
                    el:'#example-3',
                    data: { 
                        show: true
                    }
                })  

        同时使用Transitions 和Animations
          Vue 为了知道过渡的完成,必须设置相应的事件监听器

        JavaScript 钩子
          可以在属性中声明 JavaScript 钩子

            <transition
                v-on:before-enter="beforeEnter"
                v-on:enter="enter"
                v-on:after-enter="afterEnter"
                v-on:enter-cancelled="enterCancelled"
    
                v-on:before-leave="beforeLeave"
                v-on:leave="leave"
                v-on:after-leave="afterLeave"
                v-on:leave-cancelled="leaveCancelled"
            >
          </transition>    
           methods: { 
                // 进入中
    
              beforeEnter: function (el) { 
                //...
              },
              // 此回调函数是可选项的设置
              // 与 css 结合时使用
              enter: function (el, done) { 
                  done()
                },
              afterEnter: function ( el) { 
                },
              enterCancelled: function (el) { 
              },
    
              // 离开时
    
            beforeLeave: function(el) { 
              //
          },
          // 此函数是可选项的设置
          // 与 css 结合时使用
    
          leave: function (el, done) { 
              //...
            done()
             },
          afterLeave: function (el) { 
            //...
          },
          // leaveCancelled 只用于v-show 中
          leaveCancelled: function(el) { 
          // ...
          }
    
        }

        这些钩子函数可以结合 CSS transitions/animations 使用,也可以单独使用。

       初始渲染的过度
          可以通过 appear 特性设置节点的在初始渲染的过度。

            <transition appear></transition>
              这里默认的和进入和离开过度一样,同样也可以自定义css类名
            <tranaition appear
              appear-class="custom-appear-class"
              appear-active-class="custom-appear-active-class"
            >
    
            </tranaition>

            自定义 JavaScript 钩子:

          <transition
              appear
                v-on:before-appear="customBeforAppearHook"
                v-on:appear="customAppearHook"
                v-on:after-appear="customAfterAppearHook"
            >
    
          </transition>

        多个元素的过度
          多个组件的过度很简单-我们不需要使用key 特性。我们只需要使用动态组件。

          <transition name="component-fade" mode="out-in">
            <component v-bind:is="view"></component>
          </transition>
          new Vue({ 
            el: '#transition-components-demo',
            data: { 
              view: 'v-a'
            },
            components: { 
              'v-a': { 
                  template: '<div>Component A</div>'
              },
              'v-b': { 
                  template: '<div>Component B</div>'
              }
              }
            })
          .component-fade-enter-active, .component-fade-leave-active { 
              transition: opacity .3s ease;
            }
          .component-fade-enter, .component-fade-leave-active { 
              opacity: 0;
          }

        列表过度
            目前为止,关于过度我们已经完成了:
             单个节点
             多个节点,其中每次只渲染一个
             有一个完整的列表 v-for 我们如何做到同时渲染,我们将使用
            <transition -group> 组件。
              不同于 <transition> 他会以一个真实元素渲染。默认为<span>也可以通过 tag 属性更换为其他渲染元素。
            他的元素必须具有为一个的key 属性

       列表的进入和离开
          进入和离开的过度使用之前一样的CSS 类名

         <div id="list-demo" class="demo">
              <button v-on:click="add">Add</button>
              <button v-on:click="remove">Remove</button>
              <transition-group name="list" tag="p">
              <span v-for="item in items" v-bind:key="item"
                class="list-item"
                >{{ item }}
              </span>
            </transition-group>
            </div>
          new Vue({ 
              el: '#list-demo',
              data: { 
                  items: [1,2,3,4,5,6,7,8,9],
                  nextNum: 10
              },
              methods: { 
                randomIndex: function() { 
                return Math.floor(Math.random() * this.items.length)
              },
              add: function () { 
              this.items.splice(this.radomIndex(), 0,this.nextNum++)
              },
              remove: function () { 
                  this.items.splice(this.randomIndex(), 1)
              }
            }
          })
        .list-item { 
            display: inline-balock;
            margin-right:10px;
        }
        .list-enter-active, .list-leave-active { 
            transition: all ls;
        }
        .list-enter, .list-leave-active { 
            opacity: 0;
            transform: translateY(30px);
          }

        列表的位移过度
          <transition-group> 组件还有一个特殊之处,不仅可以进入和离开动画,还可以改变定位,
          要使用这个新功能 v-move 特性,它会在元素的改变定位的过程中应用。
          可以通过 name 属性来定义前缀,也可以通过move-class 属性手动设置。
          v-move 对于设置过度的过度的切换时机和过度曲线非常有用,

           <div id="flip-list-demo" class="demo">
                <button v-on:click="shuffle">Shuffle</button>
                <transition-group name="flip-list" tage="ul">
                  <li v-for="item in items" v-bind:key="item">
                    {{item}}
                  </li>
                </transition-group>
            </div>
            new Vue({ 
                el: '#flip-list-demo',
                data: { 
                    items: [1,2,3,4,5,6,7,8,9]
                },
                methods: { 
                  shuffle: function () { 
                    this.items = _.shuffle(this.items)
                    }
                  }
             })
            .flip-list-move { 
                transition: transform 1s;
            }

        列表的渐进过度
          通过data 属性 与 JavaScript 通信,可以实现列表的渐进过度

         <div id="staggered-list-demo">
              <input v-mode="query">
              <transition-group
                name="staggered-fade"
                tage="ul"
                v-bind:css= " false"
                v-on:before-enter="beforeEnter"
                v-on:enter = "enter"
                v-on:leave="l            >
    
                  <li 
                    v-for="{item, index} in computedList"
                    v-bind:key = "item.msg"
                    v-bind:data-index="index"
                  >{{ item.msg}}</li>
            </transition-group>
          </div>
          new Vue({ 
              el: '#staggered-list-demo',
              data: { 
                    query:' ',
                    list: [ 
                        {msg: 'Bruce Lee'},
                        {msg: 'Jackie Chan'},
                        {msg: 'Chunck Norris'},
                        {msg: 'Jet Li'},
                        {msg: 'Kung Fury'}    ]
                },
              computed: { 
                  computedList: function () { 
                      var vm = this
                      return this.list.filter(function (item) { 
                        return item.msg.toLowerCase().indexOf
                        (vm.query.toLowerCase()) !=== -1
                      })
                    }
                  },
                methods: { 
                    beforeEnter: function (el) { 
                        el.style.opacity = 0
                        el.style.height = 0
                    },
                    enter: function (el,done) { 
                      var delay= el.dataset.index * 150
                        setTimeout(function () { 
                            Velocity( 
                                el,
                            {opacity: 1, height: '1.6em'},
                            {complete: done}
                        )
                      }, delay)
                    },
                    leave: function (el, done) { 
                        var delay = el.dataset.index * 150
                        setTimeout(function () { 
                            Velocity( 
                                  el,
                              {opacity:0, height:0},
                              {complete: done}
    
                            )
                        },delay)
                       }
                      }
                    })   

        可复用的过度
          过度可以通过 Vue 的组件系统实现复用,要创建一个可复用的过度组件,你需要做的就是
          将 <transition> 或者 <transition-group> 作为一个跟=根组件,放置在其中就可以了
          使用 template 的简单例子

            Vue.component('my-special-transition', { 
                      template:` 
                          <transition
                            name="very-special-transition"
                            mode= "out-in"
                            v-on:before-enter="beforeEnter"
                            v-on:after-enter="afterEnter"
                            >
                            <slot></slot>
                          </transition>
                          \`,
                    methods: { 
                        beforeEnter: function(el) { 
                            // ...
                        },
                        afterEnter: function (el) { 
                           // ...
                        }
                    }
            })

          函数组件更适合完成这个任务:

        动态过渡
          在Vue 中及时是过度也是数据驱动的,动态过度基本是通过name 特性来绑定动态值
            <transition v-bind:name="transitionName"></transition>
            所有的过渡特性都是动态绑定。它不仅是简单的特性,通过事件的钩子函数方法,可以在获取到相应上下文数据

           <div id="dynmic-fade-">
                Fade In: <input type="range" v-model="fadeInDuration"
                       min="0" v-bind:max="maxFadeFuration">
                Fade Out: <input type="range" v-model="fadeOtDuration"
                    min="0" v-bind:max="maxFadeFuration">
                <transition
                    v-bind:css="false"
                    v-on:before-enter="beforeEnter"
                    v-on:enter="enter"
                    v-on:leave="leave"
                  >
                  <p v-if="show">hello</p>
              </transition>
              <button v-on:click="stop = true">Stop it!</button>
            </div>
            new Vue({
                el: '#dynamic-fade-demo',
                data: {
                    show: true,
                    fadeInDuration: 1000,
                    fadeOutDuration: 1000,
                    maxFadeDuration: 1500,
                    stop: false
                },
                mounted: function () {
                    this.show = false
                },
                methods: {
                  beforeEnter: function (el) {
                      el.style.opacity = 0
                },
              enter: function (el, done) {
                    var vm = this
                      Velocity(el,
                          { opacity: 1 },
                          {
                              duration: this.fadeInDuration,
                              complete: function () {
                                  done()
                                  if (!vm.stop) vm.show = false
                              }
                          }
                        )
                    },
                  leave: function (el, done) {
                      var vm = this
                        Velocity(el,
                          { opacity: 0 },
                          {
                            duration: this.fadeOutDuration,
                            complete: function () {
                                done()
                                vm.show = true
                              }
                            }
                           )
                        }
                      }
                  })
  • 相关阅读:
    修改spring源码重写classloader实现项目加密
    Java验证工具类
    jsp相关基础知识
    HTTP协议详细分析
    Java获取Linux和Window系统CPU、内存和磁盘总使用率的情况
    关于Genymotion下载比较慢的解决办法
    Android Studio:Failed to resolve ***
    ActionBar设置自定义setCustomView()留有空白的问题
    Service是什么?Service又不是什么?
    Socket--Android王国的外交发言人
  • 原文地址:https://www.cnblogs.com/nmxs/p/6230397.html
Copyright © 2011-2022 走看看