过滤器
Vue. 支持在{{}}插值的尾部添加一小管道符 “ | ” 对数据进行过滤,经常用于格 式化文本,比如字母全部大写、货币千位使用逗号分隔等。过滤的规则是自定义 的, 通过给 Vue 实例添加选项 filters 来设置 过滤器:{{ data | filter1 |filter2}} {{date | formatDate(66,99)}} 中的第一个和第二个参数,分别对应过滤器的第二个和 第三个参数
{{date | formatDate(66,99)}}
filters:{
//这里的value就是需要过滤的数据
formatDate: function(value,a,b){
//将字符串转化为date类型
var date = new Date(value);
var year = date.getFullYear();//年
var month = plusDate(date.getMonth()+1);//月
var day = plusDate(date.getDate());//日
var hours = plusDate(date.getHours());
var min = plusDate(date.getMinutes());
var sec = plusDate(date.getSeconds());
//将整理好的数据返回
return year +'--'+month +'--'+day +' '+hours+'--'+min+'--'+sec+a+b;
}
注意 competed VS method的区别
- 渲染方式、计算属性依赖
- 缓存
注意competed VS watch的区别
- 异步和大量操作
- 例如异步访问api,debounce,设置中间状态。
Class与Style绑定
v-bind:class
- 绑定HTML Class
- 对象语法,键值对,注意计算属性使用,实现复杂逻辑的class绑定
- 数组语法,多个class
- 用在组件上
- 内联样式绑定
- 对象语法,用对象写css看起来很像,注意用驼峰命名
- 数组语法,内联绑定多个样式在一个元素上
条件渲染
使用key管理可以复用的元素
Vue会尽可能高效的渲染元素,通常会复用已有元素而不是从头开始渲染。
Vue提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”
添加一个具有唯一值的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>
元素仍然会被高效复用,因为没有添加key属性
v-if VS v-show
<h1 v-show="ok">Hello!</h1>
不同的是v-show的元素会始终会被渲染保留在DOM中。v-show只是简单地切换元素的css属性的display。
=> v-show不支持元素和v-else
- v-if
- v-if是真正的条件渲染,会确保在切换过程中条件块类的事件监听器和自主家适当地被销毁和重建。
- v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做直到条件第一次变为真,才会开始渲染条件块。
- v-show
- 无论初始条件是什么,元素总会被渲染,并且只是简单地基于css进行切换
总结:v-if有更高的切换开销,而v-show有更高的初始渲染开销。
如果需要频繁地切换,则v-show更好
如果在运行时条件改变很少,则v-show更好
v-if与v-for
不推荐两者一起使用,当v-if和v-for一起使用时,v-for具有比v-if更高的优先级。
列表渲染
v-for数组
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
<script>
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
</script>
=>
Parent-0-Foo
Parent-1-Bar
第二个参数index可选
可以用of代替in作为分隔符
v-for对象
<ul id="v-for-object" class="demo">
<li v-for="(value,name) in object">
{{ value }}: {{value}}
</li>
</ul>
<script>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
</script>
可选第二个参数为property名称(也就是键名)
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
=>
0.title: How to do lists in Vue
1.author: Jane Doe
2.publishedAt: 2016-04-10
可选第三个参数为索引index
遍历对象时,会按Object.keys()的结果遍历
维护状态
当 Vue 正在更新使用 v-for
渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key
属性:
建议尽可能在使用 v-for
时提供 key
attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
<div v-for="item in items" v-bind:key="item.id">
<!-- 内容 -->
</div>
数组更新检测
变异更新
这些方法会改变原数组,Vue将被侦听的数组的变异方法进行包裹,所以它们也将触发视图更新
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
替换数组
(计算属性)这些方法它们不会改变原始数组,而总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组,filter(),concat(),slice()
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
Vue不会丢弃现有DOM并重新渲染整个列表。Vue为了使DOM元素得到最大范围的重用而实现了一些智能的方式。
两个数组变动Vue检测不到
- 改变数组的指定项
- 改变数组的长度
解决方法
-
set方法用于改变数组的某个元素
//改变数组的指定项 (set) changeOne: function(){ Vue.set(app.arr, 1, 'car') // this.arr[1] = 'car'无效 },
-
splice
//改变数组的长度 changeLength: function(){ this.arr.splice(1) //this.arr.length = 1 无效 }
事件处理
v-on
内联处理器中的方法
都是say这个方法,只是值不同。
<div id="example-3">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>
<script>
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})
</script>
在内联语句中处理原始DOM事件,可以用特殊变量$event把它传入方法。
如果方法中带有参数,但是尼没有加括号,默认传原生事件对象event
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
<script>
methods: {
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) event.preventDefault()
alert(message)
//$event.preventDefault
}
}
</script
<div id="app"> //没有传参数,就是原生的。或者$event
<button @click="showBtnname($event)">显示按钮的名字</button> <br><br>
{{msg}}
</div>
new Vue({
el: "#app",
data: {
msg:''
},
methods: {
showBtnname: function(e){
this.msg = e.target.innerText;
}
}
})
事件修饰符
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。
为了方法只有纯粹的数据逻辑,而不是去处理DOM事件细节Vue.js为v-on提供了事件修饰符
.stop
.prevent
.capture
.self
.once
.passive
<!-- 阻止单击事件继续传播 -->
<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>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
.stop和.self有时结合使用
<div @click.self="divClick" style="background-color: cadetblue; width: 100px; height: 100px;">
<button @click.stop="btnClick">点击</button>
</div>
使用修饰符时注意顺序
v-on:click.prevent.self
会阻止所有的点击
v-on:click.self.prevent
只会阻止对元素自身的点击
passive
Vue 还对应 addEventListener
中的 passive
选项提供了 .passive
修饰符。
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
这个 .passive
修饰符尤其能够提升移动端的性能。
不要吧.passive
和 .prevent
一起使用,prevent会被忽略。
按键修饰符按键码
<input v-on:keyup.enter="submit">
<input v-on:keyup.13="submit">
可以通过全局config.keyCodes
对象自定义修饰符别名
// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
系统修饰键
用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta
.exact
鼠标修饰键
.left
.right
.middle
为什么在HTML中监听事件
所有的Vue.js事件处理方法和表达式都严格绑定在当前视图的ViewModel上
- 在html里轻松找到JavaScript里对应的方法
- 无须在JavaScript里手动解绑事件
- 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。
表单输入绑定v-model
v-model指令在表单元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素
<input>
<textarea>
<select>
v-model本质上不过是语法糖。负责监听用户输入事件以及更新数据,并对一些极端场景进行一些特殊处理
v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件
- text 和 textarea 元素使用
value
属性和input
事件; - checkbox 和 radio 使用
checked
属性和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
复选框
单个复选框绑定到布尔值
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
多个复选框绑定到同一个数组
个复选框,绑定到同一个数组:
<div id='example-3'>
<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>
</div>
<script>
new Vue({
el: '#example-3',
data: {
checkedNames: []
}
})
</script>
单选按钮
<div id="example-4">
<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>
<br>
<span>Picked: {{ picked }}</span>
</div>
<script>
new Vue({
el: '#example-4',
data: {
picked: '' //'One'
}
})
</script>
空字符串,或非要绑定的字符串值
选择框
有value直接优 先匹配一个value值,没有value就匹配一个text值
单选下拉框,空字符串
<div id="example-5">
<select v-model="selected">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
el: '...',
data: {
selected: ''
}
})
</script>
推荐像上面这样提供一个值为空的禁用选项,兼容ios
多选下拉框(绑定到一个数组)
<div id="example-6">
<select v-model="selected" multiple style="width: 50px;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
el: '#example-6',
data: {
selected: []
}
})
</script>
用v-for渲染的动态选项
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
<script>
new Vue({
el: '...',
data: {
selected: 'A',
options: [ //数组 ,对象
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})
</script>
值绑定
单选按钮:
<input type="radio" v-model="picked" v-bind:value="value"> {{picked}}
<!-- 123 -->
复选按钮
<input type="checkbox" name="" id="" v-model="toggle" v-bind:true-value="value1" v-bind:false-value="value2">
{{toggle}}
{{toggle == value1}}
{{toggle == value2}}
<hr>
下拉框
<select v-model="valueselect" >
<option v-bind:value="{num:111}">小狗</option>
<option value="小猫">小猫</option>
<option value="小猪">小猪</option>
</select>
现在选中的是{{typeof valueselect}} -> {{valueselect}}
<script>
new Vue({
el: '...',
data: {
//绑定value
//单选按钮
picked:'true',
value: '123', //value的值会转到绑定的v-model
//复选按钮
toggle: true, //:true-value="value1" :false-value="value2"两个属性来控制
value1: '我被选中',
value2:'我未被选中',
//下拉框
valueselect: '',
})
</script>
修饰符
- .lazy
<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" >
- .number
<input v-model.number="age" type="number">
如果想自动将用户的输入值转为数值类型
- .trim
<input v-model.trim="msg">
自动过滤用户输入的首尾空白字符