Vue常用特性

1.0 表单相关

1.1 表单基本操作

  • 获取文本框的值(略)

  • 获取单选框中的值

    • 通过v-model

    • 
         
         
      
         
         
      
      

      获取复选框中的值

    • 通过v-model

    • 和获取单选框中的值一样

    • 复选框 checkbox 这种的组合时 data 中的 hobby 我们要定义成数组 否则无法实现多选

    • 
      
      
      爱好:

      获取下拉框和文本框中的值

    • 通过v-model

    • 职业:

1.2 表单修饰符

  • .number 转换为数值

    • 注意点:

    • 当开始输入非数字的字符串时,因为Vue无法将字符串转换成数值

    • 所以属性值将实时更新成相同的字符串。即使后面输入数字,也将被视作字符串。

  • .trim 自动过滤用户输入的首尾空白字符

    • 只能去掉首尾的 不能去除中间的空格

  • .lazy 将input事件切换成change事件

    • .lazy 修饰符延迟了同步更新属性值的时机。即将原本绑定在 input 事件的同步逻辑转变为绑定在 change 事件上

  • 在失去焦点 或者 按下回车键时才更新

  • 
    
    
    
    
    
    
    

2.0 常用特性

2.1 自定义指令

  • 内置指令不能满足我们特殊的需求

  • Vue允许我们自定义指令

Vue.directive 注册全局指令

自定义指令创建语法

Vue.directive('focus',{
              inserted:function(el){
     //获取元素焦点
     el.focus();
		}             
   })

自定义指令用法:

 




Vue.directive 注册全局指令 ---带参数

    

 
自定义指令局部指令
  • 局部指令,需要定义在 directives 的选项 用法和全局用法一样

  • 局部指令只能在当前组件里面使用

  • 当全局指令和局部指令同名时以局部指令为准

  • 
     
     

    2.2 使用method监听数据的变化

  • /*使用keyup事件监听数据的变化*/
    
    
    
    
    
    Document
    
    
    
    
    
    + =
  • 模板中放入太多的逻辑会让模板过重且难以维护 使用计算属性可以让模板更加的简洁

2.3 计算属性 computed

  • 计算属性出现的目的是解决模板中放入过多的逻辑会让模板过重且难以维护的问题.

    计算属性是根据data中已有的属性,计算得到一个新的属性.

  • computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化

  •  /*
          计算属性与方法的区别:计算属性是基于依赖进行缓存的,而方法不缓存
        */
    
    
    
    
    
    
    Document
    
    
    
    
    
    + =

    2.4 侦听器 watch

  • 使用watch来响应数据的变化

  • watch 中的属性 一定是data 中 已经存在的数据

  • 
    
    
      
      
      Document
      
      
    
    
    
      
    + =

    当然,侦听器有自己的应用场景,它的应用场景就是在执行异步请求或者进行开销比较大的操作的时候,会使用侦听器。

    下面我们来看一个异步操作的情况。就是当用户在一个文本框中输入了用户名以后,要将输入的用户名发送到服务端,来检查该用户名是否已经被占用。

  •  
    
    
      
      Document
    
    
      
    用户名: {{tip}}

    2.5 watch,computed,methods之间的对比

    1.methods方法表示一个具体的操作,主要书写业务逻辑。

    2.computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算,主要当做属性来使用。

    3.watch是一个对象,键是需要观察的表达式,值是对应的回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,可以看做是computed和methods的结合体。

    2.6 过滤器

  • Vue.js允许自定义过滤器,可被用于一些常见的文本格式化。

  • 过滤器可以用在两个地方:双花括号插值和v-bind表达式。

  • 过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示

  • 支持级联操作

  • 全局注册时是filter,没有s的。而局部过滤器是filters,是有s的

  • 
    
    
    
    
    Document
    
    
    
    
    

    {{msg | format1("帅气") | format2 }}

    2.7 过滤时间格式

  • 
    
    
    
    
    Document
    
    
    
    
    

    {{date | format('yyyy-MM-dd hh:mm:ss')}}

3.0 生命周期

3.1 概述

  • 事物从出生到死亡的过程

  • 每个Vue实例在被创建时都要经过一系列的初始化过程,例如:需要设置数据的监听,编译模板,将实例挂载到DOM上,并且在数据变化时更新DOM等,这些过程统称为Vue实例的生命周期。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

  • 常用的钩子函数

  • beforeCreate 在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了
    created 在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来
    beforeMount 在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已
    mounted el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上 在这个钩子函数里面我们可以使用一些第三方的插件
    beforeUpdate 数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的
    updated 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的
    beforeDestroy 实例销毁之前调用
    destroyed 实例销毁后调用
  • 其实Vue实例的生命周期,主要分为三个阶段,分别为

  • 挂载(初始化相关属性,例如watch属性,method属性)

    1. beforeCreate 啥也干不了

    2. created 创建 初始化数据 method

    3. beforeMount 虚拟dom

    4. mounted 挂载 经历到这个阶段,数据才可以显示在页面上

  • 更新(元素或组件的变更操作)

    1. beforeUpdate

    2. updated 更新 页面变化立刻,就会被同步到

  • 销毁(销毁相关属性)

    1. beforeDestroy 销毁前

    2. destroyed 销毁。 挂了。彻底废了

  • 前四个阶段  beforeCreate , created, beforeMount , Mounted. 这四个阶段叫做组件(实例)的创建阶段

    第五个和第六个 beforeUpdate Updated  组件的运行阶段

    第七个和第八个 beforeDestroy destroyed 组件的销毁阶段

