vue基础
-
数据驱动视图
- 页面数据发生变化时,页面自动渲染
- 数据驱动视图是单向的数据绑定
-
双向数据绑定
- js的数据会自动渲染到页面上
- 页面上的表单采集的数据变化,也会自动被获取更新到js中
MVVM
MVVM是vue实现数据驱动视图和双向数据绑定的核心原理,M,V,VM
vue的基本使用
最基本的vue
<div id="app">{{username}}</div>
<script>
//创建vue实例
const vm = new Vue({
//绑定id选择器app
el: '#app',
//数据
data: {
username: 'zs'
},
methods:{}
})
</script>
注意:el尽量绑定外面一个大盒子,如果有多个同名盒子的话,vue只绑定第一个
指令
内容渲染指令
- v-text
<p v-text="username"></p>
会覆盖标签内部原本的内容
- {{}}插值表达式
<p>姓名:{{username}}</p>
<p>{{firstName + ' ' + lastName}}</p>
<p>{{num * 2]}}</p>
会插到原本内容,插值内部支持运算,字符串方法等
- v-html
<p v-html="username"></p>
会识别html标签渲染到页面
属性绑定指令
属性绑定是绑定了个新属性上去,不是其本身自带的属性
注意:插值表达式只能用在元素的内容节点,不能用在属性节点
动态绑定数据(对象)
// 单个动态数据
<div :class="{ active: isActive }"></div>
data: {
isActive: true
}
// 多个动态数据
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
data: {
isActive: true,
hasError: false
}
// 或
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
// 结果渲染为
<div class="static active"></div>
动态绑定数据(数组)
// 绑定多个class
<div :class="[activeClass, errorClass]"></div>
// 动态绑定class(三元表达式)
<div v-bind:class="[isActive ? activeClass : '']"></div>
动态绑定数据(数组对象)
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
动态绑定数据(到组件上)
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
<my-component v-bind:class="{ active: isActive }"></my-component>
// isActive为真时
<p class="foo bar active">Hi</p>
动态绑定数据(对象数组)
优先级从后往前
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
// 本例如果浏览器支持flex,即为
<div style="display: flex;"></div>
- v-bind可以简写为冒号(:)
// 2.6.0新增
// v-bind后的参数attributeName也可以动态改变了
// 语法为 v-bind:[attributeName] = "url"
// v-on同理
// attributeName为一个字符串,如果求得的结果出现问题,vue会将其变成null
// []中不能有空格或'
(在插值和属性中编写JS语句)
<div id="app">
<!--其实就是在""内拼接js字符串-->
<div :title="'box'+index">鼠标放上去显示box3</div>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
index: '3',
tips: 'hello'
}
})
</script>
事件绑定指令
- v-on可以简写为@
现在我们遇到了一个问题,我们想要获取到鼠标对象e,此时可以使用**$event**
<button @click="add(1,$event)"></button>
methods: {
add(n,e) {
this.count += n
console.log(e)
}
}
事件修饰符(vue特供)
//不用在事件处理函数写,直接绑在事件上
<button v-on:click.stop="add(1)">+1</button>
移动端新增.passive
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
还有按键修饰符,比如keyup.esc和keyup.enter等
双向绑定指令
- v-model(只能和表单元素一起使用)
表单元素:input、textarea、select
即获取表单的value属性同步修改
//data中的数据改变时,表单的内容会变;表单内容变化时,data也会变
<input type="text" v-model="username">
多个复选框绑定同一个数组
<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>
同时,我们还可以为选项绑定其他值
<!-- 当选中时,`picked` 为字符串 "a" -->
<input type="radio" v-model="picked" :value="a">
<select v-model="selected">
<!-- 内联对象字面量 -->
<option v-bind:value="{ number: 123 }">123</option>
</select>
vm.selected.number // => 123
事件修饰符
v-model的本质
// v-model其实只是一个语法糖,相当于v-bind + @input
<input v-model="searchText">
// 等价于
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
条件渲染指令
- v-if
//会真的移除和创建
<p v-if="flag"></p>
<p v-if="type === 'A'">优秀</p>
<p v-else-if="type === 'B'">良好</p>
<p v-else>一般</p>
如果有多个元素同时需要被切换,我们的第一反应是用一个div包裹起来然后用v-if,但是这样会有一个问题,dom中会多产生一个div;我们不想产生,可以用template包裹,最终不会渲染template
注意:vue会选择最小开销渲染元素,所以通常会复用已有元素
比如切换登录
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
// 因为二者已有元素完成相同,所以vue只需要替换input的placeholder,此时文本框输入的内容不会清除
但是这样给我们造成了困扰,我们想在切换的时候重新渲染输入框怎么办,vue的策略是给两个input设置不同的key
- v-show
//实际效果是display:none
<p v-if="flag"></p>
在vue2中,同一元素的v-if和v-for一起使用时,v-for优先级更高(不推荐)
列表渲染指令
- v-for
vue官方要求必须在v-for后绑定一个:key
用of或者in都行
数组
两个参数
<ul id="example-1">
<li v-for="(item,index) of items" :key="item.message">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
对象
三个参数,键值、键名、索引
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
当我们想将v-for的数据提前过滤一下时,可以使用computed;但是在某些情况下无法使用computed,例如双层for循环,我们可以使用方法来解决
<ul v-for="set in sets">
<li v-for="n in even(set)">{{ n }}</li>
</ul>
data: {
sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
与v-if同理,v-for也可以在template上使用,一次循环渲染包含多个元素的内容
v-once
只在第一次的时候展示数据,之后不会随着数据改变而改变
<p v-once> {{message}} </p>