Vue-查缺补漏

MVVM

MVVM(Model-View-ViewModel):它将 View 和 Model 分割开,利用 ViewModel 将 Model 中的数据经过一定的处理变成适用于 View 的数据结构并传送到 View 渲染界面,同时 view 层的视图更新也会通知 viewModel,然后再更新 model 中的数据。View 和 ViewModel 之间通过双向绑定建立联系。

选项 el

  • el 用于指定一个页面已经存在的 DOM 元素来挂载 Vue 实例
  • el可以是 HTMLElement,也可以是 CSS 选择器
  • 挂载成功后,可通过 vm.$el 来访问该元素

选项 data

  • Vue 实例中的 data选项,声明应用内需要双向绑定的数据(建议所有用的的数据都预先再data内声明,这样不至于将数据散落在业务逻辑中,难以维护)
  • Vue 实例本身也代理了data对象中所有的属性,同时也代理methods里的方法,所有可以直接通过 vue 实例来访问属性,调用方法
  • 除了显示声明data外,也可以指向一个已有的变量,并且它们之间默认建立了双向绑定

Vue 生命周期函数

  • beforeCreate -> created
    进行初始化事件、进行数据的观测。在 created时,数据已经和data属性进行绑定,此时还没有el选项,

  • created -> beforeMount

    • 首先判断对象是否有el选项
      有,继续向下编译;没有,则停止编译。可通过手动在**Vue 实例上调用vm.$mount(el)**方法继续向下执行。
    • 判断 对象是否有 template选项
      有,则将其作为模板编译成render函数;没有,则将外部 HTML 作物模板编译。template 选项 优先级高于outer HTML
    • 如果对象还有render函数,以createElement作为函数,则直接用它渲染
    • 综合排名优先级:
      render函数选项 > template选项 > outer HTML
  • beforeMount -> mounted
    给 Vue 实例对象添加$el成员,并替换掉要挂载的 DOM 元素。

  • beforeUpdate -> updated
    当 Vue 发现data中数据变化,会触发对应组件的重新渲染

双括号(Mustache 语法)中的表达式

双括号中,只支持单个表达式,不支持语句和流程控制;不能直接使用用户自定义的全局变量,只能使用 Vue 白名单内的全局变量,如MathDate.

过滤器 filters 选项

可自定义过滤器,用于常见文本格式化,在 2 个地方使用,在表达式尾部,由管道(|)符号指示.
过滤器函数总接受表达式的值作第一参数,也可接受多个参数

  • 双大括号插值中

    1
    2
    3
    {{ message | filterA | filterB('arg1', arg2)}}
    // message 的值作为 filterA函数 第一个参数
    // filterA 函数的返回值,作为 filterB函数的 第一参数, 字符串"arg1",作为第二个参数, 表达式 arg2 的值作为第三个参数
  • v-bind表达式

    1
    <div v-bind:class="class | fromatClass"></div>

表达式 和 语句

表达式(expression)

  • 它是由常量、变量、运算符组合,计算以后返回一个结果值。表达式本身什么事情也不做,只是返回结果值。
  • 表达式 2 个作用:
    1. 放在赋值语句的右边
    2. 作为函数的参数

语句(statement)

  • js 整句或命令,以分号结束,语句用来自行使某件事发生
  • 赋值或函数调用这些有副作用的表达式,可以作为单独的语句。这种把表达式当作语句的用法称作表达式语句

计算属性

  • 默认getter方法来读取一个计算属性,,需要时也可以提供setter方法,当 手动修改计算属性的值,会触发setter 函数,执行一些自定义操作。
  • 计算属性可以依赖其他计算属性
  • 计算属性不仅可以依赖当前 Vue 实例的数据,也可以依赖其他实例的数据 (一个组件需要依赖另一个组件的数据)
  • 计算属性是基于它的依赖缓存的,如果一个计算属性所依赖的数据发生变化时,它才会重新取值。

v-bind 指令

动态的更新 HTML 元素上的属性,当数据变化,就会重新渲染。

绑定 class 几种方式

  • 对象语法
    对象中可以传入多个属性,来动态切换class. 对象内每项表达式为真时,对应的类名就会加上。

    1
    2
    3
    4
    5
    6
    <div :class="{'active': isActive, 'error': isError}"></div>
    <!--
    当数据 isActive, isError,为真时,对应类名active,error就会加载

    当数据isActive, isError变化,对应类名也会更新
    -->

    :class的 表达式过长、逻辑复杂时,可 绑定一个返回对象的计算属性

  • 数组语法
    :class绑定一个数组,应用一个 class 列表

    1
    2
    3
    4
    5
    6
    <div :class="[activeCls, errorCls]"></div>

    data: { activeCls: 'active', errorCls: 'error', }

    <!-- 结果 -->
    <div class="active error"></div>
  • 当直接在自定义组件使用class:class,样式规则会直接应用到这个组件的根元素上;如果需要给具体的子元素设置类名,应当使用组件的props来传递。

条件渲染指令

  • v-if,表达式的值为真,当前组件/元素及所有子节点将被渲染,为假时被移除。
  • 如果一次判断多个元素,可在内置<template>元素上使用条件指令,最终的渲染结果不会包含该元素。
  • Vue 在渲染时,出于效率考虑,会尽可能的复用已有的元素而非重新渲染。添加key属性后,就不会复用了。key的必须时唯一的。
  • v-show不能在<template>上使用。
  • v-show是改变元素的 CSS 属性display,无论条件真假,都会被编译,用于频繁切换条件。