3.2 案例演示

  • 一个案例让你了解什么是生命周期。

  • 
    
    
      
      Document
    
    
      
    {{msg}}

    3.3 代码分析

    beforeCreate: Vue实例初始化之后,以及事件初始化,以及组件的父子关系确定后执行该钩子函数,一般在开发中很少使用。

    created: 在调用该方法之前,初始化会被使用到的状态,状态包括props,methods,data,computed,watch.

    而且会实现对data中属性的监听,也就是在created的时候数据已经和data属性进行了绑定。(放在data中的属性当值发生改变的时候,视图也会改变)。同时也会对传递到组件中的数据进行校验。

    所以在执行created的时候,所有的状态都初始化完成,我们也完全可以在该阶段发送异步的ajax请求,获取数据。

    但是,在created方法中,是无法获取到对应的的$el选项,也就是无法获取Dom. 所以说上题中选项c的说法是正确的

    created方法执行完毕后,下面会判断对象中有没有el选项。如果有,继续执行下面的流程,也就是判断是否有template选项,如果没有el选项,则停止整个生命周期的流程,直到执行了vm.$mount(el)后,才会继续向下执行生命周期的流程。

    我们将上方代码el选项去掉了,运行上面的代码后,我们发现执行完created方法后,整个流程就停止了。

    现在,我们不添加el选项,但是手动执行vm.$mount(el),也能够使暂停的生命周期进行下去。

    我们继续向下看,就是判断在对象中是否有template选项。

    第一:如果Vue实例对象中有template参数选项,则将其作为模板编译成render函数,来完成渲染。

    第二:如果没有template参数选项,则将外部的HTML作为模板编译(template),也就是说,template参数选项的优先级要比外部的HTML

    第三:如果第一条,第二条件都不具备,则报错。

    接下来会触发beforeMount这个钩子函数:

    在执行该钩子函数的时候,虚拟DOM已经创建完成,马上就要渲染了,在这里可以更改data中的数据,不会触发updated, 其实在created中也是可以更改数据,但是不会触发updated函数。

    下面再执行mounted的时候,可以看到真实的数据。同时整个组件内容已经挂载到页面中了,数据以及真实DOM都已经处理好了,可以在这里操作真实DOM了,也就是在mounted的时候,页面已经被渲染完毕了,在这个钩子函数中,我们可以去发送ajax请求。

    当整个组件挂载完成后,有可能会进行数据的修改,当Vue发现data中的数据发生了变化,会触发对应组件的重新渲染,先后调用了beforeUpdateupdated钩子函数。

    updated之前beoreUpdate之后有一个非常重要的操作就是虚拟DOM会重新构建,也就是新构建的虚拟DOM与上一次的虚拟DOM树利用diff算法进行对比之后重新渲染。

    而到了updated这个方法,就表示数据已经更新完成,dom也重新render完成。

    下面如果我们调用了vm.$destroy方法后,就会销毁所有的资源。

    首先会执行beforeDestroy 这个钩子函数,这个钩子函数在实例销毁前调用,在这一步,实例仍然可用。

    在该方法中,可以做一些清理的工作,例如:清除定时器等。

    但是执行到destroyed钩子函数的时候,Vue实例已经被销毁,所有的事件监听器会被移除,所有的子实例也会被销毁。

    最后做一个简单的总结:

  • beforeCreate( )// 该钩子函数执行时,组件实例还未创建.
    created()//组件初始化完毕,各种数据可以使用,可以使用ajax发送异步请求获取数据
    beforeMounted()// 未执行渲染,更新,虚拟DOM完成,真实DOM未创建
    mounted()// 初始化阶段结束,真实DOM已经创建,可以发送异步请求获取数据,也可以访问dom元素
    beforeUpdate()//更新前,可用于获取更新前各种状态数据
    updated()//更新后执行该钩子函数,所有的状态数据是最新的。
    beforeDestroy() // 销毁前执行,可以用于一些定时器的清除。
    destroyed()//组件已经销毁,事件监听器被移除,所有的子实例也会被销毁。

4.0 响应式与数组变异方法

4.1 变异方法

  • 力有不逮的对象

