开发者社区> 李一花> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Vue.js 2.0 快速上手 - 基础篇 - 知乎专栏 ·「魔都三帅」

简介: Vue 2.0 出来也有一段时间了,作为一个有志向的全面发展好青年,在征服 Vue 1.x,React,React Native 后,为了之后能更快迁移公司的项目到 Vue 2.x,于是决定先看看 Vue 2.0。
+关注继续查看

Vue 2.0 出来也有一段时间了,作为一个有志向的全面发展好青年,在征服 Vue 1.x,React,React Native 后,为了之后能更快迁移公司的项目到 Vue 2.x,于是决定先看看 Vue 2.0。

鉴于部分读者可能不了解 Vue,先简单看看各种特性。

本文假设你有一定的 HTML 基础,并熟悉一种或以上编程语言(那就能看懂 JS 了)。

模板语法

Vue 提供了一堆数据绑定语法。

  • {{ text }} 文本插值
  • HTML 输出
  • v-bind HTML 属性插值。如
  • JavaScript 表达式。直接在 mustache、属性插值里面使用各种表达式(加减乘除、三元运算、方法调用等)。
  • 过滤器(有点类似 Shell 命令中的管道,可以定义过滤器来对原始值进行变化)。
  • 指令。之前提到的 v-bind 也是一种指定,其他包括 v-on: 系列(dom 事件的监听)、v-for、v-model等。

Vue 实例

Vue 实例,实则也就是 ViewModel(数据 + 函数),都是通过构造函数 Vue 创建的:


var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data,
  created: function () {
    // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
  }
})
vm.$data === data // -> true
vm.$el === document.getElementById('example') // -> true
// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
  // 这个回调会在 `vm.a` 改变的时候触发
})

Vue 实例都有自己的生命周期,比如 created, mounted, updated 以及 destroyed。所有方法被 called 的时候,this 都指向所在的 Vue 实例。

计算属性和监听器

计算属性

其实就是一个需要计算的 getter:


riginal message: "{{ message }}"


  
Computed reversed message: "{{ reversedMessage }}"



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

和使用 method 的区别在于,计算属性根据它的依赖被缓存,即如果 message 没有被修改,下次 get 不会进行重复计算,而 method 则每次调用都会重新计算。这也意味着如 Date.now() 这样返回的计算属性会永远得不到更新。

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 = 'MarkZhai' 的时候,firstName 和 lastName 都会被更新。

监听器

Vue 的 watch 也可以用来做类似的事:


{{ fullName }}

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

对比一下计算属性版本:
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

看上去好像简单了很多,那还要 Watcher 干啥呢。。。主要应用场景是异步或耗时操作:

如此,使用 watch 让我们可以进行异步操作(访问 API),限制操作间隔,并设置中间状态直到获得了真正的答案。

除了使用 watch option,也可以用 vm.$watch API。

Class 和 Style 绑定

除了数据绑定,常见的还有 style、class 的绑定(正如很久以前在 JQuery 中常用的)。

对象语法

我们可以传递一个对象给 v-bind:class 来动态切换 classes:


对应的 active 和 text-danger 则通过 data 传递过来。

我们也可直接通过 data 把 class 传递过来


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

当然我们也能使用上面提到的 computed 来进行对应属性,如 active 的计算。

数组语法

可以直接传递一个数组给 v-bind:class:



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

绑定内联样式

跟 class 差不多:

或者直接绑定到 style:


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

类似的,也有数组绑定。

条件绑定

v-if

其实就是个标签啦


Yes


Yes

No


因为 v-if 必须附加到一个单一 element 上,那如果我们想切换多个元素呢?可以使用 template 元素:


v-show

也可以用 v-show 来做条件显示的逻辑,


Hello!


区别在于

  • v-show 不支持 template 和 v-else
  • v-if 是 lazy 的,不会渲染没有走到的条件。而 v-show 只是简单的基于 CSS 的切换。所以 v-show 的初始 render 代价较高。
  • 由于 v-if 是真实的渲染,切换后原来的 dom 会被 destroyed,而新的 dom 会被重新创建。所以切换代价更高。

所以如果切换得较为频繁可以使用 v-show,如果在运行时不太会改变则可以使用 v-if。

列表渲染

v-for

其实就是个循环标签啦:


    {{ parentMessage }} - {{ index }} - {{ item.message }}

对应的 vm 实例:

var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

模板 v-for

跟 v-if 类似,我们也能在 template 上使用 v-for:

对象 v-for

也能使用 v-for 遍历对象的属性:


  {{ value }}
  

new Vue({
  el: '#repeat-object',
  data: {
    object: {
      FirstName: 'John',
      LastName: 'Doe',
      Age: 30
    }
  }
})


