Vue基础
Vue快速使用
编辑器选择
只要能编写html的编辑器都可以。
引入:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
快速使用
在js中创建vue对象:
<script>
// 新建vue对象
const vm = new Vue({
el: '#app', // 键名称固定,值为选择器,#app即id为app的标签
data: { // 键名称固定,值为各种变量
name: 'tom',
age: '18'
}
})
</script>
使用模板语法:
<div id="app">
<!-- name,age为vue对象data中的变量 -->
<p>我的名字是:{{ name }}</p>
<p>我的年龄是:{{ age }}</p>
</div>
<script>
// 新建vue对象
const vm = new Vue({
el: '#app', // 键名称固定,值为选择器,#app即id为app的标签
data: { // 键名称固定,值为各种变量
name: 'tom',
age: '18'
}
})
</script>
模板语法之插值
基本插值
vue对象的data键中可以放各种变量:
<script>
// 新建vue对象
const vm = new Vue({
el: '#app',
data: {
name: 'tom',
age: '18'
}
})
</script>
模板语法插值(根据变量名):
<div id="app">
<p>字符串:{{ name }}</p>
<p>数值:{{ age }}</p>
<p>数组:{{ hobby }}</p>
<p>对象:{{ obj }}</p>
<p>标签字符串:{{ link }}</p>
</div>
三目运算符
age变量大于等于18,返回值为成年人,否则返回值为未成年人
<p>三目运算符:{{ age>=18?"成年人":"未成年人" }}</p>
文本指令
文本指令,写在标签上的,以 v- 开头的属性。
文本指令 | 作用 |
---|---|
v-text | 把变量值显示在标签上,不做渲染,与模板语法一样 |
v-html | 标签字符串会渲染后在显示,其余与-v-text一样 |
v-show | 显示与不显示,修改display属性,会一直在页面上 |
v-if | 显示与不显示,不显示就是直接删除 |
使用:
<div id="app">
<p v-text="link1"></p>
<p v-html="link1"></p>
<p v-show="show1">显示文字1</p>
<p v-if="show1">显示文字2</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
link1: '<a href="https://www.baidu.com">百度一下 你就知道</a>',
show1: false,
}
})
</script>
页面效果:
f12查看元素:
v-show与v-if的区别
v-show为false时是设置display属性为none,而v-if为false时是直接删除标签。
双向数据绑定
v-model
双向数据绑定使用v-model指令:
<div id="app">
<input type="text" v-model="name"> name的值为{{ name }}
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name: '',
}
})
</script>
进阶
v-model有三种模式:
模式 | 作用 |
---|---|
.lazy | input框失焦后才会变化 |
.number | 只保留数字,但是字母开头就会失效 |
.trim | 移除首尾空格 |
<body>
<div id="app">
lazy模式:<input type="text" v-model.lazy="name1"> name的值为:{{ name1 }}<br>
number模式:<input type="text" v-model.number="name2"> name的值为:{{ name2 }}<br>
trim模式:<input type="text" v-model.trim="name3"> name的值为:{{ name3 }}<br>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name1: '',
name2: '',
name3: '',
}
})
</script>
事件指令
v-on
按钮,标签的事件:单击事件、双击事件...
语法结构:
<p v-on:事件名='函数'></p>
简写:
<p @事件名='函数'></p>
函数需要放在vue对象的methods中。
<script>
const vm = new Vue({
methods:{ // 函数要放在methods中,可以放多个
myFunc:function () {
},
}
})
</script>
案例:点击按钮后名字更改:
<div id="app">
<button v-on:click="myFunc">名字更改</button>
<p>名字:{{ name }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data:{
name:'tom'
},
methods:{ // 函数要放在methods中,可以放多个
myFunc:function () {
this.name = 'john'
},
}
})
</script>
输入框常见事件
事件 | 作用 |
---|---|
v-on:change | 失去焦点并且内容变化会触发 |
v-on:blur | 失去焦点会触发 |
v-on:input | 只要内容发生变化就会触发 |
事件修饰符
修饰事件 | 作用 |
---|---|
.stop | 只处理自己的事件,父控件冒泡的事件不处理 |
.self | 只处理自己的事件,子控件冒泡的事件不处理 |
.prevent | 阻止a链接的跳转 |
.once | 事件只会触发一次(适用于抽奖页面) |
.stop
<div id="app">
<ul @click="ulClick" style="background-color: aqua">
<li @click.stop="liClick" style="background-color: red">文本</li>
</ul>
</div>
<script>
const vm = new Vue({
el: '#app',
methods: {
ulClick(){
alert('ul')
},
liClick(){
alert('li')
},
}
})
</script>
.prevent
<div id="app">
<a href="https://www.baidu.com" @click.prevent="aClick">百度一下</a>
</div>
<script>
const vm = new Vue({
el: '#app',
methods: {
aClick(){
}
}
})
</script>
按键修饰符
普通使用
监测按下了哪个键。
<div id="app">
<input type="text" @keydown="down($event)">
</div>
<script>
const vm = new Vue({
el: '#app',
methods: {
down(e) {
console.log(e)
}
}
})
</script>
监听enter键
<div id="app">
<input type="text" @keydown.enter="enterDown">
</div>
<script>
const vm = new Vue({
el: '#app',
methods: {
enterDown() {
alert('你按下了enter键')
}
}
})
</script>
其他按键监听
大部分按键需要配合键码监听,比如a键监听:
<input type="text" @keydown.65="">
字母与数字键的对应关系:
按键 | 键码 | 按键 | 键码 | 按键 | 键码 | 按键 | 键码 |
---|---|---|---|---|---|---|---|
A | 65 | J | 74 | S | 83 | 1 | 49 |
B | 66 | K | 75 | T | 84 | 2 | 50 |
C | 67 | L | 76 | U | 85 | 3 | 51 |
D | 68 | M | 77 | V | 86 | 4 | 52 |
E | 69 | N | 78 | W | 87 | 5 | 53 |
F | 70 | O | 79 | X | 88 | 6 | 54 |
G | 71 | P | 80 | Y | 89 | 7 | 55 |
H | 72 | Q | 81 | Z | 90 | 8 | 56 |
I | 73 | R | 82 | 0 | 48 | 9 | 57 |
数字键盘与功能键:
按键 | 键码 | 按键 | 键码 | 按键 | 键码 | 按键 | 键码 |
---|---|---|---|---|---|---|---|
0 | 96 | 8 | 104 | F1 | 112 | F7 | 118 |
1 | 97 | 9 | 105 | F2 | 113 | F8 | 119 |
2 | 98 | * | 106 | F3 | 114 | F9 | 120 |
3 | 99 | + | 107 | F4 | 115 | F10 | 121 |
4 | 100 | Enter | 108 | F5 | 116 | F11 | 122 |
5 | 101 | - | 109 | F6 | 117 | F12 | 123 |
6 | 102 | . | 110 | ||||
7 | 103 | / | 111 |
按键 | 键码 | 按键 | 键码 | 按键 | 键码 | 按键 | 键码 |
---|---|---|---|---|---|---|---|
BackSpace | 8 | Esc | 27 | Right Arrow | 39 | -_ | 189 |
Tab | 9 | Spacebar | 32 | Dw Arrow | 40 | .> | 190 |
Clear | 12 | Page Up | 33 | Insert | 45 | /? | 191 |
Enter | 13 | Page Down | 34 | Delete | 46 | `~ | 192 |
Shift | 16 | End | 35 | Num Lock | 144 | [{ | 219 |
Control | 17 | Home | 36 | ;: | 186 | | | 220 |
Alt | 18 | Left Arrow | 37 | =+ | 187 | ]} | 221 |
Cape Lock | 20 | Up Arrow | 38 | ,< | 188 | '" | 222 |
属性指令
标签都是有属性的,想要动态变化属性,可以使用v-bind。
<img v-bind:属性='值' />
简写:
<img :属性='值' />
动态变化属性:
<div id="app">
<button v-on:click="changeImg">图片更改</button>
<img v-bind:src=imgUrl alt="" width="500px">
</div>
<script>
const vm = new Vue({
el: '#app',
data:{
imgUrl:'https://img0.baidu.com/it/u=530426417,2082848644&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500'
},
methods:{
changeImg:function () {
this.imgUrl = 'https://img1.baidu.com/it/u=700675537,3936578503&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500'
},
}
})
</script>
style和class使用
标签属性style和class是可以有多个值的,所以在使用v-bind指令时可以让它等于数组或者对象。
class属性
css样式:
<style>
.red {
color: red;
}
.big {
font-size: 32px;
}
</style>
使用:
<div id="app">
<p v-bind:class=myClass_str>文本</p>
<p v-bind:class=myClass_array>文本</p>
<p v-bind:class=myClass_obj>文本</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
myClass_str: 'red', // 字符串类型
myClass_array: ['red', 'big'], // 数组类型
myClass_obj: {'red': false, 'big': true}, // 对象类型
}
})
</script>
等价于:
<div id="app">
<p class='red'>文本</p>
<p class='red big'>文本</p>
<p class='red'>文本</p>
</div>
数组类型和对象类型都可以添加多个值,字符串只能添加单个值,其中数组类型最好用。
style属性
style使用键值对添加值时,css属性可以使用驼峰,比如font-size,可以写成fontSize,也可以加引号'font-size'不变。
<div id="app">
<p v-bind:style=myStyle_str>文本</p>
<p v-bind:style=myStyle_array>文本</p>
<p v-bind:style=myStyle_obj>文本</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
myStyle_str: 'color:red;font-size:32px;', // 字符串类型
myStyle_array: [{color:'red'}, {fontSize:'32px'}], // 数组类型
myStyle_obj: {color: 'red', fontSize: '32px'}, // 对象类型
}
})
</script>
字符串类型、数组类型和对象类型都可以添加多个值,其中对象类型最好用。
条件渲染
vue的三个判断条件指令:
- v-if:符合条件就显示
- v-else-if:与v-if搭配使用,与v-if差不多
- v-else:与v-if搭配使用,以上条件都不符合显示。
<p v-if="条件1">优秀</p>
<p v-else-if="条件2">良好</p>
<p v-else>不及格</p>
如果score大于等于90,显示优秀;如果score大于等于60小于90,显示良好;如果以上都不符合,显示不及格。
<div id="app">
<p v-if="score>=90">优秀</p>
<p v-else-if="score >= 60 && score< 90">良好</p>
<p v-else>不及格</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
score: 85,
}
})
</script>
循环渲染
v-for
循环使用v-for指令。
<p v-for="变量名 in 被循环的变量">{{ 变量名 }}</p>
循环数字:
<div id="app">
<h1>循环整型</h1>
<span v-for="item in num">{{ item }}, </span>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
num: 10,
}
})
</script>
循环字符串:
<div id="app">
<h1>循环字符串</h1>
<span v-for="item in str">{{ item }}, </span>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
str: 'abcdefg',
}
})
</script>
循环数组:
<div id="app">
<h1>循环数组</h1>
<span v-for="item in for_list">{{ item }}, </span>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
for_list: [1, 'asd', 555],
}
})
</script>
循环对象:
<div id="app">
<h1>循环列表</h1>
只拿对象的值:<span v-for="item in for_obj">{{ item }}, </span><br>
拿对象的键和值:<span v-for="(value, key) in for_obj">{{ key }}:{{ value }}, </span>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
for_obj: {name:'tom', age:18},
}
})
</script>
key属性
vue会先复制原生的DOM,生成一个虚拟的DOM。数据修改时,会先在虚拟DOM上更改,然后和原生DOM比较,再进行页面上数据的更新,这样做提高了数据的刷新速度。
在使用v-for时,可以写一个key属性:
<span v-for="item in 4" :key="item">{{ item }}</span>
这个作用相当于给标签写了个唯一属性key,它可以在数据更改时提高页面的刷新速度。
对于小项目来说,这个作用几乎没有。
数组的检测与更新
有时候,我们用一些数组,对象的方法更新数组或对象时,发现页面没有变化。
使用以下方法操作数组:
- 可以检测变动:push、pop、shift、unshift、splice、sort、reverse
- 不会检测变动:filter()、concat()、slice()、map(),新数组替换旧数组
<div id="app">
<button @click="myClick">改变数据</button>
<span v-for="item in myList">{{ item }}, </span>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
myList: [1, 2, 3],
},
methods: {
myClick(){
this.myList[0] = 222
},
}
})
</script>
上面这个例子点击按钮后并不会改变页面上的数据。
解决方法:
<div id="app">
<button @click="myClick">改变数据</button>
<span v-for="item in myList">{{ item }}, </span>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
myList: [1, 2, 3],
},
methods: {
myClick(){
Vue.set(vm.myList, 0, 222)
},
}
})
</script>
根据输入过滤案例
<div id="app">
<input type="text" v-model="name" @input="handlerInput"><br>
<p v-for="item in newList">{{ item }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name: '',
dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
newList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
},
methods: {
handlerInput() {
this.newList = this.dataList.filter(item=>{
return item.indexOf(this.name)>=0
})
}
}
})
</script>
表单控制
checkbox
单个多选框:
<div id="app">
<input type="checkbox" v-model="checkOne">记住密码
<p>checkbox状态:{{ checkOne }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data:{
checkOne:true
},
methods: {
}
})
</script>
多个多选框:
<div id="app">
<input type="checkbox" v-model="checkMany" value="篮球">篮球
<input type="checkbox" v-model="checkMany" value="足球">足球
<input type="checkbox" v-model="checkMany" value="乒乓球">乒乓球
<p>checkbox选中:{{ checkMany }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data:{
checkMany:[]
},
methods: {
}
})
</script>
radio
<div id="app">
<input type="radio" v-model="check" value="男">男
<input type="radio" v-model="check" value="女">女
<input type="radio" v-model="check" value="保密">保密
<p>radio选中:{{ check }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data:{
check:''
},
methods: {
}
})
</script>
购物车案例
选择商品实现:
点击查看代码
<div id="app">
<table>
<thead>
<tr>
<th>商品名</th>
<th>数量</th>
<th>单价</th>
<th>选择</th>
</tr>
</thead>
<tbody>
<tr v-for="item in dataList">
<td>{{ item.name }}</td>
<td>{{ item.quantity }}</td>
<td>{{ item.price }}</td>
<td><input type="checkbox" v-model="checkList" :value="item" @change="checkChange"></td>
</tr>
</tbody>
</table>
<p>商品:{{ checkList }}</p>
<p>总价:{{ total }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
dataList: [
{name: '牛奶', quantity: 2, price: 65},
{name: '娃娃', quantity: 1, price: 144},
{name: '钢笔', quantity: 5, price: 8},
{name: '电脑', quantity: 1, price: 5565},
],
checkList: [],
total: 0,
},
methods: {
checkChange() {
let total = 0
this.checkList.forEach((item, index)=>{
total += item.price * item.quantity
})
this.total = total
}
}
})
</script>
全选/反选实现
点击查看代码
<div id="app">
<table>
<thead>
<tr>
<th>商品名</th>
<th>数量</th>
<th>单价</th>
<th>全选<input type="checkbox" v-model="checkAll" @change="checkAllChange"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in dataList">
<td>{{ item.name }}</td>
<td>{{ item.quantity }}</td>
<td>{{ item.price }}</td>
<td><input type="checkbox" v-model="checkList" :value="item" @change="checkChange"></td>
</tr>
</tbody>
</table>
<p>商品:{{ checkList }}</p>
<p>总价:{{ getPrice() }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
dataList: [ // 商品详情
{name: '牛奶', quantity: 2, price: 65},
{name: '娃娃', quantity: 1, price: 144},
{name: '钢笔', quantity: 5, price: 8},
{name: '电脑', quantity: 1, price: 5565},
],
checkList: [], // 选中的商品
checkAll:false, // 全选框
},
methods: {
// 获取总价
getPrice() {
// 临时存储商品总价
let total = 0
// 计算总价
this.checkList.forEach((item, index)=>{
total += item.price * item.quantity
})
return total
},
// 单选选框变化
checkChange() {
// 商品没有全选时,全选框应该不打勾
this.checkAll = this.dataList.length === this.checkList.length
},
// 全选框变化
checkAllChange() {
if (this.checkAll) {
this.checkList = this.dataList
}else {
this.checkList = []
}
}
}
})
</script>
数量加减实现
点击查看代码
<div id="app">
<table>
<thead>
<tr>
<th>商品名</th>
<th>数量</th>
<th>单价</th>
<th>全选<input type="checkbox" v-model="checkAll" @change="checkAllChange"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in dataList">
<td>{{ item.name }}</td>
<td>
<button @click="reduce(item)">-</button>
{{ item.quantity }}
<button @click="item.quantity++">+</button>
</td>
<td>{{ item.price }}</td>
<td><input type="checkbox" v-model="checkList" :value="item" @change="checkChange"></td>
</tr>
</tbody>
</table>
<p>商品:{{ checkList }}</p>
<p>总价:{{ getPrice() }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
dataList: [ // 商品详情
{name: '牛奶', quantity: 2, price: 65},
{name: '娃娃', quantity: 1, price: 144},
{name: '钢笔', quantity: 5, price: 8},
{name: '电脑', quantity: 1, price: 5565},
],
checkList: [], // 选中的商品
checkAll: false, // 全选框
},
methods: {
// 获取总价
getPrice() {
// 临时存储商品总价
let total = 0
// 计算总价
this.checkList.forEach((item, index) => {
total += item.price * item.quantity
})
return total
},
// 单选选框变化
checkChange() {
// 商品没有全选时,全选框应该不打勾
this.checkAll = this.dataList.length === this.checkList.length
},
// 全选框变化
checkAllChange() {
if (this.checkAll) {
this.checkList = this.dataList
} else {
this.checkList = []
}
},
// 数量减少
reduce(item) {
if (item.quantity === 1) {
alert('不能在减少了!')
} else {
item.quantity--
}
},
}
})
</script>