文章目录
一、什么是Vue
- 构建用户界面
- 用vue往html页面中填充数据,非常的方便
- 框架
- 框架是一套现成的解决方案,程序员只能遵守框架的规范,去编写自己的业务功能!
- vue 的指令、组件(是对 UI 结构的复用)、路由、Vuex、vue 组件库
二、Vue的两个特性
- 数据驱动视图
- 数据的变化会驱动视图自动更新
- 好处:程序员只管把数据维护好,拿吗页面结构会被vue自动渲染出来!
- 双向数据绑定:
在网页中,from表单负责采集数据,Ajax负责提交数据。
- js数据的变化,会自动渲染到页面上
- 页面上表单采集的数据发生变化的时候,会被vue自动获取到,并更新到js数据中
注意
数据驱动视图和数据双向绑定的底层原理是MVVM(Mode数据源、View视图、ViewMode就是vue的实例)
三、Vue的基本使用
1. 基本使用步骤
- 导入vue.js的script脚本文件
- 在页面中声明一个将要被vue所控制的DOM区域
- 创建vm实例对象(vue实例对象)
<body>
<!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 -->
<div id="app">{{ username }}</div>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
username: 'zhangsan'
}
})
</script>
</body>
四、Vue指令
1. 内容渲染指令
v-text
指令的缺点:会覆盖元素内部原有的内容!<!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 --> <div id="app"> <p v-text="username"></p> <p v-text="gender">性别:</p> </div> <!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 --> <script src="./lib/vue-2.6.12.js"></script> <!-- 2. 创建 Vue 的实例对象 --> <script> // 创建 Vue 的实例对象 const vm = new Vue({ // el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器 el: '#app', // data 对象就是要渲染到页面上的数据 data: { username: 'zhangsan', gender: '女', } }) </script>
{{ }}
插值表达式:在实际开发中用到最多,只是内容的占位符,不会覆盖原有的内容!<!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 --> <div id="app"> <p>姓名:{{ username }}</p> <p>性别:{{ gender }}</p> </div> <!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 --> <script src="./lib/vue-2.6.12.js"></script> <!-- 2. 创建 Vue 的实例对象 --> <script> // 创建 Vue 的实例对象 const vm = new Vue({ // el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器 el: '#app', // data 对象就是要渲染到页面上的数据 data: { username: 'zhangsan', gender: '女', } }) </script>
v-html
指令的作用:可以把带有标签是字符串,渲染成真正的HTML内容!<!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 --> <div id="app"> <div v-html="info"></div> </div> <!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 --> <script src="./lib/vue-2.6.12.js"></script> <!-- 2. 创建 Vue 的实例对象 --> <script> // 创建 Vue 的实例对象 const vm = new Vue({ // el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器 el: '#app', // data 对象就是要渲染到页面上的数据 data: { info: '<h4 style="color: red; font-weight: bold;">欢迎大家来学习 vue.js</h4>' } }) </script>
2.属性绑定指令
注意
插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中!
- 在vue中,可以使用
v-bind:
指令,为元素的属性动态绑定值; - 简写是英文的
:
- 在使用
v-bind:
属性绑定期间,如果绑定内容需要进行动拼接,则字符串的外面应该包裹单引号,例如:<div :title="'box' + index">这是一个 div</div>
3.事件绑定
v-on:
简写是@
- 语法格式为:
<button @click="add"></button> //vue实例对象中新建methods节点 methods: { add() { // 如果在方法中要修改 data 中的数据,可以通过 this 访问到 this.count += 1 } }
3.1事件参数对象
$event
是 vue 提供的特殊变量,用来表示原生的事件参数对象 event。$event 可以解决事件参数对象 event 被覆盖的问题。示例用法如下:
<button @click="add(3, $event)"></button>
methods: {
add(n, e) {
// 如果在方法中要修改 data 中的数据,可以通过 this 访问到
this.count += 1
}
}
3.2事件修饰符
在事件处理函数中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。因此,vue 提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发进行控制。常用的 5 个事件修饰符如下:
事件修饰符 | 说明 |
---|---|
.prevent | 阻止默认行为 (例如:阻止 a 链接跳转、阻止表单提交) |
.stop | 阻止事件冒泡 |
.capture | 以捕获模式触发当前的事件处理函数 |
.once | 事件只触发1次 |
.self | 只有在event.terget是当前元素自身时触发事件处理函数 |
例如
.prevent
<a @click.prevent="xxx">链接</a>
.stop
<button @click.stop="xxx">按钮</button>
按键修饰符
在监听键盘事件
时,我们经常需要判断详细的按键
。此时,可以为键盘相关的事件
添加按键修饰符
,例如:
<input type="text" @keyup.esc="clearInput" @keyup.enter="commitAjax">
4.双向绑定指令
vue 提供了 v-model 双向数据绑定
指令,用来辅助开发者在不操作 DOM
的前提下,快速获取表单的数据
。
v-model指令
- input输入框
- type=‘radio’
- type=‘checkbox’
- type=‘xxxx’
- textarea
- select
4.1 v-model 指令的修饰符
修饰符 | 作用 | 示例 |
---|---|---|
.number | 自动将用户的输入值转为数值类型 | <input v-model.number="age" /> |
.trim | 自动过滤用户输入的首尾空白字符 | <input v-model.trim="msg" /> |
.lazy | 在输入时不会实时更新,输入完失去焦点时更新 | <input v-model.lazy="msg" /> |
5.条件渲染指令
v-if
v-show
- v-else (注意:v-else 指令必须配合 v-if 指令一起使用,否则它将不会被识别!)
- v-else-if (注意:v-else-if 指令必须配合 v-if 指令一起使用,否则它将不会被识别!)
v-show
的原理是:动态为元素添加或移除display: none
样式,来实现元素的显示和隐藏- 如果要频繁的切换元素的显示状态,用 v-show 性能会更好
v-if
的原理是:每次动态创建或移除元素
,实现元素的显示和隐藏- 如果刚进入页面的时候,某些元素默认不需要被展示,而且后期这个元素很可能也不需要被展示出来,此时 v-if 性能更好
在实际开发中,绝大多数情况,不用考虑性能问题,直接使用 v-if 就好了!!!
v-if 指令在使用的时候,有两种方式:
- 直接给定一个布尔值 true 或 false
<p v-if="true">被 v-if 控制的元素</p>
- 给 v-if 提供一个判断条件,根据判断的结果是 true 或 false,来控制元素的显示和隐藏
<p v-if="type === 'A'">良好</p>
6.列表渲染指令
vue 提供了 v-for
列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构
。v-for 指令需要使用item in items
形式的特殊语法,其中:
- item 是被循环的每一项
- items 是待循环的数组
v-for 中的索引
v-for
指令还支持一个可选的第二个参数,即当前项的索引。语法格式为 (item, index) in items
注意:v-for
指令中的 item
项和index
索引都是形参,可以根据需要进行重命名。例如 (user, i) in userlist
使用 key 维护列表的状态
当列表的数据变化
时,默认情况下,vue 会·尽可能的复用·已存在的 DOM 元素,从而提升渲染的性能
。但这种默认的性能优化策略,会导致有状态的列表无法被正确更新
。
为了给 vue 一个提示,以便它能跟踪每个节点的身份,从而在保证有状态的列表被正确更新
的前提下,提升渲染的性能
。此时,需要为每项提供一个唯一的 key 属性
<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 的值类型,是有要求的:字符串或数字类型 -->
<!-- key 的值是千万不能重复的,否则会终端报错:Duplicate keys detected -->
<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>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
list: [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
{ id: 3, name: '王五' },
{ id: 4, name: '张三' },
]
}
})
</script>
七、过滤器
1.过滤器
过滤器(Filters)
是 vue 为开发者提供的功能,常用于文本的格式化
。过滤器可以用在两个地方:插值表达式
和 v-bind 属性绑定
。
过滤器应该被添加在 JavaScript 表达式的尾部
,由“管道符
”进行调用,示例代码如下:
<!-- 在双花括号中通过“管道符”调用 capitalize 过滤器,对 message 的值进行格式化 -->
<p>{{ message | capitalize }}</p>
<!-- 在 v-bind 中通过“管道符”调用formatId 过滤器,对 rawId 的值进行格式化 -->
<div v-bind:id="rawId | formatId"></div>
2. 定义过滤器
2.1 私有过滤器
在创建 vue 实例期间,可以在 filters 节点
中定义私有过滤器,只能在当前 vm 实例
所控制的 el
区域内使用,示例代码如下:
<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 vue.js'
},
// 过滤器函数,必须被定义到 filters 节点之下
// 过滤器本质上是函数
filters: {
// 注意:过滤器函数形参中的 val,永远都是“管道符”前面的那个值
capi(val) {
// 字符串有 charAt 方法,这个方法接收索引值,表示从字符串中把索引对应的字符,获取出来
// val.charAt(0)
const first = val.charAt(0).toUpperCase()
// 字符串的 slice 方法,可以截取字符串,从指定索引往后截取
const other = val.slice(1)
// 强调:过滤器中,一定要有一个返回值
return first + other
}
}
})
</script>
</body>
2.2 全局过滤器
多个 vue 实例之间共享过滤器
,则可以按照如下的格式定义全局过滤器
:
// 使用 Vue.filter() 定义全局过滤器
Vue.filter('capi', function (str) {
const first = str.charAt(0).toUpperCase()
const other = str.slice(1)
return first + other
})
//在vue实例前定义全局过滤器
const vm = new Vue({
XXXX
})
过滤器的注意点
- 要定义到 filters 节点下,本质是一个函数
- 在过滤器函数中,一定要有 return 值
- 在过滤器的形参中,可以获取到“管道符”前面待处理的那个值
- 如果全局过滤器和私有过滤器名字一致,此时按照“就近原则”,调用的是”私有过滤器“
在企业级项目开发中:
- 如果使用的是 2.x 版本的 vue,则依然可以使用过滤器相关的功能
- 如果项目已经升级到了 3.x 版本的 vue,官方建议使用
计算属性
或方法
代替被剔除的过滤器功能
八、侦听器
1.什么是watch侦听器
watch 侦听器
允许开发者监视数据的变化,从而针对数据的变化做特定的操作
。
语法格式如下:
const vm = new Vue({
el: '#app',
data: {
username: ''
},
// 所有的侦听器,都应该被定义到 watch 节点下
watch: {
// 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
// 新值在前,旧值在后
username(newVal, oldVal) {
console.log(newVal, oldVal)
}
}
})
2.immediate
默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用
,则需要使用 immediate
选项。示例代码如下:
watch: {
username: {
// handler 是固定写法,表示当 username 的值变化时,自动调用 handler 处理函数
handler: async function (newVal) {
if (newVal === '') return
const { data: res } = await axios.get('https://www.escook.cn/api/finduser/' + newVal)
console.log(res)
},
// 表示页面初次渲染好之后,就立即触发当前的 watch 侦听器
immediate: true
}
}
3.deep选项
如果 watch 侦听的是一个对象
,如果对象中的属性值发生了变化
,则无法被监听到
。此时需要使用 deep 选项
,代码示例如下:
const vm = new Vue({
el: '#app',
data: {
// 用户的信息对象
info: {
username: 'admin',
address: {
city: '北京'
}
}
},
// 所有的侦听器,都应该被定义到 watch 节点下
watch: {
/* info: {
handler(newVal) {
console.log(newVal)
},
// 开启深度监听,只要对象中任何一个属性变化了,都会触发“对象的侦听器”
deep: true
} */
// 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
'info.username'(newVal) {
console.log(newVal)
}
}
})
九、计算属性
1. 什么是计算属性
计算属性指的是通过一系列运算
之后,最终得到一个属性值
。
这个动态计算出来的属性值
可以被模板结构
或 methods 方法
使用。示例代码如下:
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
// 红色
r: 0,
// 绿色
g: 0,
// 蓝色
b: 0
},
computed: {
// rgb 作为一个计算属性,被定义成了方法格式,
// 最终,在这个方法中,要返回一个生成好的 rgb(x,x,x) 的字符串
rgb() {
return `rgb(${this.r}, ${this.g}, ${this.b})`
}
},
methods: {
// 点击按钮,在终端显示最新的颜色
show() {
console.log(this.rgb)
}
},
});
2. 计算属性的特点
- 虽然计算属性在
声明的时候
被定义为方法
,但是计算属性的本质是一个属性
- 计算属性会缓存
计算的结果
,只有计算属性依赖的数据变化时
,才会重新进行运算