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
						                                    }
						                                }
						                             )
						                        }
						                    }
						              })
 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏黒之染开发日记

css3动画在手机端的流畅度比较

我发现即使都是用css3的transition做动画,有的属性在动画播放时却会不流畅,出现定格动画的效果,这里做个比较,方便我以后做动画。

42720
来自专栏练小习的专栏

封装图片滑动效果

by bopooo 在腾讯QQ软件下载的页面有一个图片滑动的效果,觉得还不错 就自己封装了一个 技术方面在 动作缓冲上 遇到一些问题 不过都解决了 不过还...

270100
来自专栏程序员互动联盟

【专业技术】CSS作用及用法

层叠样式表(Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的...

37470
来自专栏web

慕课网javascript 进阶篇 第九章 编程练习

13640
来自专栏吴裕超

vue .sync修饰符的使用

在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显...

18420
来自专栏木子昭的博客

<自动化办公> Python 操控 Word

虽然Word不好用, 但还必须得用它, python-docx是专门用于编辑Word文档的一个工具库, 它有两大用途, 自动化生成word文档 and 自动化...

3.1K80
来自专栏向治洪

Markdown对应Yelee主题语法

概述 这里说的是Yelee主题的语法和原生语法是有些区别的;更多的基础语法可以到Cmd Markdown上面去查看;但是我觉得都会各有不同吧 注意这里说的不是真...

20460
来自专栏落花落雨不落叶

【被玩坏的博客园】之canvas装饰博客园侧边栏

17220
来自专栏落花落雨不落叶

【被玩坏的博客园】之canvas装饰博客园侧边栏

51170
来自专栏好好学习吧

js实现html表格<td>标签中带换行的文本显示出换行效果

如下内容中我写了几行,但是表格中并未按行显示,换行符反而变成了空格,于是想自己转换下

1.4K30

扫码关注云+社区

领取腾讯云代金券