目录
1. vue简介
vue是构建用户界面的框架。往html页面里面填充数据,一套现成的解决方案。
1)vue的特性
- 数据驱动视图
- 双向数据绑定
1⃣️数据驱动视图
在使用了vue的页面中,vue会监听数据的变化,从而自动重新渲染页面的结构。示意图如下:
- 数据的变化会驱动视图自动更新
- 程序员只需要把数据维护好,那么页面结构会被vue自动渲染出来
2⃣️双向数据绑定
在填写表单时,双向数据绑定可以辅助开发者在不操作DOM地前提下,自动把用户填写的内容同步到数据源中。示意图如下:
- 在网页中,form表单负责采集数据,Ajax负责提交数据
- js数据的变化,会被自动渲染到页面上
- 页面上表单采集的数据发生变化的时候,会被vue自动获取到并更新到js数据中
2)MVVM
MVVM是vue实现数据驱动视图和双向数据绑定的核心原理。MVVM指的是Model、View和ViewModel,它把每个HTML页面都拆分成了这三个部分,如图所示:
3)MVVM的工作原理
ViewModel作为MVVM的核心,是它把当前页面的数据源(Model)和页面的结构(View)连接到了一起。
- 当数据源发生变化时,会被ViewModel监听到,VM会根据最新的数据源自动更新页面的结构
- 当表单元素的值发生变化时,也会被VM监听到,VM会把变化过后最新的值自动同步到Model数据源中
2. vue的基本使用
1)基本使用步骤
- 导入vue.js的script脚本文件
- 在页面中声明一个将要被vue所控制的DOM区域
- 创建vm实例对象,即vue实例对象
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">{{ username }}</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
username: 'zs'
}
})
</script>
</body>
结果为:
2)基本代码与MVVM的对应关系
3. vue的调试工具
4. vue的指令
1)指令的概念
指令是vue为开发者提供的模版语法,用于辅助开发者渲染页面的基本结构。
vue中的指令按照不同的用途可以分为如下6大类:
- 内容渲染指令
- 属性绑定指令
- 事件绑定指令
- 双向绑定指令
- 条件渲染指令
- 列表渲染指令
2)内容渲染指令
用来辅助开发者渲染DOM元素的文本内容。常用的内容渲染指令有3个:
- v-text:只能渲染文本内容,会覆盖元素内部原有的内容
- {{ }}:插值表达式(Mustache),只能渲染文本内容,会保留元素自身的默认值
- v-html:可以把包含HTML标签的字符串渲染为页面的HTML元素
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<!-- 把username对应的值渲染到p标签中 -->
<p v-text="username"></p>
<!-- 把gender对应的值渲染到标签中 -->
<!-- 默认中的文本“性别”会被gender的值覆盖掉 -->
<p v-text="gender">性别:</p>
<hr>
<!-- {{}}:插值表达式,将对应的值渲染到元素的内容节点中,同时保留元素自身的默认值 -->
<p>姓名:{{ username }}</p>
<p>性别:{{ gender }}</p>
<hr>
<div v-text="info"></div>
<div>{{ info }}</div>
<!-- v-html:可以把包含HTML标签的字符串渲染为页面的HTML元素 -->
<div v-html="info"></div>
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
username: 'zs',
gender: '男',
info: '<h4 style="color:red; font-weight:bold;" >欢迎光临</h4>'
}
})
</script>
</body>
结果为:
3)属性绑定指令
如果需要为元素的属性动态绑定属性值,则需要用到v-bind属性绑定指令。
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<!-- v-bind:属性绑定指令 -->
<input type="text" v-bind:placeholder="tips">
<hr>
<img v-bind:src="pic" alt="" style="height: 50px;">
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
tips: '请输入内容',
pic: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
}
})
</script>
</body>
结果为:
使用JavaScript表达式
在vue提供的模版渲染语法中,除了支持绑定简单的数据只之外,还支持javaScript表达式的运算
4)事件绑定指令
vue提供了v-on事件绑定指令,用来辅助程序员为DOM元素绑定事件监听。
注意:原生DOM对象有onclick、oninput、obkeyup等原生事件,替换为vue的事件绑定形式后,分别为:v-on:click、v-on:input、v-on:keyup
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<h3>count的值为:{{ count }}</h3>
<!-- 在绑定事件处理函数的时候,可以用()传参 -->
<button v-on:click="add(1)">+1</button>
<button v-on:click="sub(1)">-1</button>
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
count: 0
},
//methods:定义事件的处理函数
methods: {
// add: function() {}
add(n) {
// console.log(vm);
// vm.count++;
console.log(vm == this);
this.count += n;
},
sub(n) {
// vm.count--;
this.count -= n;
}
}
})
</script>
</body>
结果为:
1⃣️事件对象$event
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<h3>count的值为:{{ count }}</h3>
<!-- $event:vue提供的内置变量, 是原生DOM的事件对象e -->
<button v-on:click="add(1, $event)">+1</button>
<button v-on:click="sub(1, $event)">-1</button>
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
count: 0
},
methods: {
add(n, e) {
// e.target:button
console.log(e);
this.count += n;
if(this.count %2 == 0) {
e.target.style.backgroundColor = "red";
}
else {
e.target.style.backgroundColor = "";
}
},
sub(n, e) {
this.count -= n;
if(this.count %2 == 0) {
e.target.style.backgroundColor = "red";
}
else {
e.target.style.backgroundColor = "";
}
}
}
})
</script>
</body>
结果为:
2⃣️事件修饰符
在事件处理函数中调用event.preventDefault()或者event.stopPropagation()是非常常见的需求。因此,vue提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发进行控制。
常见的5个事件修饰符:
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<!-- .prevent:阻止默认行为 -->
<a href="http://www.baidu.com" @click.prevent="show">跳转到百度页面</a>
<hr>
<div style="width: 200px; height: 200px; background-color: antiquewhite; " @click="div">
<!-- .stop:阻止事件冒泡 -->
<button @click.stop="btn">点击按钮</button>
</div>
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {},
methods: {
show() {
// 阻止默认行为
// e.preventDefault();
console.log("跳转到百度页面");
},
btn() {
// 阻止冒泡
// e.stopPropagation();
console.log('btn');
},
div() {
console.log('div');
}
}
})
</script>
</body>
结果为:
3⃣️按键修饰符
在监听键盘事件时,经常需要判断详细的按键,此时可以为键盘相关的事件添加按键修饰符。
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<input type="text" @keyup.enter="submit" @keyup.esc="clearInput($event)">
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {},
methods: {
submit() {
console.log('按下了enter键,调用了submit方法');
},
clearInput(e) {
console.log('按下了esc键,调用了clearInput方法');
e.target.value = '';
}
}
})
</script>
</body>
结果为:
5)双向绑定指令
vue提供了v-model双向数据绑定指令,用来辅助开发者在不操作DOM的前提下,快速获取表单的数据。input输入框、textarea、select等。
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
{{ username }}
<hr>
<!-- 表单数据更改的时候,data的值也跟着被修改 -->
<input type="text" v-model="username">
<hr>
<select v-model="city">
<option value="">请选择城市</option>
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">广州</option>
</select>
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
username: 'zs',
city: ''
}
})
</script>
</body>
结果为:
1⃣️v-model指令的修饰符
为了方便对用户输入的内容进行处理,vue为v-model指令提供了3个修饰符:
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<!-- 1. .number:自动将输入值转换为数字型 -->
<input type="text" v-model.number="n1">+<input type="text" v-model.number="n2">=<span>{{ n1+n2 }}</span>
<hr>
<!-- 2. .trim:自动过滤用户输入的首尾空白字符 -->
<input type="text" v-model.trim="username">
<button @click="show">获取用户名</button>
<hr>
<!-- 3. .lazy:光标离开input时候再更新值 -->
<input type="text" v-model.lazy="username">
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
username: 'zs',
n1: 1,
n2: 2
},
methods: {
show() {
console.log('用户名是' + this.username);
}
}
})
</script>
</body>
结果为:
6)条件渲染指令
用来辅助开发者按需控制DOM的显示与隐藏。条件渲染指令有:
- v-if:每次动态创建或移除元素,从而实现元素的显示与隐藏;如果刚进入页面的时候,某些元素默认不需要被展示,而且后期这个元素很可能不被展示出来,则用v-if性能更好
- v-show:动态为元素添加或移除 display:none 样式,来实现元素的显示与隐藏;如果频繁的切换元素的显示状态,用v-show性能会更好
在现实开发中,不用考虑性能问题,直接使用v-if
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<p v-if="flag">这是被 v-if 控制的元素</p>
<p v-show="flag">这是被 v-show 控制的元素</p>
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
flag: true
}
})
</script>
</body>
结果为:
1⃣️v-else-if
充当v-if的“else-if”块,可以连续使用。必须配合v-if指令一起使用,否则它将不会被识别。
<body>
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<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>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
flag: true,
type: "A"
}
})
</script>
</body>
结果为:
7)列表渲染指令
vue提供了v-for列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。v-for需要使用 item in items 形式的特殊语法,其中:
- items:待循环的数组
- item:被循环的每一项
v-for指令还支持一个可选的第二个参数,即当前的索引,语法格式为:(item,index)in items
<body>
<link rel="stylesheet" href="./lib/bootstrap.css">
<!-- 1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.在页面中声明一个将要被Vue控制的DOM区域 -->
<div id="app">
<table class="table table-bordered table-hover table-striped">
<thead>
<th>索引号</th>
<th>id</th>
<th>姓名</th>
</thead>
<tbody>
<!-- 只要用到了v-for指令,一定要绑定一个:key属性,而且尽量把id作为key的值 -->
<!-- 官方对key的值类型:必须是字符串或数字类型 -->
<tr v-for="(item, index) in list" :key="item.id">
<td>{{ index }}</td>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
</div>
<!-- 3.创建Vue的实例对象 -->
<script>
const vm = new Vue({
//el:表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
//data:要渲染到页面上的数据
data: {
list: [
{id: 1, name: 'zs'},
{id: 2, name: 'ls'},
{id: 3, name: 'ww'}
]
}
})
</script>
</body>
结果为:
1⃣️key的注意事项
- key的值只能是字符串或数字类型
- key的值必须具有唯一性,即:key的值不能重复
- 建议把数据项id属性的值作为key的值,因为id属性的值具有唯一性
- 使用index的值当作key的值没有任何意义,因为index的值不具有唯一性
- 建议使用v-for指令时一定要指定key的值,即提升性能,又防止列表状态紊乱
5. 过滤器
1)过滤器的基本使用
过滤器(Filters)是vue为开发者提供的功能,常用于文本的格式化。过滤器可以用在两个地方:插值表达式和v-bind属性绑定。
- 过滤器应该被添加在JavaScript表达式的尾部,由“管道符”进行调用。
- 要定义在filters节点下,本质是一个函数
- 在过滤器函数中,一定要有return值
- 在过滤器的形参中,可以获取到“管道符”前面待处理的那个值
<body>
<div id="app">
<p>message的值是:{{ message | capi }}</p>
</div>
<script src="lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
message: 'hello'
},
// 过滤器函数,必须被定义到filters节点之下,过滤器的本质是函数
filters: {
// 参数val实际上是管道符前面的那个值,即message的值
capi(val) {
// 将第一个字母转换成大写
const first = val.charAt(0).toUpperCase();
// 截取
const others = val.slice(1);
// 过滤器一定要有返回值
return first + others;
}
}
})
</script>
</body>
结果为:
2)私有过滤器和全局过滤器
在filters节点下定义的过滤器称为“私有过滤器”,因为它只能在当前vm实例所控制的el区域内使用。如果希望在多个vue实例之间共享过滤器,则可以按照如下的格式定义全局过滤器:
- 如果全局过滤器和私有过滤器名字一致,则按照就近原则,调用私有过滤器
<body>
<div id="app">
<p>message的值是:{{ message | capi }}</p>
</div>
<div id="app1">
<p>message的值是:{{ message | capi }}</p>
</div>
<script src="lib/vue-2.6.12.js"></script>
<script>
// 全局过滤器:独立于每个vm实例之外
Vue.filter('capi', function(str) {
const first = str.charAt(0).toUpperCase();
const others = str.slice(1);
// 过滤器一定要有返回值
return first + others + '---';
})
const vm = new Vue({
el: '#app',
data: {
message: 'hello'
},
// 过滤器函数,必须被定义到filters节点之下,过滤器的本质是函数
filters: {
// 参数val实际上是管道符前面的那个值,即message的值
capi(val) {
// 将第一个字母转换成大写
const first = val.charAt(0).toUpperCase();
// 截取
const others = val.slice(1);
// 过滤器一定要有返回值
return first + others;
}
}
})
const vm1 = new Vue({
el: '#app1',
data: {
message: 'helloworld'
}
})
</script>
</body>
结果为:
3)连续调用多个过滤器
过滤器可以串联的进行调用,例如:
4)过滤器传参
过滤器的本质是JavaScript函数,因此可以接收参数,格式如下: