VUE 基础

注意:文中的 vm 为 var vm = new Vue() ,可以在内外部通过vm引用,也可以在内部通过this指向

内在

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter

  1. Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 仅支持IE9及以上版本浏览器的原因。
  2. 因此初始化实例时不在data中的属性不会自动转换为响应式。且Vue 不允许动态添加根级响应式属性。在初始化实例前应声明所有根级响应式属性,即使为空。

Vue 在更新 DOM 时是异步执行的。在每一个事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。为了在数据更新后等待dom也更新完成,可以使用Vue.nextTick(callback)vm.$nextTick()

指令 (Directives)

通常带有 v- 前缀,通过:传入参数 , 通过.添加修饰符 , 其值(如有)应为单个 JavaScript 表达式。(且可访问到Date,Math等特定的全局变量)指令的职责是,将表达式值的变化更新作用于 DOM。不同于angular.js,在vue中指令和组件是完全不同的两个概念。

  • v-text 更新元素的 textContent。
  • v-once 仅进行首次插值
  • v-show
  • v-if / v-else-if / v-else
  • v-for
  • v-model
  • v-html 请勿对用户提供的内容使用该指令,易导致xss攻击
  • v-slot 提供具名插槽或需要接收 prop 的插槽。
  • v-bind 操作dom属性,可缩写为:。对于布尔型特性 ,由于只要出现就意味着值为 true,因此若为nullundefinedfalse,vue直接不渲染该属性。
  • v-on 监听dom事件,可缩写为@
    • 从 2.6.0 开始,可以用方括号传入字符串null作为指令参数。字符串不能有空格和引号,且会自动转为小写。null可用于移除绑定。
 ... 
 ... 
  • v-pre 对其中的{{...}}不进行编译
  • v-cloak 这个属性会保持在元素上直到关联实例结束编译。
[v-cloak] {
  display: none;
}
...
{{ message }}

计算属性 和 侦听器

定义计算属性 和 侦听器时,均不应使用箭头函数

计算属性

计算属性应处于computed中,每当计算属性的相关响应式依赖发生改变,则重新求值。
直接在模板语法中执行函数也可以达成该效果,但需注意的是,函数每当页面发生渲染时,都会重新执行,因此性能开销会大于计算属性。好处在于非响应式依赖变更时,函数值也会随着页面渲染而更新。

页面第一次加载时,两个值相同。
str发生更新,两值同步更新。
trigger1更新,此时页面重新渲染,{{computedFun()}}更新,而{{computedData}}不变。
trigger2更新,两值都不变。

{{computedData}}
{{computedFun()}}
{{trigger1}}

data:{
  str : "当前时间是:",
  trigger1 : false,
  trigger2 : false
},
computed: {
  computedData: function () {
    return this.str + new Date()
  },
  computedData2: vm => vm.str + new Date()
},
methods: {
  computedFun(){
    return this.str + new Date()
  }
}
侦听器

侦听器可以达到与计算属性相同的效果
需要监听对象某个属性时,可以直接将对象.属性作为key,或将deep设为true

  watch: {
    str: function (val,oldVal) {
      this.watchedData = val + new Date()
    },
    str2: "someMethod",
    "obj.key": function (val,oldVal) {
      ...
    },
    obj2: {
      handler: "someMethod",
      deep: true,//该回调会在被侦听的对象的任何 property 改变时触发,不论嵌套多深
      immediate: true//侦听绑定后(created之前)立刻生效,此时old值为undefined,新值为data中值
    }
  }

侦听器每次只能侦听一个值,如果需要同时侦听多个,可配合computed使用

computed: {
  tempData: function () {
    const { param1 , param2 } = this;
    return { param1 , param2 } 
  }
},
  watch: {
    tempData: function (val) {
      ...
    }
  }
计算属性的getter和setter

计算属性默认为getter方法,也可以给予一个包含get和set方法的对象,当主动设置计算属性值时就会触发setter

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

Class与Style

class有两种绑定方式

  1. 对象语法 :class="{ 'className' : true , 'className2' : false}"
    (值为 truthy 即可,不一定需要为true)
  2. 数组语法 :class="[ 'className1' , 'className2' ]"
    注:对自定义添加的class,和该组件本身根元素的class,会取并集

style也有两种绑定方式

  1. 对象语法 :style="{ 'background-color' : 'red', fontSize: 15 + 'px' }"
  2. 数组语法 :style="[{ 'background-color' : 'red' }],[{ fontSize: 15 + 'px' }]"
    注:对需要加浏览器前缀的CSS属性,vue会自动检测并添加,如transform

条件渲染

值为 truthy 即可,不一定需要为true

v-if / v-else-if / v-else
  1. key管理可复用的元素
  2. 可以用template当做不可见的包裹元素,并在上面使用 v-if。


注:不要把 v-if 和 v-for 同时用在同一个元素上。(因 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,因此每当页面渲染时不管数组是否发生变化都进行了一次map,不利于性能。)

v-show

v-show不支持template, 有较高的初始渲染开销和较低的切换开销。

列表渲染

  • 支持 (均可以为计算属性或一个方法的返回值)
    1. 数组
    2. 对象
    3. 整数(会把模板重复对应次数)
  • 建议使用key追踪每个节点的身份
  • 类似v-if也可以用