Vue 2.x教程之基础API


Posted in Javascript onMarch 06, 2017

本文主要介绍的是关于Vue 2.x之基础API的相关内容,主要内容如下

  • 模板语法(文本插值、属性绑定、JS表达式、过滤器、指令)
  • Vue实例(viewModal(属性+函数)、生命周期)
  • 计算属性和监听器 (computed(get,set) 与 watch)
  • 样式绑定(对象绑定、数组绑定、内联绑定)
  • 条件绑定(v-if v-show)
  • 列表渲染 (v-for、:key、数组监测、过滤/排序)
  • 事件处理 (监听、修饰符、key修饰符)
  • 表单输入绑定(text、checkbox、radio、select)

一、模板语法

文本插值

- 使用 `{{ }} / <span v-text="msg"></span>` 绑定数据
- `{{ }}` 纯文本绑定,单向,随vm变化而变化
- `<span v-once>{{ msg }}</span>` 纯文本,单次,不跟随vm变化
- `<span v-html="msg"></span>` 不转义html标签,绑定html

属性绑定

- 使用 `v-bind` 指令绑定数据至标签属性
- `<a v-bind:id="msgId"></a> 简写 <a :id="msgId"></a>`

模板中的JS

  • 支持表达式执行,但不支持多个表达式、语句和控制流的执行
  • 属性绑定和绑定的数据都支持JS表达式
//加减乘除、三元运算、方法调用
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
//错误用法
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

过滤器

- 使用 `|` 对原始值进行处理
- 用于属性绑定与 `{{ }}`
- `{{ msg | capitalize }} <a :id="msgId | formatId"></a>`
- 可以串联 `{{ msg | filterA | filterB }}`
- 可以接收参数 `{{ msg | filterA(arg1, arg2) }}`

指令

- 带有 `v-` 前缀的特殊属性
- 当其表达式的值改变时相应地将某些行为应用到 DOM 上
- `v-bind/v-for/v-html/v-on/v-if/...`
- `v-bind` 缩写 `<a v-bind:href="url" rel="external nofollow" rel="external nofollow" ></a><a :href="url" rel="external nofollow" rel="external nofollow" ></a>`
- `v-on` 缩写 `<a v-on:click="doSomething"></a><a @click="doSomething"></a>`

注册过滤器

//全局注册
Vue.filters('capitalize',value=>{
 if (!value) return ''
 value = value.toString()
 return value.charAt(0).toUpperCase() + value.slice(1)
})
//局部注册
filters: {
 capitalize: function (value, arg1) {
 if (!value) return ''
 value = value.toString()
 return value.charAt(0).toUpperCase() + value.slice(1)
 }
}
//使用
<span>{{msg | capitalize(arg1) }}

注意

  • 注册过滤器时,如果需要传递参数,必须从第二个参数开始,第一个参数为当前绑定的数据
  • 过滤器一般用于简单的文本格式化,如果是对多个状态数据,或是复杂的数据处理应该使用计算属性

注册指令

//全局注册
// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
 // 当绑定元素插入到 DOM 中。
 inserted: function (el) {
 // 聚焦元素
 el.focus()
 }
})
//局部注册
directives: {
 focus: {
 // 指令的定义---
 }
}
//使用
<input v-focus />

二、Vue实例

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

Vue 2.x教程之基础API

