Vue基础知识

Vue.js是什么

Vue.js是一个渐进式javascript框架,渐进式就是由浅入深、由简单到复杂的方式去使用Vue.js。Vue的核心是一个允许采用简洁的模版语法来声明式地将数据渲染进DOM的系统。
Vue有响应式和双向绑定特性。
响应式就是修改data中的数据,视图的数据也会发生改变,双向绑定是针对表单元素,比如文本框中输入的数据发生改变视图的数据也会改变。
组件化应用构建:
组件系统是Vue的另一个重要概念,因为它是一个抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。所有界面都可以抽象为一个组件树。
Vue中的所有组件都是Vue实例,我们只看到根组件有new Vue(),但是在子组件中并没有,为什么子组件也是Vue实例,那是因为webpack编译的时候会使用vue-loader去处理这些vue文件,生成一个个vue组件定义。

当一个Vue实例被创建时,它将data对象中的所有属性加入到Vue的响应式系统中。当这些属性的值发生改变时,视图将会产生响应,即匹配更新为新的值。当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时data中存在的属性才是响应式的。这里唯一的例外是使用 Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。

生命周期钩子函数给了用户在不同阶段添加自己代码的机会。不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a)。因为箭头函数没有this,this会作为变量一直向上查找,经常导致报错。

指令是带有v-前缀的特殊特性。指令特性的值预期是单个javascript表达式(v-for是例外情况)。

动态参数

可以用方括号括起来的javascript表达式作为一个指令的参数:

...

这里的attributeName会被作为一个javascript表达式进行动态求值,如果你的Vue实例有一个data属性attributeName,其值为href,那么这个绑定将等价于v-bind:href。
注意:如果返回的是非字符串则会触发警告,并且方括号中不能有空格或者引号,变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。

计算属性和侦听器

计算属性
背景

模版内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模版中放入太多的逻辑会让模版过重且难以维护。所以对于任何复杂逻辑,你都应当使用计算属性。
例如:

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('') } } })

从上面的例子中我们可以看到vm.reversedMessage 的值始终取决于 vm.message 的值。你可以像绑定普通属性一样在模版中绑定计算属性。Vue知道vm.reversedMessage 依赖于 vm.message,因此当vm.message发生改变时,所有依赖vm.reversedMessage的绑定也会更新。我们可以得出结论,data中定义的数据和computed中定义的数据都是响应式的。

计算属性缓存vs方法

背景:
我们为什么需要缓存?假设我们有一个性能开销比较大的方法A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有很多地方需要调用A。如果没有缓存,我们将会多次执行方法A,造成性能的浪费。这时候我们可以使用计算属性缓存的方式来代替。

我们可以用计算属性也可以直接在表达式中调用方法来达到同样的效果:

{{reverseMessage()}}

不管是计算属性还是方法得到的结果都是相同的。然后不同的是:计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要message还没有发生变化,多次访问reversedMessage计算属性会立即返回之前的计算结果,而不必再次执行函数。比如:页面上有多个地方访问reversedMessage,那么它只会计算一次,返回的结果相同,但如果是用方法的话,访问几次就会调用几次。

计算属性的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.firstName和vm.lastName也会相应地更新。

侦听器watch
背景

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

计算属性可以直接在模版还有js中使用,主要用在简单逻辑的运算上,而且是同步不能是异步的情况下使用,它必须返回的是一个数值,而watch可以用于异步或者复杂运算上,两者在某种程度上功能可以重合的,不过使用场景也有所不同

Class与Style绑定

绑定Class

有两种方式一种是对象一种是数组

如果是对象,那么active是class名,isActive可以是布尔值也可以是js表达式但是最终一定会被转为布尔值。
绑定的class也可以写在computed或data中

data: { classObject: { active: true, 'text-danger': false } } computed: { classObject: function () { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal' } } }
数组语法

可以是变量

data: { activeClass: 'active', errorClass: 'text-danger' }

可以是三目运算

可以是对象和变量

用在组件上

绑定内联样式

变量都可以绑定到data或computed中。

条件渲染

用key管理可复用的元素

【Vue会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使vue变得非常快之外,还有其他一些好处。例如,如果你允许用户在不同的登录方式之间切换:



那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素, 不会被替换掉——仅仅是替换了它的 placeholder。
这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key 属性即可:



使用场景:比如之前做的情报墙有多个图表循环切换的时候就会出现样式问题,这时候可以给它们一个key就有可能避免这种情况。

维护状态

当Vue正在更新使用v-for渲染的元素列表时,它默认使用就地更新的策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时DOM状态(例如:表单输入值)的列表渲染输出。
为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一的key属性。
简单的理解:比如一个输入框列表,在第一个输入框中输入了数值,把第一个输入框和第二个位置互换就会发现输入的数值还是在第一个输入框里,并没有随着第一个输入框位置的改变而改变
文章:https://juejin.im/post/5c2746b4e51d450d50306db2
https://www.zhihu.com/question/61078310

数组更新监测

除了以下两种方式无法监测其他情况都可以监测。
由于js的限制,vue不能监测以下数组 的变动:
1.当你利用索引值设置一个数组项时,也就是说改变数组中的某一个元素的值,例如vm.items[indexOfItem] = newValue
2.当你修改数组的长度时,例如:vm.items.length = newLength
举个例子:

let vm = new Vue({
   data () {
       items: ['a', 'b', 'c']
   },
})
vm.items[1] = 'x'  // 不是响应式的,不会触发dom更新
vm.items.length = 2  // 不是响应式的,不会触发dom更新

解决方法:
第一类问题解决方案:

vm.$set(vm.items, indexOfItem, newValue)
vm.items.splice(indexOfItem, 1, newValue)

第二类问题解决方案:

vm.items.splice(newLength)
对象变更检测注意事项

还是由于js的限制,vue不能检测对象属性的添加或删除
总结:Vue不能检测到数组和对象某个元素的变化,导致数据发生变化但是页面没有响应

在v-for里使用值范围

v-for不仅可以接受数组、对象,还可以接受整数。在这种情况下,它会把模版重复对应次数。

{{n}}
v-for与v-if一同使用

不推荐在同一个元素上使用v-if和v-for。当它们处于同一节点,v-for的优先级比v-if更高。

在组件上使用v-for

事件处理

监听事件的几种写法
直接写在html中

{{ counter }}

new Vue ({ el: '#example1', data: { counter: 0 } })

这里适合比较简单的代码逻辑

事件处理方法

如果是比较复杂的代码逻辑一般会直接写在methods中,有时需要在内联语句处理器中访问原始的DOM事件。可以用特殊变量$event把它传入方法:


new Vue({
  methods: {
    warn: function (message, event) {
    // 现在我们可以访问原生事件对象
    if (event) event.preventDefault()
    alert(message)
    }
  }
})
事件修饰符
passive修饰符

Vue对应addEventListener中的passive选项提供了.passive修饰符。

// 滚动事件的默认行为(即滚动行为)将会立即触发,而不会等待onScroll完成
// 这其中包含event.preventDefault()的情况
...

这个.passive修饰符尤其能够提升移动端的性能。注意不要把.passive和.prevent一起使用,因为.prevent将会被忽略。

.exact修饰符

.exact修饰符允许你控制由精确的系统修饰符组合触发的事件。例如:









鼠标按钮修饰符
  • .left
  • .right
  • .middle

表单输入绑定

基本用法

你可以用v-model指令在表单