看到 value,那肯定还有 key 了:


  {{ key }} : {{ value }}


如果再加上 index:


 {{ index }}. {{ key }} : {{ value }}


其他还有像是 v-for="n in 10" 这种用法,就不加上例子了。

组件 v-for

input 输出内容到 newTodoText,每次点击 enter 都会触发 addNewTodo,然后添加 item 到 todos,触发新的 li 添加进去:


 
Add a todo



  


Vue.component('todo-item', {
  template: '\
\
      {{ title }}\
      X\
    
\
  ',
  props: ['title']
})
new Vue({
  el: '#todo-list-example',
  data: {
    newTodoText: '',
    todos: [
      'Do the dishes',
      'Take out the trash',
      'Mow the lawn'
    ]
  },
  methods: {
    addNewTodo: function () {
      this.todos.push(this.newTodoText)
      this.newTodoText = ''
    }
  }
})


key

当 vue 在更新被 v-for 渲染的列表时候,会使用就地 patch 的策略,而不是根据元素改变的顺序。我们可以提供 key 来做这个排序:


如此,item 会根据 id 来做排序。

数组改变监测

替换方法(mutation)

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

这些方法会改变原来的 array,并自动触发 view 的更新。

替换 array

  • filter()
  • concat()
  • slice()

这几个方法会返回新的 array,如:


example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})

附加说明

如果

  • 直接 set array 的值,如 vm.items[indexOfItem] = newValue
  • 修改 array 的长度,如 vm.items.length = newLength

都是没法触发更新的,需要使用


Vue.set(example1.items, indexOfItem, newValue)

// Array.prototype.splice`
example1.items.splice(indexOfItem, 1, newValue)

example1.items.splice(newLength)

过滤/排序

配合 computed 以及 filter,或者也可以使用 v-for 的条件渲染:


{{ n }}


data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

事件处理

监听事件

使用 v-on 指令监听 DOM 的各种事件,如:


Add 1
The button above has been clicked {{ counter }} times.



var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
})


除了直接写 JS 语句,也可以直接在 v-on 中调用 methods 中定义的事件,还可以进行传参:



  Say hi
  Say what

new Vue({
  el: '#example-3',
  methods: {
    say: function (message) {
      alert(message)
    }
  }
})


我们可能也希望直接把 event 给传递到方法中(比如在方法里 preventDefault 或者 stopPropagation),也很 easy,直接使用特殊的 $event 变量就行了。

事件修饰符

除了像上面这样,在 method 里面对 event 进行操作,我们还可以使用事件修饰符(Event Modifier):

  • .stop
  • .prevent
  • .capture
  • .self

使用如:




 ...



 ...


Key 修饰符

通用的有使用 keyCode 的:

其他 alias 别名有

  • enter
  • tab
  • delete (captures both “Delete” and “Backspace” keys)
  • esc
  • space
  • up
  • down
  • left
  • right

我们也可以自己通过全局的 config 定义其他别名,如:


// enable v-on:keyup.f1
Vue.config.keyCodes.f1 = 112


表单输入绑定

基本使用

text



edit me

Message is: {{ message }}



如此,用户的输入会直接反映到 data 中的 message,然后更新到

多行的用 textarea 替换 input 就行了。

Checkbox

单个的:



{{ checked }}


多个的则可以绑到一个 array :



Jack

John

Mike


Checked names: {{ checkedNames }}

Radio



One



Two


Picked: {{ picked }}


Select



Selected: {{ selected }}
 Selected: C


多选的在 select 后面加个 multiple,然后对应的会绑定到数组。

还可以结合 v-for 进行动态渲染:


值绑定

默认地,像上面这样,最后 v-model 绑定到的对象,其值会是一个 静态字符串(或者 true/false),有时候我们想要将其值绑定到一个动态属性,就可以使用 v-bind 来达到目的。

比如对于 input:



// when checked:
vm.toggle === vm.a
// when unchecked:
vm.toggle === vm.b


甚至对象:



// when selected:
typeof vm.selected // -> 'object'
vm.selected.number // -> 123


修饰符

.lazy

默认地,v-model 在每次 input 事件后都会同步输入到数据。加上 lazy 修饰符后就会在 change 事件后才同步:

.number

会自动把输入转为 number:

这还是挺有用的,因为就算限制了 input 的 type 为 number,元素的 value 仍然会返回 string。

.trim

好像不用多说了?大家都懂吧。

组件

现代的前端框架,通常都是组件化的了。整个应用的搭建,其实就是组件的拼接。自然 Vue 也不会忘了这个。

使用组件

注册

注册一个全局组件,只需要 Vue.component(tagName, options) 即可,如:


Vue.component('my-component', {
  // options
})


