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 相关文章推荐
JS 实现完美include载入实现代码
Aug 05 Javascript
JS子父窗口互相操作取值赋值的方法介绍
May 11 Javascript
javascript获取本机操作系统类型的方法
Aug 13 Javascript
常见的javascript跨域通信方法
Dec 31 Javascript
深入理解JQuery中的事件与动画
May 18 Javascript
jQuery查找节点并获取节点属性的方法
Sep 09 Javascript
AngularJS自定义控件实例详解
Dec 13 Javascript
Vue render深入开发讲解
Apr 13 Javascript
vue中设置、获取、删除cookie的方法
Sep 21 Javascript
详解微信图片防盗链“此图片来自微信公众平台 未经允许不得引用”的解决方案
Apr 04 Javascript
微信小程序实现的图片保存功能示例
Apr 24 Javascript
vue实现二级导航栏效果
Oct 19 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
PHP Class&amp;Object -- PHP 自排序二叉树的深入解析
2013/06/25 PHP
PHP基本语法总结
2014/09/06 PHP
浅谈Coreseek、Sphinx-for-chinaese、Sphinx+Scws的区别
2016/12/15 PHP
Thinkphp5.0框架视图view的模板布局用法分析
2019/10/12 PHP
PHP正则之正向预查与反向预查讲解与实例
2020/04/06 PHP
BOOM vs RR BO3 第一场2.13
2021/03/10 DOTA
浅谈javascript的原型继承
2012/07/25 Javascript
JS将光标聚焦在文本最后的实现代码
2014/03/28 Javascript
CSS javascript 结合实现悬浮固定菜单效果
2015/08/23 Javascript
JS实现滑动菜单效果代码(包括Tab,选项卡,横向等效果)
2015/09/24 Javascript
JavaScript中的this到底是什么(一)
2015/12/09 Javascript
Angular 路由route实例代码
2016/07/12 Javascript
详解AngularJS ng-class样式切换
2017/06/27 Javascript
vue2.0 elementUI制作面包屑导航栏
2018/02/22 Javascript
layui从数据库中获取复选框的值并默认选中方法
2018/08/15 Javascript
基于Angular中ng-controller父子级嵌套的相关属性详解
2018/10/08 Javascript
antd组件Upload实现自己上传的实现示例
2018/12/18 Javascript
layui switch 开关监听 弹出确定状态转换的例子
2019/09/21 Javascript
JS精确判断数据类型代码实例
2019/12/18 Javascript
一个检测OpenSSL心脏出血漏洞的Python脚本分享
2014/04/10 Python
Python中字符串的常见操作技巧总结
2016/07/28 Python
Python基于分水岭算法解决走迷宫游戏示例
2017/09/26 Python
使用python实现http及ftp服务进行数据传输的方法
2018/10/26 Python
python钉钉机器人运维脚本监控实例
2019/02/20 Python
详解使用python爬取抖音app视频(appium可以操控手机)
2021/01/26 Python
遮罩层 + Iframe实现界面自动显示的示例代码
2020/04/26 HTML / CSS
廉价航班、机票和酒店:JustFly
2018/02/07 全球购物
linux面试题参考答案(5)
2016/11/05 面试题
法雷奥SQA(electric)面试问题
2016/01/23 面试题
车间主管岗位职责
2013/11/14 职场文书
助学感谢信范文
2015/01/21 职场文书
酒桌上的开场白
2015/06/01 职场文书
2015年秋季灭鼠工作总结
2015/07/27 职场文书
Pycharm 如何设置HTML文件自动补全代码或标签
2021/05/21 Python
python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法
2021/06/05 Python
JavaScript数组reduce()方法的语法与实例解析
2021/07/07 Javascript