Vue.js——学习笔记


Vue-自学笔记

Vue (读音 /vju?/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

总之一句话:有问题,查官网。本笔记只适合学习复习使用。如果学习话,请自行查阅Vue官网。

本笔记来源于:自学过程,参考Vue官方文档。——大娃

基础

安装

https://cn.vuejs.org/v2/guide/installation.html 相关版本介绍

1. 直接引用

2. CDN

3. 模块化构建

起步

  1. 声明式渲染

    {{ message }}
    var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) //声明式渲染
  2. 条件与循环

    鼠标悬停几秒钟查看此处动态绑定的提示信息!
    var app2 = new Vue({ el: '#app-2', data: { message: '页面加载于 ' + new Date().toLocaleString() } }) //逻辑判断,相关指令
  3. 处理用户输入

    {{ message }}

    var app6 = new Vue({ el: '#app-6', data: { message: 'Hello Vue!' } }) //事件绑定,自动渲染
  4. 组件化应用构建

    Vue.component('todo-item', {
      // todo-item 组件现在接受一个
      // "prop",类似于一个自定义 attribute。
      // 这个 prop 名为 todo。
      props: ['todo'],
      template: '
  5. {{ todo.text }}
  6. ' })
    Vue.component('todo-item', { props: ['todo'], template: '
  7. {{ todo.text }}
  8. ' }) var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { id: 0, text: '蔬菜' }, { id: 1, text: '奶酪' }, { id: 2, text: '随便其它什么人吃的东西' } ] } }) //组件化应用构建-自定义

从上述简单的案例,让用户明白Vue能够用来干什么。虽然这些作者都已经说了,这些都只是Vue的皮毛的体现,但是就这些内容,已经颠覆了我对前端的认知了。

Vue实例

创建一个Vue实例

api:https://vuejs.org/v2/api/#Options-Data

var vm = new Vue({
  // 选项
})

当创建一个 Vue 实例时,你可以传入一个选项对象( {} 这个就是选项对象。)。这篇教程主要描述的就是如何使用这些选项来创建你想要的行为。

目前你只需要明白所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象 (一些根实例特有的选项除外)

数据与方法

api: https://vuejs.org/v2/api/#Instance-Properties

注意:当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时就已经存在于 data 中的属性才是响应式

这里唯一的例外是使用 Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。

Object.freeze(obj) 方法可以冻结一个对象。

var obj = {
  foo: 'bar'
}

Object.freeze(obj)

new Vue({
  el: '#app',
  data: obj
})

{{ foo }}

除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来。

var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})

vm.$data === data // => true
vm.$el === document.getElementById('example') // => true

// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
  // 这个回调将在 `vm.a` 改变后调用
})

我的理解: 这些API 也就是Vue提供了能够直接访问 Vue实例对象的参数的。

生命周期钩子

api: https://vuejs.org/v2/guide/instance.html#Instance-Lifecycle-Hooks

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

注意:不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a)vm.$watch('a', newValue => this.myMethod())。因为箭头函数并没有 thisthis 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致 Uncaught TypeError: Cannot read property of undefinedUncaught TypeError: this.myMethod is not a function 之类的错误。

官方提示:下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。

自己的理解:就是在生命周期的各个阶段,调用对应的回调函数,能够进行相关的操作。给用户提供了很多操作底层的机会。生命周期图中(标红部分)每个生命周期阶段都对应的一个点,也就是相同名字的对应回调函数。

模板语法

Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。

在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。