实际渲染出来的 dom 则定义在 template option 中,如:


// 注册
Vue.component('my-component', {
  template: '

A custom component!

'
})
// 创建一个根实例
new Vue({
  el: '#example'
})



局部注册

局部注册只需要放在 Vue 实例中:


var Child = {
  template: '
A custom component!

'
}
new Vue({
  // ...
  components: {
    //  只在父亲的模板里可用
    'my-component': Child
  }
})



Dom 模板解析限制

当使用 Dom 作为模板(比如使用 el 选项来使用已有内容加载元素),将会受到一些因为 HTML 工作原理而导致的限制,因为 Vue 只能在浏览器解析后才获取模板数据并进行处理。比如

中将不能出现自定义组件,只能通过 is 特殊属性进行规避。

可以通过以下方法使用字符串模板,就不会有这些限制:


Vue.component('hello-world', {
  template: '#hello-world-template'
})


  • 在极小的应用或者大型模板的 demo 的时候可能会有用,其他情况下应该尽量避免。因为这样会把它和其他模板定义给隔离开。

    v-once 定义简单的静态组件

    在 Vue 里面渲染纯净的 HTML 元素是很快的,但有时候你可能需要一个包含了很多静态内容的组件。这种情况下,你可以通过在根元素加上 v-once 指令确保它只被评估了一次然后就被缓存下来了,像是这样:

    Vue 1.x TO 2.0

    通过使用 vue-migration-helper 可以快速扫出需要替换的代码。

    主要有以下几类:

    • 官方依赖,比如 vue-resource、vue-router(这个升级完接口也改了不少,迁移向导)、vue-loader、vue-hot-reload-api、vue-invalidate(还在升级中)等。
    • 第三方库。
    • UI组件库,比如 vux(目前计划是11月发布适配 2.0 的版本)、饿了么前端提供的那些(并没有给出更新计划)。
    • 组件间通讯,不能再使用 dispatch,而需要使用全局 eventbus 或者 vuex。
    • 各种 API 废弃,见 issue 2873,像是 attached、activated 这些生命周期 API 都被干掉了。

    具体一点的话,像是

    index

    $index 现在必须使用 index 了(在 v-for 中显示声明)

    filters

    不能像以前那样到处用了,只在 {{ }} 中生效,转而用计算属性或者方法吧。

    transition

    transition 属性被废弃了。可以看看新的 Transitions 文档

    vue router

    加了全局和离开当前页面的钩子,router-link,router data,等等。

    等等等等,要升级还是挺痛苦的。啊,对了 vuex 也升级到 2.0 了。更像 redux 了。心情很复杂

    尾声

    差不多也就是这样了。如果你是一个有一定经验并懂得基本 HTML 和 CSS 的高级工程师,我相信几天你就能看完并上手它了,毕竟对比 React 那一整套东西,还是相对简单的。


  • Vue.component('terms-of-service', {
      template: '\
    \
    Terms of Service
    
    \
          ... 很多静态内容 ...\
        
    
    \
      '
    })




原文发布时间为:2016年11月10日
原文作者:掘金
本文来源:掘金 如需转载请联系原作者

 






版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
前端-vue基础15-简单计算器
前端-vue基础15-简单计算器
10 0
《两地书》--Kubernetes(K8s)基础知识(docker容器技术)
 一个目标:容器操作;两地三中心;四层服务发现;五种Pod共享资源;六个CNI常用插件;七层负载均衡;八种隔离维度;九个网络模型原则;十类IP地址;百级产品线;千级物理机;万级容器;相如无亿,K8s有亿:亿级日服务人次。
61 0
《零基础》MySQL 连接的使用(二十)
在前几章节中,我们已经学会了如何在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据。 本章节我们将向大家介绍如何使用 MySQL 的 JOIN 在两个或多个表中查询数据。
25 0
Spring Boot 2.x基础教程:使用@Async实现异步调用
Spring Boot 2.x基础教程:使用@Async实现异步调用
49 0
原创翻译 通过拨号上网的Windows CE6.0 GPRS连接
介绍Windows CE提供两种方式与GPRS调制解调器连接:使用"cell core"函数和使用"拨号上网"。因为大多数的GPRS调制解调器不支持前一种方式需要的无线接口层(Radio Interface Layer, RIL)驱动,所以拨号上网是常被使用的方式。
846 0
吉特仓储管系统(开源)--使用Grunt压缩JS文件
  在吉特仓储管理系统开发的过程中大量使用到了JS,随着JS文件的增多我们需要对JS进行有效的管理,同时也要对JS文件进行一些压缩。文本用于记录一下使用grunt压缩JS的操作步骤,便于遗忘之后记录查找,文章内容非常浅显。
1161 0
+关注
126
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载