Vue笔记
那该多好 Lv2

编码时需要注意的问题

  1. 被Vue管理的函数最好写成普通函数,以保证this的指向是vm或组件的实例对象
  2. 不被Vue管理的函数(定时器的回调函数、ajax的回调函数、Promise的回调函数等),最好写成箭头函数,这样this的指向才是vm或组件的实例对象

Vue中的MVVM模型

  1. M: 模型(Model): data中的数据

  2. V: 视图(View) : 模板代码

  3. VM: 视图模型(ViewModel) : Vue实例

结果: ① data中所有的属性,最后都出现在了Vue的实例vm身上;

② vm身上所有的属性及Vue原型上所有的属性,在Vue的模板中都可以直接使用

Vue中的数据代理

  1. Vue中的数据代理是通过vm对象代理data对象中属性的操作(读/写)
  2. 基本原理:
① 通过Object.defineProperty()把data对象中所有属性添加到vm上。
② 为每一个添加到vm上的属性,都指定一个getter/setter。
③ 在getter/setter内部去操作(读/写) data中对应的数据

Vue中的事件

事件的基本使用

  1. 使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名。
  2. 事件的回调需要配置在methods对象中,最终会在vm上。
  3. methods中配置的函数,不要用箭头函数!否则this就不指向vm了。
  4. methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象。
  5. @click=”demo” 和 @click=”demo($event)” 效果一致,但后者可以传其他参数。

事件修饰符

  1. prevent:阻止默认事件
  2. stop:阻止事件冒泡
  3. once:事件只触发一次
  4. capture:使用事件的捕获模式
  5. self:只有event.target是当前操作的元素时才触发事件
  6. passive:事件的默认行为立即执行,无需等待事件回调执行完毕

键盘事件(常用的按键别名)

回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合keydown去使用)
上 => up
下 => down
左 => left
右 => right

计算属性computed

  1. 用途: 要使用的数据需要通过已有的属性加工后得来
  2. 原理:底层借助了Objcet.defineproperty方法提供的getter和setter
  3. get函数什么时候执行?
    (1).初次读取时会执行一次
    (2).当依赖的数据发生改变时会被再次调用
  4. 与methods实现相比,内部有缓存机制(复用),效率更高,调试方便
  5. 计算属性最终会出现在vm上,直接读取使用即可
  6. 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