插值

  1. 文本 (Mustache 语法 {{}}

    数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值

    Message: {{ msg }}
    
  2. 原始HTML(v-html指令)

    Using v-html directive:

    注意:你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。

  3. Attribute (v-bind指令)

    对于布尔 attribute (它们只要存在就意味着值为 true),v-bind 工作起来略有不同,在这个例子中.

    如果 isButtonDisabled 的值是 nullundefinedfalse,则 disabled attribute 甚至不会被包含在渲染出来的 `` 元素中。

  4. 使用-JavaScript-表达式

    {{ number + 1 }}
    
    {{ ok ? 'YES' : 'NO' }}
    
    {{ message.split('').reverse().join('') }}
    
    

    这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。

    
    {{ var a = 1 }}
    
    
    {{ if (ok) { return message } }}
    

    注意:模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 MathDate 。你不应该在模板表达式中试图访问用户定义的全局变量。

指令

指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

  1. 参数

    一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML attribute。

  2. 动态参数

    从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:

    
     ... 
    
    
     ... 
    
  3. 修饰符

    修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()

    ...

缩写

  1. v-bind缩写

    
    ...
    
    
    ...
    
    
     ... 
    
  2. v-on缩写

    
    ...
    
    
    ...
    
    
     ... 
    

计算属性和侦听器

计算属性(computed)

对于任何复杂逻辑,你都应当使用计算属性

  1. 基础例子

    Original message: "{{ message }}"

    Computed reversed message: "{{ reversedMessage }}"

    var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } })

    结果:

    Original message: "大娃测试"

    Computed reversed message: "试测娃大"

    这里我们声明了一个计算属性 reversedMessage。我们提供的函数将用作属性 vm.reversedMessage 的 getter 函数:

    console.log(vm.reversedMessage) // => 'olleH'
    vm.message = 'Goodbye'
    console.log(vm.reversedMessage) // => 'eybdooG'
    

    你可以打开浏览器的控制台,自行修改例子中的 vm。vm.reversedMessage 的值始终取决于 vm.message 的值。

    你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。

    大娃理解:computed:这个VM的系统属性就是定义计算属性的。里面的方法自定义。实现了动态绑定data,还实现了缓存。调用属性名,就等于调用这个计算方法的getter()方法。

  2. 计算属性缓存VS方法

    注意:我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

    相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

    我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

  3. 计算属性VS侦听属性

    我现在还不知道侦听属性 watch 有什么用。不过能看到计算属性的缓存优势

    var vm = new Vue({
      el: '#demo',
      data: {
        firstName: 'Foo',
        lastName: 'Bar'
      },
      computed: {
        fullName: function () {
          return this.firstName + ' ' + this.lastName
        }
      }
    })
    
  4. 计算属性的setter
    计算属性默认只有 getter ,不过在需要时你也可以提供一个 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]
        }
      }
    }
    // ...
    

    现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

侦听器(Watchers)

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

watch: {
    // 如果 `question` 发生改变,这个函数就会运行
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  }

具体案例,查询官网给出的案例

大娃理解:监听器,功能也如字面意思,监听。当监听的属性发生变化的时候,做出指定的操作。

这里监听的属性可以是计算属性。

Class与Style绑定

补充概念:Truthy(真值) https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy

在 JavaScript 中,truthy(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除 false0""nullundefinedNaN 以外皆为真值)。

绑定HTML Class

  1. 对象语法

    可以直接定义在模板中

    可以:一个对象
    
    或者:两个对象
    data: { isActive: true, hasError: false } 或者:也可以不定义在模板中
    data: { classObject: { active: true, 'text-danger': false } } 或者:使用计算属性
    data: { isActive: true, error: null }, computed: { classObject: function () { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal' } }
  2. 数组语法

    我们可以把一个数组传给 v-bind:class

    //方式1:
    
    //方式2:三元表达式+数组
    //方式3:JS模板+数组
  3. 用在组件上(需要对Vue组件有了解)

    其实就是在说:自定义的模板组件,你定义时候带的class样式,默认是替换不掉的

    你定义的模板:

    Vue.component('my-component', {
      template: '

    Hi

    ' })

    然后你用的时候再加class的话

    
    

    会被渲染成这样,累加class的形式(class数据动态绑定形式的也是这样)

    Hi

绑定内联样式

  1. 对象语法

    data: { activeColor: 'red', fontSize: 30 } 或者直接绑定到一个样式对象通常更好,这会让模板更清晰:
    data: { styleObject: { color: 'red', fontSize: '13px' } }
  2. 数组语法

  3. 自动添加前缀

    v-bind:style 使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。

    很nice的配置。 如下所示,自动添加浏览器前缀

    -webkit-transition: all 4s ease;
    -moz-transition: all 4s ease;
    -ms-transition: all 4s ease;
    -o-transition: all 4s ease;
    transition: all 4s ease; 
    
  4. 多重值

    从 2.3.0 起你可以为 style 绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值,

    例如:

    这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex

条件渲染

v-if

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。

Vue is awesome!

Oh no ??

  1. template元素上使用-v-if-条件渲染分组

    PS:因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个