vue入门(一)
1. 什么是vue
- 一个框架(现有的解决方案)
- 构造用户界面(操作html页面的内容)
2. vue的特性
-
数据驱动视图
页面所依赖的数据发生变化时,vue会监听数据的变化,重新渲染页面
-
双向数据绑定
- 页面所依赖的数据发生变化时,vue会监听数据的变化,重新渲染页面
- 页面中的表单数据发生变化时,vue也会监听其变化,相应的改变页面所依赖的数据
- 优点
数据的同步减少了对DOM的操作
3. vue的核心原理-mvvm
-
实现两大特性的核心原理
-
组成
M:Model:页面渲染时所需要的数据源
V:view:页面结构,视图
VM:ViewModel:表示vue的实例:MVVM的核心
4. vue的使用
- 导入vue.js的script脚本文件
- 在页面中声明一个将要被vue所控制的DOM区域
- 创建vue实例对象
- 示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- vue要渲染的区域 -->
<div class="box">{{username}}</div>
<!-- 引入vue.js文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 定义自己的js,使用vue创建一个实例 -->
<script>
const vm = new Vue({
el: '.box',
data: {
username: 'zhangsna'
}
})
</script>
</body>
</html>
- 效果图
- 注意点
vue的控制范围为选择器选中的标签(只会选中第一个,如果存在多个,例如标签选择器)及其标签内部的标签
5.vue 指令
模板语法,类似于模板引擎的语法
5.1 内容渲染指令(为元素内容设置值)
v-text:渲染文本,覆盖标签原有的文本,作为属性值使用
v-html:可以渲染带有html标签的文本
{{}} :插值表达式:起到占位符的效果,不会覆盖原有的内容
- 为元素内容设置值,不能为元素的属性设置值
- 示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="box">
<!-- 使用v-text渲染文本 -->
<p v-text="username">111</p>
<!-- 使用v-html渲染含有html标签的文本-->
<p v-html="username">111</p>
<!-- 使用 {{}} 插值表达式来渲染文本 -->
<p>性别:{{gender}}</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '.box',
data: {
username: '<h3 style="color:red;">123</h3>',
age: 18,
gender: '男'
}
})
</script>
</body>
</html>
- 效果图
5.2 属性绑定指令(为元素的属性设置值)
v-bind:要设置的属性名="这里输入vue实例中的data属性名"
- 简写的形式
简写为 :要设置的属性名="这里输入vue实例中的data属性名"
- {{}}插值表达式和v:bind 中的内容支持js的语法
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="box">
<!-- 为input的占位符属性设置值 -->
<input type="text" v-bind:placeholder="placeholderText">
<!-- 给图片的src属性设置值 -->
<img :src="imageSrc" alt="" width="100px">
<!-- {{}}插值表达式和V:bind支持js的语法 -->
<!-- 将data中的age加上1 -->
<p>age+1={{age+1}}</p>
<!-- 字符串调用方法 -->
<p>{{placeholderText}} 的翻转的结果为 {{placeholderText.split('').reverse().join('')}}</p>
<!-- 拼接字符串 -->
<p :title="'p'+age">111</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '.box',
data: {
placeholderText: '请输入内容',
imageSrc: 'https://game.gtimg.cn/images/yxzj/cp/a20161115tyf/logo.png',
age: 18,
}
})
</script>
</body>
</html>
- 效果图
5.3 事件绑定指令
- 语法
v-on:事件名称="事件处理函数"
-
绑定到元素的开始标签中
-
常见的绑定事件
- v-on:click
- v-on:input
- v-on:keyup
-
v-on:的简写形式
@代替
- 事件处理函数
写在vue实例的methods方法中
其中的方法的this指向为vue实例对象(bind绑定)
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- vue要渲染的区域 -->
<div class="box">
<p>count的值为{{count}}</p>
<!-- count+1按钮 -->
<!-- 可以传入参数 -->
<button v-on:click="add(2)">+1</button>
<!-- count-1按钮 -->
<button @click="sub(2)">-1</button>
</div>
<!-- 引入vue.js文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 定义自己的js,使用vue创建一个实例 -->
<script>
const vm = new Vue({
el: '.box',
data: {
username: 'zhangsna',
count: 0
},
// methods对象 ,存储的是事件处理函数
methods: {
// 这里的this指向为vue实例对象
/**
*
* 原理是使用了js中的bind函数绑定的
* 如果通常理解是函数的调用者
* 因为使用了bind函数绑定(源码查看)
*/
add: function(n) {
this.count += n
},
sub: function(n) {
this.count -= n;
}
}
})
</script>
</body>
</html>
- 效果图
5.3.2 事件参数对象($event)
- Vue的内置对象
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="box">
<p>count的值为:{{count}}</p>
<!-- $event为Vue的一个内置对象 -->
<button @click="add(1,$event)">+1</button>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '.box',
data: {
count: 0,
},
methods: {
// 函数的简写形式
add(n, e) {
this.count += n;
console.log(e.target);
// 修改按钮的背景颜色
if (this.count % 2 == 0) {
e.target.style.backgroundColor = 'red';
} else {
e.target.style.backgroundColor = '';
}
}
}
})
</script>
</body>
</html>
- 效果图
5.3.3 事件修饰符
- 对事件的触发进行控制
事件修饰符 | 说明 |
---|---|
.prevent | 阻止默认行为 |
.stop | 阻止事件冒泡 |
.capture | 以捕获方式的事件处理函数 |
.once | 绑定的事件只触发一次 |
.self | 只有在event.target是当前元素自身时触发事件处理函数 |
- 在事件名称后添加
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.father {
width: 100px;
height: 100px;
background-color: skyblue;
}
.son {
width: 50px;
height: 50px;
background-color: pink;
}
</style>
</head>
<body>
<!-- vue要渲染的区域 -->
<div class="box">
{{username}}
<!-- 要跳转的a链接 -->
<!-- 使用事件修饰符来阻止默认行为 -->
<a href="www.baidu.com" @click.prevent="show">跳转到百度首页</a>
<!-- 阻止事件的冒泡 -->
<div class="father" @click="fatherShow">
<div class="son" @click.stop="sonShow">
</div>
</div>
</div>
<!-- 引入vue.js文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 定义自己的js,使用vue创建一个实例 -->
<script>
const vm = new Vue({
el: '.box',
data: {
username: 'zhangsna'
},
methods: {
show() {
console.log('阻止了a链接的跳转行为');
},
sonShow() {
console.log('son');
},
fatherShow() {
console.log('father');
}
}
})
</script>
</body>
</html>
- 效果图
5.3.4 按键修饰符
- 用于判读详细的按键,为键盘相关的事件添加按键修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- vue要渲染的区域 -->
<div class="box">
<!-- 绑定按键事件和按键修饰符 -->
<!-- esc键按下清空输入框的内容 -->
<!-- enter键按下发起Ajax请求 -->
<input type="text" @keyup.esc="clearVal" @keyup.enter="commit">
</div>
<!-- 引入vue.js文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 定义自己的js,使用vue创建一个实例 -->
<script>
const vm = new Vue({
el: '.box',
data: {
username: 'zhangsna'
},
methods: {
clearVal(e) {
// 清空输入框内容
console.log(e.keyCode);
e.target.value = '';
},
commit(e) {
console.log(e.keyCode);
console.log('发起ajax请求');
}
}
})
</script>
</body>
</html>
- 效果图
5.4 双向绑定指令
- 使用v-model双向绑定指令,在不操作DOM的情况下,快速获取表单的数据
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- vue要渲染的区域 -->
<div class="box">
<!-- 普通元素单向数据 -->
<p>{{username}}</p>
<!-- 表单元素设置v-model来进行双向绑定 -->
<!-- 将表单的value值与username的值进行了双向绑定 -->
<input type="text" v-model="username">
<!-- 与v-bind的区别,v-bind为单向数据绑定 -->
<input type="text" :value="username">
<!-- 普通元素不能进行双向绑定,无法操作value值 -->
<div v-model="username"></div>
<!-- select标签的 的双向绑定 -->
<select v-model="city">
<option value="0">请选择</option>
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">广州</option>
</select>
</div>
<!-- 引入vue.js文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 定义自己的js,使用vue创建一个实例 -->
<script>
const vm = new Vue({
el: '.box',
data: {
username: 'zhangsna',
// select的双向绑定
city: 0
}
})
</script>
</body>
</html>
- 效果图
5.4.2 v-model指令的修饰符
- 方便对用户输入的内容进行处理
修饰符 | 作用 | 示例 |
---|---|---|
.number | 自动将用户的输入值转为数值类型 | <input v-model.number="age" /> |
.trim | 自动过滤用户输入的首位空白字符 | <input v-model.trim="msg" /> |
.lazy | 在"change"时而非"input"时更新,用户输入完后再同步 | <input v-model.lazy="msg" /> |
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- vue要渲染的区域 -->
<div class="box">
<!-- 将用户输入转换为数值型 -->
<input type="text" v-model.number="n1"> +<input type="text" v-model.number="n2"> = {{n1+n2}}
<hr>
<!-- 将用户输入的首尾字符给去除 -->
<input type="text" v-model.trim="username">
<button @click="showName">获取用户名</button>
<hr>
<!--对用户的输入进行懒同步,用户输入完毕再同步 -->
<input type="text" v-model.lazy="msg">
</div>
<!-- 引入vue.js文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 定义自己的js,使用vue创建一个实例 -->
<script>
const vm = new Vue({
el: '.box',
data: {
username: 'zhangsna',
n1: 1,
n2: 2,
msg: "hello world"
},
methods: {
showName() {
console.log(`用户名为:"${this.username}"`);
}
}
})
</script>
</body>
</html>
- 效果图
5.5 条件渲染指令
- v-if
- 动态的添加和移除DOM元素,从而控制元素再页面上的显示和隐藏
- 当某个元素默认不需要显示,并且在后期很可能也不需要显示的情况使用
- v-show
- 添加和移除style的display属性,从而控制元素的显示与隐藏
- 适用于频繁显示与隐藏元素
v-show 和 v-if 绑定的值为true时显示,为false隐藏
- 示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- vue要渲染的区域 -->
<div class="box">
<p v-if="flag">v-if控制的元素</p>
<p v-show="flag">v-show控制的元素</p>
</div>
<!-- 引入vue.js文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 定义自己的js,使用vue创建一个实例 -->
<script>
const vm = new Vue({
el: '.box',
data: {
username: 'zhangsna',
flag: true
}
})
</script>
</body>
</html>
- 效果图
- v-else
- 配合v-if使用,实现条件渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- vue要渲染的区域 -->
<div class="box">
<!-- 使用v-else实现添加渲染 -->
<!-- 根据type的值按需渲染 -->
<div v-if="type==='A'">优秀</div>
<div v-else-if="type==='B'">良好</div>
<div v-else-if="type==='C'">及格</div>
<div v-else>差</div>
</div>
<!-- 引入vue.js文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 定义自己的js,使用vue创建一个实例 -->
<script>
const vm = new Vue({
el: '.box',
data: {
username: 'zhangsna',
type: "A"
}
})
</script>
</body>
</html>
- 效果图
5.6 循环渲染指令
- v-for指令
基于一个数组来循环渲染一个列表结构,语法:item in items
- item:数组中的每一项
- items:被循环的数组
6.品牌列表案例
- 实现品牌的查看
- 品牌的添加
- 品牌的删除
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>品牌列表案例</title>
<link rel="stylesheet" href="./lib/bootstrap.css">
<link rel="stylesheet" href="./css/brandlist.css">
</head>
<body>
<div id="app">
<!-- 卡片区域 -->
<div class="card">
<div class="card-header">
添加品牌
</div>
<div class="card-body">
<!-- 添加品牌的表单区域 -->
<form @submit.prevent="add">
<div class="form-row align-items-center">
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">品牌名称</div>
</div>
<input type="text" class="form-control" placeholder="请输入品牌名称" v-model.trim="brand">
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary mb-2">添加</button>
</div>
</div>
</form>
</div>
</div>
<!-- 表格区域 -->
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">品牌名称</th>
<th scope="col">状态</th>
<th scope="col">创建时间</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in list" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>
<!-- 状态款,复选框 -->
<div class="custom-control custom-switch">
<!-- 单机按钮可以改变状态 -->
<input type="checkbox" class="custom-control-input" :id="'customSwitch'+item.id" v-model="item.status">
<!-- 按需显示已启用还是已经禁用 -->
<label class="custom-control-label" :for="'customSwitch'+item.id" v-if="item.status">已启用</label>
<label class="custom-control-label" :for="'customSwitch'+item.id" v-else>已禁用</label>
</div>
</td>
<td>{{item.time}}</td>
<td>
<!-- 实现删除的事件绑定 -->
<a href="javascript:;" @click="del(item.id)">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 导入vue.js文件 -->
<script src="./lib/vue-2.6.12.js"></script>
<script>
// 创建一个vue的实例
const vm = new Vue({
el: '#app',
data: {
brand: '',
nextId: 4,
list: [{
id: 1,
name: '宝马',
status: true,
time: new Date()
}, {
id: 2,
name: '奔驰',
status: true,
time: new Date()
}, {
id: 3,
name: '奥迪',
status: true,
time: new Date()
}, ]
},
methods: {
del(id) {
// 使用filter过滤器实现删除,保留不为当前id的数组元素
this.list = this.list.filter(function(value) {
return value.id !== id
})
},
add() {
// 创建一个对象
var obj = {
id: this.nextId,
name: this.brand,
status: true,
time: new Date()
}
// push对象到list
this.list.push(obj);
this.nextId++;
this.brand = '';
}
}
})
</script>
</body>
</html>
- 效果图