var vm = new Vue({
 name:'root',
 // 数据
 data: { a: 1 } / Function, // data类型根实例为Object,组件中为Function
 props:[]/{}, // 设置父组件传递给子组件的数据限制
 computed:{}, // 计算属性
 watch:{}, // 监控属性
 methods:{}, // 事件操作
 // 资源
 directives:{}, // 内部指令
 filters:{}, // 内部过滤器
 components:{}, // 内部组件
 // 生命周期:实例创建 => 编译挂载 => 组件更新 => 销毁
 beforeCreate(){
 console.log('beforeCreate ==> 实例创建')
 },
 created(){
 // 可以操作data, 但未生成DOM(未挂载)发起异步请求,初始化组件状态数据 data
 console.log('created ==> 实例创建完成,属性已绑定')
 },
 beforeMount(){
 console.log('beforeMount ==> 模板编译/挂载之前')
 },
 mounted(){
 // 已生成DOM到document中,可访问this.$el属性
 console.log('mounted ==> 模板编译/挂载之后')
 },
 beforeUpdate(){
 console.log('beforeUpdate ==> 组件更新之前')
 },
 updated(){
 // 操作DOM $('#box1')
 console.log('updated ==> 组件更新之后')
 },
 activated(){
 // 操作DOM $('#box1')
 console.log('activated ==> 组件被激活时(for keep-alive组件)')
 },
 deactivated(){
 console.log('deactivated ==> 组件被移除时(for keep-alive组件)')
 },
 beforeDestroy(){
 // 解除事件绑定,销毁非Vue组件实例等 如:this.$off('event1') select2.destory()
 console.log('beforeDestroy ==> 组件销毁之前')
 },
 destroyed(){
 console.log('destroyed ==> 组件销毁之后')
 }
})

三、计算属性与监听器

computed

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

可以像绑定普通属性一样在模板中绑定计算属性

声明式地创建依赖关系,计算属性的 getter 是干净无副作用的,因此也是易于测试和理解的。

<div id="example">
 <p>Original message: "{{ message }}"</p>
 <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
 el: '#example',
 data: {
 message: 'Hello'
 },
 computed: {
 // a computed getter
 reversedMessage: function () {
 // `this` points to the vm instance
 return this.message.split('').reverse().join('')
 }
 }
})

使用 methods 和 filter 也能达到计算属性同样的效果,但计算属性使模板更加简单清晰(模板中放入太多的逻辑会让模板过重且难以维护)。

计算属性有 计算缓存 的特性,计算属性是基于它的依赖缓存,只有在它的相关依赖发生改变时才会重新取值,而 methods 每次执行都会重新取值。

什么需要缓存?

假设我们有一个重要的计算属性 A ,这个计算属性需要一个巨大的数组遍历和做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter !如果你不希望有缓存,请用 method 替代。

getter与setter

计算属性默认为 getter

data: {
 firstName: 'Foo',
 lastName: 'Bar'
},
computed: {
 fullName: function () {
 return this.firstName + ' ' + this.lastName
 }
}

也可以添加 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]
 }
 }
}

watch

使用 watch 来监听data,实时响应数据的变化

例:监听用户输入,显示 正在输入...,输入完成时,显示 请稍等...,并发送异步请求,请求成功里,显示答案

var watchExampleVM = new Vue({
 el: '#watch-example',
 data: {
 question: '',
 answer: 'I cannot give you an answer until you ask a question!'
 },
 watch: {
 // 如果 question 发生改变,这个函数就会运行
 question: function (newQuestion) {
 this.answer = '正在输入...'
 this.getAnswer()
 }
 },
 methods: {
 // _.debounce 是一个通过 lodash 限制操作频率的函数。
 // 在这个例子中,我们希望限制访问yesno.wtf/api的频率
 // ajax请求直到用户输入完毕才会发出
 getAnswer: _.debounce(
 function () {
 if (this.question.indexOf('?') === -1) {
  this.answer = '需要一个问题标识\'?\''
  return
 }
 this.answer = '请稍候...'
 var vm = this
 axios.get('https://yesno.wtf/api')
  .then(function (response) {
  vm.answer = _.capitalize(response.data.answer)
  })
  .catch(function (error) {
  vm.answer = 'Error! Could not reach the API. ' + error
  })
 },
 // 这是我们为用户停止输入等待的毫秒数
 500
 )
 }
})

