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可用于移除绑定。
<a v-bind:[attributeName]="url"> ... </a>
<a v-on:[eventName]="doSomething"> ... </a>
  • v-pre 对其中的{{...}}不进行编译
  • v-cloak 这个属性会保持在元素上直到关联实例结束编译,通常通过以下代码实现防抖
[v-cloak] {
  display: none;
}
...
<div v-cloak>
  {{ message }}
</div>

计算属性 和 侦听器

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

计算属性

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

页面第一次加载时,两个值相同。
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。
<template v-if="loginType === 'username'">
  <label>Username</label>
  <input key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input key="email-input">
</template>

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

v-show

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

列表渲染

  • 支持 (均可以为计算属性或一个方法的返回值)
    1. 数组
    2. 对象
    3. 整数(会把模板重复对应次数)
  • 建议使用key追踪每个节点的身份
  • 类似v-if也可以用<template>来循环渲染一段包含多个元素的内容。

v-for="item in items" 或 v-for="item of items"
v-for="(item, index) in items"
v-for="(value, name, index) in object"

通过以下方式变更数组/对象无法触发视图更新
  1. 利用索引直接设置一个项时,例如:vm.items[index] = newValue
  2. 修改数组的长度时,例如:vm.items.length = newLength
  3. 对象属性的新增或删除
  4. 利用 Object.assign() 或 _.extend() 直接赋值

可通过以下方法解决

Vue.set(vm.target, attrToChange, newValue)
vm.$set(vm.target, attrToChange, newValue)

数组也可以通过splice方法解决

vm.items.splice(indexOfItem, 1, newValue)
vm.items.splice(newLength)

另外如使用Object.assign()_.extend()时,参考如下

Object.assign(vm.userProfile, {age: 27}) //无效
vm.userProfile = Object.assign({}, vm.userProfile, {age: 27}) //有效
组件列表
  • 组件上使用v-for时,必须传入key
  • 迭代数据不会自动传入组件,需要依赖prop
<my-component
  v-for="(item, index) in items"
  v-bind:item="item"
  v-bind:index="index"
  v-bind:key="item.id"
></my-component>

事件处理

  • 通过$event可以把原生DOM事件传入方法
事件修饰符

修饰符可以串联,且其顺序决定了逻辑代码的顺序

  • .stop 阻止继续传播
  • .prevent 阻止默认事件
  • .capture 添加事件监听器时使用事件捕获模式
  • .self 仅当 event.target 是自身时触发,不会被子元素触发
  • .once 仅执行一次
  • .passive (2.3.0 新增) 对应addEventListener 中的 passive 选项,可以提升移动端的性能。会覆盖.prevent
按键修饰符

可以将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。如.enter , .tab , .delete (捕获“删除”和“退格”键) , .esc , .space , .up , .down , .left , .right, .ctrl, .alt, .shift, .meta(windows键或command键)以及鼠标按键.right , .left, .middle

<input v-on:keyup.enter="submit">
<input v-on:keyup.page-down="onPageDown">

也可以通过config.keyCodes自定义按键修饰符

// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
  • 2.5.0 新增.exact修饰符
    允许控制由精确的系统修饰符组合触发的事件
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

表单输入

v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • text 和 textarea 元素使用 value 属性和 input 事件;
  • checkbox 和 radio 使用 checked 属性和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。

通常情况下v-model 绑定的值是静态字符串或布尔值,但如果使用v-bind:value则也可以传入其他类型

复选框

单个复选框可绑定到布尔值,或通过true-valuefalse-value绑定其他属性。多个复选框时则可通过value绑定到数组

<input type="checkbox" id="checkbox" v-model="checked">
<input type="checkbox" v-model="toggle" true-value="yes" false-value="no">

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
...
checked : false
toggle : "no"
checkedNames: []
修饰符
  • .lazy 在“change”时而非“input”时更新
  • .number 将输入值转为number类型
  • .trim 自动过滤收尾空白字符

生命周期

new Vue()时依次执行breforeCreatecreatedbeforeMountmounted

  • breforeCreate
    此时不存在this.$eldatamethods也都拿不到
  • created
    此时不存在this.$el,但可以拿到datamethods。获取数据可以放在该阶段
  • beforeMount
    必须有 el: '#app'才会触发,此时this.$el指向html中书写的内容,但并未经过vue处理,如<div>{{loading}}</div>
  • mounted
    必须有 el: '#app'才会触发,此时this.$el指向渲染后的模板内容,如<div>true</div>

beforeCreate ->inject -> Props -> Methods -> Data -> Computed -> Watch ->provide-> created

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容