众所周知,在 Vue 中,直接修改对象属性的值无法触发响应式。当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变,上代码:


    

{{key}}----{{val}}

 

这是什么原因?

原因在于: Vue 的响应式系统是基于Object.defineProperty这个方法的,该方法可以监听对象中某个元素的获取或修改,经过了该方法处理的数据,我们称其为响应式数据。但是,该方法有一个很大的缺点,新增属性或者删除属性不会触发监听

原因在于,在 Vue 初始化的时候, Vue 内部会对 data 方法的返回值进行深度响应式处理,使其变为响应式数据,所以, vm.obj.a 是响应式的。但是,之后设置的 vm.obj.b 并没有经过 Vue 初始化时响应式的洗礼,所以,理所应当的不是响应式。

  • 更凄惨的数组

  • 
        

    {{item }}

    也就是说,数组连自身元素的修改也无法监听,原因在于, Vuedata 方法返回的对象中的元素进行响应式处理时,如果元素是数组时,仅仅对数组本身进行响应式化,而不对数组内部元素进行响应式化。

    这也就导致如官方文档所写的后果,无法直接修改数组内部元素来触发响应式。那么,有没有破解方法呢?

  • 当然有,官方规定了 7 个数组方法,通过这 7 个数组方法,可以很开心地触发数组的响应式,这 7 个数组方法分别是:

  • push() 往数组最后面添加一个元素,成功返回当前数组的长度
    pop() 删除数组的最后一个元素,成功返回删除元素的值
    shift() 删除数组的第一个元素,成功返回删除元素的值
    unshift() 往数组最前面添加一个元素,成功返回当前数组的长度
    splice() 有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除 后想要在原位置替换的值
    sort() sort() 使数组按照字符编码默认从小到大排序,成功返回排序后的数组
    reverse() reverse() 将数组倒序,成功返回倒序后的数组




  
  
  Document
  
  



  
  • {{item}}
  •  

    可以发现,这 7 个数组方法貌似就是原生的那些数组方法,为什么这 7 个数组方法可以触发应式,触发视图更新呢?

    你是不是心里想着:数组方法了不起呀,数组方法就可以为所欲为啊?

    Sorry,这 7 个数组方法是真的可以为所欲为的。

    因为,它们是变异后的数组方法。什么是变异数组方法?变异数组方法即保持数组方法原有功能不变的前提下对其进行功能拓展,在 Vue 中这个所谓的功能拓展就是添加响应式功能。

    4.2 替换数组

    • 不会改变原始数组,但总是返回一个新数组

    filter filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
    concat concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组
    slice slice() 方法可从已有的数组中返回选定的元素。该方法并不会修改数组,而是返回一个子数组
    
    
    
    
      
      
      Document
      
      
    
    
    
      
  • {{item}}
  • 4.3 动态数组响应式数据(Object.defineProperty()

    • 了解完变异方法后,我们回到最初的问题,vm.obj.b = 2; 或者使用索引或length修改数组就真的不能变成响应式的吗?

    • 在解决这个问题之前先了解一下 Vue 的响应式原理:

    关于响应式,提出3个问题?

     第一个问题: 给属性重新赋值成对象,是否是响应式的?
      第二个问题: 给`Vue`实例新增一个成员是否是响应式的?
      第三个问题: 通过索引和length修改数组是否是响应式的?

    • 看一下官方的解决方法

    • 深入响应式原理 — Vue.js

    当你把一个 JS 对象传给 Vue 实例的 data 属性时,Vue 将遍历此对象的所有属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本的浏览器。 

    为什么要使用 Vue.set

    受限于现代浏览器,Vue 检测不到对象的添加和删除;因为 Vue 在初始化实例时对 data 属性执行 getter/setter 转化操作,所以对象必须在 data 中才能让其响应式。

    Vue 不允许在已经创建的实例上动态添加新的根级响应式属性,但是有时我们项目中一开始的对象的属性不确定,你可能需要为已有对象赋予多个新属性,不过可以使用 Vue.set 或者vm.$set 方法将响应式属性添加到嵌套的对象上。代码演示如下

    - Vue.set(a,b,c)   让触发视图重新更新一遍,数据动态起来
    - a是要更改的数据 、  b是数据的第几项、   c是更改后的数据

    
    
    
    
    
    Document
    
    
    
    
    

    {{ obj.message }}


    {{ obj.newProperty }}


    • {{ item }}

     总结:

    vue中使用索引改变数组是不响应的,解决方式是使用Vue.set(a,b,c)  

    vue中使用length改变数组的长度也是不响应的,解决方法是使用this.arr.splice(0)---利用的是数组变异方法。

    vue中如果给一个对象动态的添加了新属性,我们也需要使用Vue.set(a,b,c)   让 触发视图重新更新一遍

    你可能感兴趣的:(vue.js,javascript,前端)