使用 watch 选项允许我们执行异步操作(访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这是计算属性无法做到的。

四、样式绑定

使用 v-bind:class v-bind:style 来绑定样式

data:()=>{
 return {
 isActive: true,
 hasError: false,
 classObj:{
 'active':true,
 'align-left':true,
 },
 activeClass: 'active',
 errorClass: 'text-danger',
 styleObj:{
 color: 'red',
 fontSize: '13px'
 },
 activeColor: 'red',
 fontSize: 30,
 baseStyles:{color: 'red'},
 overridingStyles: { fontSize: '20px'}
 }
}

对象语法绑定

class 绑定的是对象的 key,如果对象的值为 true,则绑定 key

style 绑定的整个 对象

绑定 class

<div v-bind:class="classObj"></div>
//<div class="active align-left"></div>
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
//<div class="static active"></div>

绑定style

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<div v-bind:style="styleObj"></div>
// <div style=" color:'red'; fontSize:'13px'; "></div>

数组语法绑定

class 绑定的是数组的 值

style 绑定的是数组中的 对象

<div v-bind:class="[activeClass, errorClass]">
// <div class="active text-danger">
// 使用三元表达式
<div v-bind:class="[isActive ? activeClass : '', errorClass]">
// 数组语法中使用对象语法
<div v-bind:class="[{ active: isActive }, errorClass]">
//绑定style
<div v-bind:style="[baseStyles, overridingStyles]">

五、条件渲染

v-if

切换元素的隐藏和显示 v-if、v-else、v-if-else

切换单个元素

<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>

切换多个元素

<template v-if="ok">
 <h1>Title</h1>
 <p>Paragraph 1</p>
 <p>Paragraph 2</p>
</template>

多条件判断

<div v-if="type === 'A'">
 A
</div>
<div v-else-if="type === 'B'">
 B
</div>
<div v-else-if="type === 'C'">
 C
</div>
<div v-else>
 Not A/B/C
</div>

条件渲染默认会复用相同的组件,如果不复用元素,可添加 key 值

<template v-if="loginType === 'username'">
 <label>Username</label>
 <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
 <label>Email</label>
 <input placeholder="Enter your email address" key="email-input">
</template>

v-show

用于切换元素样式属性 display 的 block 和 none

与 v-if 不同的是,元素隐藏时,并没有从DOM中删除,而 v-if 是删除了元素保存在缓存中。

注意 v-show 不支持 <template> 语法

v-if 是真实的条件渲染,因为它会确保条件块在切换当中适当地销毁与重建条件块内的事件监听器和子组件。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。

区分 v-if 与 v-show 的使用场景:

  • v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗
  • 如果需要频繁切换使用 v-show 较好
  • 如果在运行时条件不大可能改变则使用 v-if 较好

六、列表渲染

v-for='item of items / item in items' 用于迭代对象或数组中的元素

data: {
 items: [
 {message: 'Foo' },
 {message: 'Bar' }
 ]
 object: {
  firstName: 'John',
  lastName: 'Doe',
  age: 30
 }
}

基本用法

<ul id="example-1">
 <li v-for="item in items">
 {{ item.message }}
 </li>
</ul>

添加第二个参数可以获取当前迭代的 key 值

数组迭代

<ul id="example-2">
 <li v-for="(item, index) in items">
 {{ parentMessage }} - {{ index }} - {{ item.message }}
 </li>
</ul>

对象迭代

<div v-for="(value, key) in object">
 {{ key }} : {{ value }}
</div>

循环组件,向组件中传递数据

<my-component
 v-for="(item, index) in items"
 v-bind:item="item"
 v-bind:index="index">
</my-component>

组件有自己的作用域,向组件中传递数据需要使用属性传递

v-for 具有比 v-if 更高的优先级

判断每一个todo项是否可显示

<li v-for="todo in todos" v-if="!todo.isComplete">
 {{ todo }}
</li>

判断是否需要迭代todos

<ul v-if="shouldRenderTodos">
 <li v-for="todo in todos">
 {{ todo }}
 </li>
</ul>

添加 key 属性

提升重复渲染效率

<div v-for="item in items" :key="item.id">
 <!-- 内容 -->
</div>

数组监测

Vue重写了数组的变异方法,用于监测数组的更新

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

这些操作会改变原有数组,为变异方法

非变异方法返回新的数组,可以用于替换旧的数组

直接修改数组长度、利用索引修改数组的值,不会被监听到

过滤/排序

使用计算属性对原有数组进行过滤和排序

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

七、事件监听

v-on

v-on 用于监听绑定的事件

<div id="example-3">
 <button @click="say('hi')">Say hi</button>
 <button @click="say('what')">Say what</button>
</div>
new Vue({
 el: '#example-3',
 methods: {
 say: function (message) {
  alert(message)
 }
 }
})

原生事件对象

使用 $event 传递原生事件对象

<button v-on:click="warn('hello', $event)">Submit</button>
methods: {
 warn: function (message, event) {
 // 现在我们可以访问原生事件对象
 if (event) event.preventDefault()
 alert(message)
 }
}

事件修饰符

methods 应该只处理纯粹的数据逻辑,而不是去处理 DOM 事件细节

     .stop 阻止事件冒泡

     .prevent 阻止默认事件

     .capture 使用捕获模式

     .self 只有当事件作用于本身时才触发

     .once 只绑定一次

<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>
<!-- 点击事件将只会触发一次 2.1.4-->
<a v-on:click.once="doThis"></a>
<!-- 组件中的原生事件 -->
<my-component @click.native="onClick"></my-component>

按键修饰符

监听键盘按下的键值

监听keyCode

<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">

常用按键别名

  • .enter
  • .tab
  • .delete (捕获 “删除” 和 “退格” 键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right
  • 2.1.0
  • .ctrl
  • .alt
  • .shift
  • .meta
<!-- 同上 -->
<input v-on:keyup.enter="submit">

按键组合

<!-- Alt + C -->
<input @keyup.alt.67="clear">
  • 所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上
  • 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何自己清理它们。

八、表单输入绑定

使用 v-modal 给表单控件绑定相关数据(双向绑定)

v-modal 是一个语法糖

<input v-model="something">
// 等同于
<input v-bind:value="something" v-on:input="something = $event.target.value">

基本输入

// 文本框
<input v-model="message" placeholder="edit me">
// 文本域(支持换行)
<textarea v-model="message" placeholder="add multiple lines"></textarea>
// 复选框
// 单选(返回 true/false )
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
// 多选 (返回一个数组 ['jack', 'john'])
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
//单选框 (返回选中的值)
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
// 下拉框
// 单选 (返回选中的值)
<select v-model="selected">
 <option>A</option>
 <option>B</option>
 <option>C</option>
</select>
// 多选(返回一个数组 ['A','B'])
<select v-model="selected" multiple>
 <option>A</option>
 <option>B</option>
 <option>C</option>
</select>

当有选项有 value 属性时,选中时,返回 value, 当属性没有 value 时,选中时返回字符串或 true/false

<select v-model="selected">
 <option v-for="option in options" v-bind:value="option.value">
 {{ option.text }}
 </option>
</select>

绑定动态的value

v-model 绑定的 value 通常是静态字符串,对于 radio、checkbox、select,可以动态的使用v-bind设置value

<input
 type="checkbox"
 v-model="toggle"
 v-bind:true-value="a"
 v-bind:false-value="b"
>
// 当选中时
vm.toggle === vm.a
// 当没有选中时
vm.toggle === vm.b

修饰符

v-modal 的修饰符 .lazy、 .number、.trim

<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >
// 自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值)
<input v-model.number="age" type="number">
// 过滤用户输入的首尾空格
<input v-model.trim="msg">

自定义输入组件

使用 v-modal 自定义输入组件

前提条件,组件必须有 value 属性, 在有新的value时,可通过 input 事件获取更新的值。

自定义的货币输入组件

<currency-input v-model="price"></currency-input>
Vue.component('currency-input', {
 template: '
 <span>
  $
  <input
  ref="input"
  v-bind:value="value"
  v-on:input="updateValue($event.target.value)"
  >
 </span>
 ',
 props: ['value'],
 methods: {
 // 不是直接更新值,而是使用此方法来对输入值进行格式化和位数限制
 updateValue: function (value) {
  var formattedValue = value
  // 删除两侧的空格符
  .trim()
  // 保留 2 小数位
  .slice(0, value.indexOf('.') + 3)
  // 如果值不统一,手动覆盖以保持一致
  if (formattedValue !== value) {
  this.$refs.input.value = formattedValue
  }
  // 通过 input 事件发出数值
  this.$emit('input', Number(formattedValue))
 }
 }
})

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Javascript中的var_dump函数实现代码
Sep 07 Javascript
javascript创建和存储cookie示例
Jan 07 Javascript
jQuery中children()方法用法实例
Jan 07 Javascript
javascript判断数组内是否重复的方法
Apr 21 Javascript
jquery UI Datepicker时间控件的使用方法(基础版)
Nov 07 Javascript
jQuery之动画效果大全
Nov 09 Javascript
Angular.Js的自动化测试详解
Dec 09 Javascript
纯js实现页面返回顶部的动画(超简单)
Aug 10 Javascript
webpack 单独打包指定JS文件的方法
Feb 22 Javascript
详解vuex之store拆分即多模块状态管理(modules)篇
Nov 13 Javascript
基于canvasJS在PHP中制作动态图表
May 30 Javascript
JS实现页面侧边栏效果探究
Jan 08 Javascript
jQuery实现获取h1-h6标题元素值的方法
Mar 06 #Javascript
一道面试题引发的对javascript类型转换的思考
Mar 06 #Javascript
JavaScript函数参数的传递方式详解
Mar 06 #Javascript
jQuery实现遍历复选框的方法示例
Mar 06 #Javascript
jQuery.cookie.js使用方法及相关参数解释
Mar 06 #Javascript
jQuery Validate 相关参数及常用的自定义验证规则
Mar 06 #Javascript
jQuery简单实现遍历单选框的方法
Mar 06 #Javascript
You might like
浅析51个PHP处理字符串的函数
2013/08/02 PHP
PHP把数字转成人民币大写的函数分享
2014/06/30 PHP
php发送get、post请求的6种方法简明总结
2014/07/08 PHP
通过PHP简单实例介绍文件上传
2015/12/16 PHP
PHP redis实现超迷你全文检索
2017/03/04 PHP
PHP实现的堆排序算法详解
2017/08/17 PHP
PHP实现简易计算器功能
2020/08/28 PHP
javascript 日期时间函数(经典+完善+实用)
2009/05/27 Javascript
去掉gridPanel表头全选框的小例子
2013/07/18 Javascript
js实现漂浮回顶部按钮实例
2015/05/06 Javascript
javascript实现简单加载随机色方块
2015/12/25 Javascript
vue.js表格组件开发的实例详解
2016/10/12 Javascript
用JavaScript实现让浏览器停止载入页面的方法
2017/01/19 Javascript
js获取地址栏参数的两种方法
2017/06/27 Javascript
网页中的图片查看器viewjs使用方法
2017/07/11 Javascript
jquery学习笔记之无new构建详解
2017/12/07 jQuery
解决node.js含有%百分号时发送get请求时浏览器地址自动编码的问题
2019/11/20 Javascript
[03:58]2014DOTA2国际邀请赛 龙宝赛后解密DK获胜之道
2014/07/14 DOTA
Python网络编程中urllib2模块的用法总结
2016/07/12 Python
SVM基本概念及Python实现代码
2017/12/27 Python
python编程培训 python培训靠谱吗
2018/01/17 Python
python基础教程项目四之新闻聚合
2018/04/02 Python
Django 对IP访问频率进行限制的例子
2019/08/30 Python
wxPython色环电阻计算器
2019/11/18 Python
使用python-cv2实现视频的分解与合成的示例代码
2020/10/26 Python
欧洲有机婴儿食品最大的市场:Organic Baby Food(供美国和加拿大)
2018/03/28 全球购物
ParcelABC西班牙:包裹运送和快递服务
2019/12/24 全球购物
几个数据库方面的面试题
2016/07/01 面试题
小区推广策划方案
2014/06/06 职场文书
2015圣诞节贺卡寄语
2015/03/24 职场文书
自主招生专家推荐信
2015/03/26 职场文书
培训讲师开场白
2015/06/01 职场文书
欠条样本
2015/07/03 职场文书
2016预备党员培训心得体会
2016/01/08 职场文书
2016年万圣节活动总结
2016/04/05 职场文书
Python语言中的数据类型-序列
2022/02/24 Python