Vue.js学习总结

  • Vue不支持IE8以及以下版本。
  • 想要使用Vue的话可以通过直接下载vue.js,放置到项目中写好路径就可以,或者直接通过CDN引入https://cdn.jsdelivr.net/npm/vue/dist/vue.js,当然,在构建大型应用时推荐使用NPM安装(目前还没用到,用到再说)
  • Vue是一个MVVM框架
  • 一个简单的例子:

html:

{{ message }}

js:

var app=new Vue({
    el:"#app1",
    data:{
        message:'Hello world'
    }
});

上面的代码就相当于把id为app1的div元素和一个Vue实例绑定了起来(通过传入Vue的对象的el属性来和html元素绑定)。这时候Vue将数据和DOM建立了关联,是响应式的,比如可以通过打开页面之后打开页面的控制台,手动修改app1.message就可以看到页面上自动更新了。

上面html中的这种绑定方式是使用“Mustache”语法 (双大括号) 的文本插值(Mustache就是胡子的意思)

  • v-bind是一个指令,可以单向绑定DOM和数据,说是单向其实就是说数据变了之后DOM的value值和显示也会变化,但是DOM的value变了之后(例如在input元素中),数据不会改变。例子:

html:

鼠标悬停几秒钟查看此处动态绑定的提示信息!

js:

var app2 = new Vue({
  el: '#app2',
  data: {
    message: 'This is a message'
  }
});

这样当鼠标悬停在span元素上时,就会看到这段message。在控制台中修改app2.message之后也会立刻在DOM上反映出来。

  • 创建Vue实例是通过Vue(构造)函数来创建的,通过new关键字,Vue构造函数接受一个参数,该参数是一个对象,称为选项对象,可以直接在创建时候写一个对象,也可以先创建好一个对象再传入,即下面两种方式均可:
var vm = new Vue({
  el: '#some-id',
  data: {
    message: 'This is a message'
  }
});
var obj = {
    el: '#some-id',
    data: {
        message: 'This is a message'
    }
}
var vm = new Vue(obj);

上面两种方式均可,不过若是第二种方式,需要对象中的属性名(key)与标准的选项对象中的属性名一样,即名字必须为eldatamethods等。

  • 选项对象中的属性分别为:
    • el
      绑定DOM元素,是一个字符串类型,格式为'#id'
    • data
      用于存放属性、数据等,也是一个对象,数据都存在data对象内部
    • methods
      用于存放方法,DOM事件处理函数,是一个对象,函数方法存在对象内部
    • computed
      存放计算属性,所谓计算属性,就是逻辑比较多的属性,是一个对象,计算属性存放在computed对象内部,同时,计算属性本身是一个函数,函数内部是计算的逻辑。
    • watch
      侦听器,存放要侦听的数据,是一个对象,属性的名字(key)为要侦听的数据,属性的值为一个函数,即数据发生变化时要执行的回调函数。
    • 等等

上面这些属性,都会被初始化为Vue实例的属性,并且是绑定的是响应式的,即:

// 我们的数据对象
var data = { a: 1 }

// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
  data: data
})

// 获得这个实例上的属性
// 返回源数据中对应的字段
vm.a === data.a // => true

// 设置属性也会影响到原始数据
vm.a = 2
data.a // => 2

// ……反之亦然
data.a = 3
vm.a // => 3

值得注意的是只有当实例被创建时 data 中存在的属性才是响应式的。也就是说如果你添加一个新的属性,比如:

vm.b = 'hi'

那么对 b 的改动将不会触发任何视图的更新。如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,那么你仅需要设置一些初始值,如:

data: {
  newTodoText: '',
  visitCount: 0,
  hideCompletedTodos: false,
  todos: [],
  error: null
}

在使用Object.freeze()冻结传入的选项对象之后,Vue的响应系统无法再追踪变化。