data(){
return {
firstName:'',
lastName:''
}
}
//完整写法
fullName:{
get(){
console.log('get被调用了')
return this.firstName + '-' + this.lastName
},
set(value){
console.log('set',value)
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
// 简写
fullName(){
console.log('get被调用了')
return this.firstName + '-' + this.lastName
}

监视属性watch

  1. 当被监视的属性存在变化时,回调函数自动调用,进行相关操作
  2. watch默认不监测对象内部值得改变,可通过配置deep:true监测深层数据的变化
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    data(){
    return {
    isHot:true
    }
    },
    watch:{
    // 完整写法
    isHot:{
    immediate: true, // 初始化时执行一次回调函数
    deep: true, // 开启深度监听
    handler(newValue, oldValue){
    /* 函数体逻辑 */
    }
    }
    // 简写
    isHot(newValue, oldValue){
    /* 函数体逻辑 */
    }
    }

computed和watch之间的区别

compouted能完成的功能,watch都可以完成。watch能完成的computed不一定能完成,例如:watch可以发送异步请求

绑定样式

class样式

  • 写法::class='xxx'xxx可以是字符串、数组、对象
    • 字符串写法适用于:类名不确定,要动态获取。
    • 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
    • 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div :class="mood +' '+ font">字符串写法</div>
<div :class="classArr">数组写法</div>
<div :class="classObj">对象写法</div>
data(){
return {
mood: 'normal',
font: 'font',
classArr: ['class1', 'class2', 'class3'],
classObj: {
class1: false,
class2: false,
},
}
}

style样式

  • 写法: :style="{fontSize: xxx}":style="[a,b]"
    1
    2
    <div :style="{font-size:40px}">对象写法</div> 
    <div :style="[{font-size:40px},{color:#000}]">数组写法</div>

条件渲染

v-if

写法:
  (1).v-if="表达式" 
  (2).v-else-if="表达式"
  (3).v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”

v-show

写法:v-show="表达式"
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

列表渲染

v-for指令:

  1. 用于展示列表数据
  2. 语法: v-for="(item, index) in xxx" :key:"yyy" 3. 可用于遍历 数组、对象、字符串、指定次数

双向绑定

收集表单数据:
若:<input type="text"/> ,则v-model收集的是value值,用户输入的就是value值。
若:<input type="radio"/> ,则v-model收集的是value值,且要给标签配置value值。
若:<input type="checkbox"/>
1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2.配置input的value属性:
  (1).v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
  (2).v-model的初始值是数组,那么收集的的就是value组成的数组

备注:v-model的三个修饰符:

  • lazy:失去焦点再收集数据
  • number:输入字符串转为有效的数字
  • trim:输入首尾空格过滤

过滤器

定义:对要显示的数据进行特定的格式化后再显示(适用于一些简单逻辑的处理)。
语法:

  • 注册过滤器:Vue.filter(name, callback) 或在组件的配置对象中直接写 { ..., filters:{name(value){ return... }}}
  • 使用过滤器: {{ xxx| 过滤器名 }}v-bind:属性="xxx | 过滤器名"
    备注:
  • 过滤器可以接受额外参数,多个过滤器可以串联。
  • 不会改变原数据,产生新的对应的数据
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // 全局过滤器
    Vue.filter('mySlice', function(value){
    return value.slice(0,4)
    })
    // 全局过滤器使用方式
    {{msg | mySlice}} || :x="msg | mySlice"

    /*********************************************/
    // 局部过滤器
    {
    data,
    methods,
    filters:{
    timeFormater(value, str='YYYY年MM月DD日 HH:mm:ss'){
    return dayjs(valaue).format(str)
    }
    }
    }

    // 多个参数 和 过滤器连用:
    {{time | timeFormater('YYYY_MM_DD') | mySlice}}

内置指令

v-text

  • 作用:向其所在的节点中渲染文本内容。
  • 与插值语法的区别: v-text会替换掉节点中的内容, 则不会

v-html

  • 作用: 向指定节点中渲染包含html结构的内容。
  • 与插值语法的区别:
    • v-html会替换掉节点中的内容, 不会
    • v-html可以识别html结构。
  • 需注意:v-html有安全性问题
    • 在网站上动态渲染HTML非常危险,容易导致XSS攻击
    • 一定要在可信的内容上使用v-html, 不要用在用户提交的内容上

v-cloak

  • 特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
  • 使用css配合v-cloak可以解决网速慢时页面展示出的问题

v-once

  • v-once所在节点在初次动态渲染后,就视为静态内容了。
  • 以后数据的改变不会引起v-once所在的结构更新,可以用于优化性能

v-pre

  • 跳过其所在节点的编译过程。
  • 可以利用他跳过 没有使用指令语法、没有使用插值语法的节点, 会加快编译。

自定义指令

定义语法

  1. 局部指令:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    new Vue({
    directives:{
    // '指令名':'配置对象'
    /**
    * element : 使用当前指令的真实DOM
    * binding : 自定义指令的信息对象
    */
    // abc函数的的执行: 1. 指令与元素成功绑定时。 2. 指令所在的模板被重新解析时
    // 简写
    abc(element, binding){} || 'a-bc':function(element, binding){}

    // 完整写法
    abc:{
    // 指令与元素成功绑定时
    bind(element, binding){},
    // 指令所在元素被插入页面时
    inserted(element, binding){},
    // 指令所在模板被重新解析时
    update(element, binding){}
    }
    }
    })

  2. 全局指令
    1
    2
    3
    4
    5
    6
    7
    8
    Vue.directive('abc',{
    // 指令与元素成功绑定时
    bind(element, binding){},
    // 指令所在元素被插入页面时
    inserted(element, binding){},
    // 指令所在模板被重新解析时
    update(element, binding){}
    })

生命周期

钩子函数

  1. beforeCreate
    在实例初始化之后,在数据观测和事件配置之前被调用,这时的this还不能使用
  2. created
    实例创建完成后调用,可以使用data内的数据和methods内的方法了,但dom节点还未挂载,不能对dom节点进行操作
  3. beforeMount
    在挂载开始之前被调用,相关的 render 函数首次被调用。
  4. mounted
    挂载完毕,这时dom节点被渲染到文档内,一些需要dom的操作在此时才能正常进行
  5. beforeUpdate
    数据更新前调用,发生在虚拟dom重新渲染之前,可以在这个钩子中继续更改状态,不会再次触发渲染过程
  6. updated
    虚拟dom渲染成真实dom之后调用,现在可以执行 依赖于本次更新数据的操作
  7. beforeDestroy
    实例销毁之前调用。在这一步,实例仍然完全可用。
  8. destroyed
    实例销毁后调用。Vue 实例指示的所有东西都会解绑定,自定义事件会失效,但原生dom事件依然有效。

常用的钩子

  1. mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
  2. beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

组件

Vue中使用组件的三个步骤

  1. 定义组件(创建组件)
    使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样
    区别如下:
    1. 不能写el: 最终所有组件都要经过一个vm的管理,由vm中的el决定服务于哪个容器
    2. data必须写成函数: 避免组件被复用时,数据存在引用关系
    3. 组件结构的配置项为template
  2. 注册组件
    局部注册:new Vue的时候传入components选项
     全局注册:Vue.component('组件名',组件)
    
  3. 编写组件标签

注意点

  1. 关于组件名:
    一个单词组成:
     第一种写法(首字母小写):school
     第二种写法(首字母大写):School
    
    多个单词组成:
     第一种写法(kebab-case命名):my-school
     第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
    
    备注:
     组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
     可以使用name配置项指定组件在开发者工具中呈现的名字。
    
  2. 关于组件标签:
    第一种写法:<school></school>
    第二种写法:<school/>
    备注:不用使用脚手架时,<school/>会导致后续组件不能渲染。

VueComponent

  1. 组件的本质是一个名为VueComponent的构造函数,这个构造函数是由Vue.extend 生成
  2. 只需要写入 <school/><school></school>,Vue解析时会自动帮我们执行new VueComponent(options)
  3. 每次调用Vue.extend, 返回的都是一个全新的VueComponent!
  4. 关于this指向:
    • 组件配置中:
      data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
    • new Vue(options)配置中:
      data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
      — 注意 —
      内置关系:VueComponent.prototype.__proto__ === Vue.prototype
      为了让组件实例对象可以访问到Vue原型上的属性和方法
 评论