列表渲染指令v-for

  • 遍历数组时,1 个可选参数,当前项的索引;枚举对象属性时,2 个可选参数,键名、索引

  • f-for也可以用在内置<template>上,将多个元素进行渲染

  • 数组变异方法,可改变原数组

    • push()
    • pop()
    • shift(), 从数组头部删除一个元素
    • unshift(), 从数据头部添加一个元素
    • splice(), [拼接],可添加/删除元素,参数[index,howmany,item…]
      • index, 必填,添加/删除的位置
      • howmany,必填,要删除的元素个数, 0,则不删除元素
      • item1,…,itemX, 可选,向数组中添加的新元素
    • sort()
    • reverse()
  • 数组非变异方法,不改变原数组.在使用,可以用新数组替换原数组,含有相同 元素的项不会重新渲染,因此可以 大胆替换,不用担心性能问题

    • filter()
    • concat()
    • slice()
  • Vue 不能监测到的数组变动

    • 利用索引设置一个项时, vm.items[indexOfItem]= newValue;
      解决方法:vm.$set(vm.items, indexOfItem, newValue)
    • 修改数组的长度时 vm.items.length = newLength;
      解决方法: vm.items.splice(newLength)
  • Vue 不能监测到对象属性的添加或删除

    • 对于已经创建的实例,Vue 不能动态的添加根级别的响应属性。但可以使用Vue.set(object,key,value)方法向嵌套对象添加响应式属性。

      1
      vm.$set(vm.userProfile,'age',27);
    • 有时需要为已有对象添加多个新属性,比如使用Object.assign()这种情况,应该用 2 个对象的属性创建一个新的对象

      1
      2
      3
      4
      5
      vm.userProfile = Object.assign({},vm.userProfile,{
      age: 27,
      favoriteColor: 'Vue Green'
      })

    • 显示一个数组的过滤/排序结果,但不改变或重置原始数据。这种情况下,可以创建返回过滤或排序数组的计算属性, 在计算属性不适用的情况下(例如,在嵌套v-for循环中),可以使用一个method方法

      1
      <li v-for="n in even(numbers)">{{ n }}</li>
    • 同一节点,v-for的优先级比v-if

      1
      2
      <!-- 只渲染 未完成的todos -->
      <li v-for="todo in todos" v-if="!todo.isComplete"></li>

事件处理

DOM 事件流(event flow)存在三个阶段:事件捕获、处于目标阶段、事件冒泡.触发顺序:先捕获再冒泡

事件捕获:当触发 DOM 事件时,浏览器会从 根节点 开始由外到内进行事件传播。即点击子元素,若果父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件。

事件冒泡:与事件捕获相反,由内到外进行事件传播,直到根节点。

  • v-on,1.可直接写 Js 代码;2.调用的方法名;3.内联 js 语句中调用方法,$event,访问原始 DOM 事件。
    1
    2
    3
    <button v-on:click="warn('Form cannot be submitted yet.', $event)">
    Submit
    </button>
  • 使用事件修饰符,此为更好的方式:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件的细节
    • .stop, 阻止事件继续传播(例如:阻止子节点事件,冒泡到父节点)
    • .prevent, 阻止默认事件
    • .capture<div v-on:click.capture="doThis">...</div> 添加事件监听器使用事件捕获模式(即,元素自身触发的事件先在此处理,然后才交给内部元素进行处理)
    • .self, 只有再event.target 是从当前元素自身触发,(即事件不是从内部元素冒泡触发的)

表单 与 v-model

  • 使用v-model后,表单控件显示的值只依赖所绑定的数据,不再关系初始化时的 value 属性。对再<textarea></textarea>之间插入的值,也不会生效。它本质上不过是语法糖,负责监听用户的输入事件以更新数据
  • v-model会忽略所有表单元素的value,checked,selected特性的初始值,而总是将 vue 实例中的数据作为数据来源,并在data选项中声明初始值
  • v-model 在内部使用不同的属性为不同的输入元素并抛出不同的事件:
    • text, textarea使用value属性和input事件
    • checkbox,radio使用checked属性和change事件
    • select,将value作为 prop,change事件。
  • 对于单选、复选框、选择框,v-model绑定的值通常是静态的字符串并配合value使用;
  • 对于只有一个选项的复选框,没有value属性,则绑定布尔值;有多个选项的复选框时,**v-model都有绑定到同一个数组类型**,否则默认为布尔类型
  • 选项列表,同样也分为单选和多选 2 中方式
    1
    2
    3
    4
    5
    <select v-model="selected" multiple>
    <option>html</option>
    <option value="js">javaScript</option>
    <option>css</option>
    </select>
    • 单选,
    • 多选,添加multiple属性,此时v-model绑定的时一个数组
    • <option>备选项如果用v-for动态输出,valuetext是用v-bind来动态输出的
      1
      2
      3
      4
      5
      <select v-model="selected">
      <option v-for="option in options" :value="option.value">
      {{option,text}}
      </option>
      </select>
  • 修饰符
    • .lazy,v-model在每次input事件触发后将输入框的值与data选项中的数据进行同步。.lazy转变成使用change事件进行同步数据。
      • input事件,在元素值发生变化时触发,即在用户输入时触发。可使用在input,textarea元素
      • change事件,在输入框失去焦点时才会触发,输入框内容变化时不会触发。使用在input,textarea,select元素
    • .number,将输入转换为 Number 类型
    • .trim,过滤输入的首尾空格