当然,如果要想访问选项对象的属性,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` 改变后调用
})
  • Vue的模板语法:
    • 常规的Mustache语法,例如插入到pspan标签内
    • 如果想要插入原始html,则需要使用v-html指令
    • 如果想要为DOM元素绑定属性(或者称为特性,例如src、style、class或者其他自定义的特性),那么就不能用Mustache语法了,需要用v-bind指令,如:
      v-bind的特殊之处在于,使用了v-bind之后,后面的双引号中的,就不再是一个字符串了,即这个例子中的div元素的title属性的值不是"myTitle"这个字符串,而是对应的Vue实例(假设名字是vm)中的myTitle这个变量的值,即div的title值为vm.myTitle。所以,如果单纯的想传一个字符串给元素的属性(特性),就不要加v-bind或者前面加:,这点在组件的prop传值的时候也是这样的。
    • Vue的模板语法除了可以插入常规字符串之类的,还可以插入JavaScript表达式,如:

html:

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

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

html:


{{ var a = 1 }}


{{ if (ok) { return message } }}
  • Vue指令都是带有v-前缀的特殊特性。常见指令有以下这些:
    • v-bind
      用于绑定,上面说过了,还有就是组件的prop传值时用。
    • v-on
      用于绑定DOM事件。
    • v-if
      条件判断,条件渲染
    • v-for
    • v-model

上面的指令中,v-bindv-on可以被简写,如下:

html:


...


...


...


...
  • 计算属性,函数返回一个值:

html:

Original message: "{{ message }}"

Computed reversed message: "{{ reversedMessage }}"

js:

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

运行结果为:

Original message: "Hello"

Computed reversed message: "olleH"

计算属性也可以用vm.reversedMessagge来访问,并且它的值始终依赖于vm.message,后者改变前者也响应式地改变。

使用计算属性的地方也可以通过调用方法来实现,例如:

html:

Reversed message: "{{ reversedMessage() }}"

js:

methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

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

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

计算属性处理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]
    }
  }
}
// ...
  • 侦听器的使用方式为:
new Vue({
    el:'#id',
    data:{
        str:'some message'
    },
    watch:{
        str:function(oldStr,newStr){
            //...
        }
    }
});
  • class绑定
    绑定DOM元素的class就是前面说到的用v-bind,但是在绑定classstyle时,可以传入对象和数组:

html:

js:

data: {
  isActive: false,
  hasError: true
}

在上面的例子中,activetext-danger这两个class是否存在取决于对应的Vue实例中的属性isActivehasError的真值,同时在Vue中动态的class可以和普通的class并存,所以前面可以还有一个class,所以上面的渲染结果就是:

html:

class绑定的数据对象不一定非要内联在模板中,也可以直接就是一个对象,还可以是一个计算属性:

html:

js:

data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

除此之外,还可以是一个数组(甚至数组中还可以内嵌对象模板):

html:

js:

data: {
  isActive: true,
  errorClass: 'text-danger'
}

渲染为:

html:

如果是在自定义组件上,这些类会被添加到该组件的根元素上,这个元素上已经存在的类不会被覆盖:
js:

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

Hi

' })

html:


如果isActive的真值为真,则最终被渲染为:

html:

Hi

  • 绑定内联样式
    绑定CSS样式时,也是用上面提到的v-bind指令,然后让DOM元素的style属性(特性)等于一个对象或者数组即可:

html:

js:

data: {
  activeColor: 'red',
  fontSize: 30
}

或者直接绑定到一个样式对象通常更好,这会让模板更清晰:

html:

js:

data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

当然,也可以绑定到一个数组,数组的元素为多个样式对象。

  • v-if
    条件渲染,用法为

    Yes

    ,表示这个DOM元素对于的Vue实例(假设为vm)中的属性vm.ok为真时渲染h1这个元素。与v-if配合使用的经常有v-elsev-else-if。如果想要用v-if一条指令条件渲染多个元素,那么应该用一个