初始vue(上)
初始vue(上)
dleei初识Vue
vue是什么?
在vue官网的简介是:用于 构建用户界面1 的 渐进式2 框架3
构建用户界面:基于数据动态渲染出用户看到的页面
渐进式:循序渐进逐步学习,使用
框架:一套完整的项目解决方案,可以极大地提高开发的效率
既然那么好用,让我们来盘一盘这个vue
vue中的MVVM
- M指的是model(模型),对应data中的数据。
- V指的是view(视图),一个展示用户界面的模板,可以简单的理解为HTML标签页面。
- MV指的是ViewModel(视图模层),它是Vue的实例对象,一个连接view和model的桥梁,负责把model对象封装成可以显示和接受输入的界面对象。
vue的基本使用
核心步骤(4步):
准备容器
引包(官网) — 开发版本/生产版本
创建Vue实例 new Vue()
指定配置项,渲染数据
- el:指定挂载点
- data提供数据
创建vue实例,初始化渲染
来到vue2的官网看看该如何使用
依照上面的顺序
1 | //准备容器 (Vue所管理的范围) |
这样的话data里面的数据就被渲染到页面上了
只能渲染由vue托管的区域,没有托管的区域不会动态渲染
插值表达式
数据绑定最常见的形式就是使用Mustache
语法 (小胡子语法) 的文本插值
作用:利用表达式进行插值,渲染到页面上
语法:{{ 表达式}}
<span>Message: {{ msg }}</span>
所谓的表达式,就是一段可以被求值的代码,js引擎会将其计算并最终得出一个结果
money + 100
money - 100
money * 10
money / 10
price >= 100 ? '真贵':'还行'
obj.name
arr[0]
fn()
obj.fn()
以上这些都是表达式
可以简单的直接渲染数据,既然支持表达式那么也可以往里面写一些复杂的计算表达式,就像这样
<h3>{{title}}<h3>
<p>{{nickName.toUpperCase()}}</p>
<p>{{age >= 18 ? '成年':'未成年'}}</p>
<p>{{obj.name}}</p>
<p>{{fn()}}</p>
当msg里面的数据发生变化的时候,对应页上的信息也会进行动态的渲染和更新
通过使用 v-once 指令
,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:
<span v-once>这个将不会改变: {{ msg }}</span>
注意:
数据必须存在
插值表达式,只能支持表达式,而非语句: if ,for…
不能够在标签中使用
响应式特性
当data里面的数据发生变化的时候,对应页上的信息也会进行动态的渲染和更新
data中的数据, 最终会被添加到实例上
① 访问数据: “实例.属性名”
② 修改数据: “实例.属性名”= “值”
vue指令
v-html
作用:设置元素的innerHTML
语法: v-html = 表达式
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html
指令
<div id="app">
<div v-html="msg"></div>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
msg: '<h1>燕子,你别走!!!没了你我可怎么活啊!</h1>'
}
})
</script>
v-if
v-if 底层原理:通过创建 / 删除 dom 元素来实现盒子的显示隐藏,当表达式的值为 true 时就显示,为 false 时就隐藏
适用于初始状态
就决定了显示隐藏的场景
v-show
v-show 底层原理: 通过设置 display:none
,来改变盒子的显示隐藏
当表达式的值为 true 时就显示,为 false 时就隐藏
适用于频繁切换
显示隐藏的场景
v-else ,v-else-if
- 作用:辅助v-if进行判断渲染
- 语法:v-else v-else-if=”表达式”
- 需要紧接着v-if使用
<div id="app">
<p v-if="gender===0">性别:♂ 男</p>
<p v-else>性别:♀ 女</p>
<hr>
<p v-if="score>=90">成绩评定A:奖励电脑一台</p>
<p v-else-if="score>=70">成绩评定B:奖励周末郊游</p>
<p v-else-if="score>=60">成绩评定C:奖励零食礼包</p>
<p v-else>成绩评定D:惩罚一周不能玩手机</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script>
// 目标:
// 1. 根据条件渲染姓名
// 2. 根据成绩来渲染奖励
const app = new Vue({
el: '#app',
data: {
gender: 0,
score: 95
}
})
</script>
v-on
作用: 注册事件 = 添加监听 + 处理逻辑
语法:
- v-on :事件名 = “内联语句”
- v-on: 事件名 = “methods中的函数名”
简写形式
@事件名
<div id="app">
<button @click={{count--}}>-</button>
<span>{{ count }}</span>
<button @click={{count++}}>+</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script>
// 目标: 点击 - 让数字减一, 点击 + 让数字加一
const app = new Vue({
el: '#app',
data: {
count: 100
}
})
</script>
methods 中存放函数
只要是定义在 methods 中的函数,最终都会放到实例对象上,所以内部的 this 指向实例对象
1 | <div id="app"> |
v-on调用传参
1 | <div id="app"> |
v-bind
作用:动态设置标签的属性值
语法: v-bind:属性名=”表达式”
简写:
:属性名 = “表达式”
以下是一些常见的HTML标签属性
1.src 属性(用于图像、音频、视频等):
<img :src="imageSource">
<audio :src="audioSource"></audio>
<video :src="videoSource"></video>
2.href 属性(用于链接):
<a :href="externalLink">Visit Website</a>
3.title 和 alt 属性(用于提示信息):
<img :title="imageTitle" :alt="imageAlt" src="imageSource">
4.disabled 属性(用于禁用表单元素):
<button :disabled="isDisabled">Submit</button>
5.placeholder 属性(用于表单元素的占位符文本):
<input :placeholder="inputPlaceholder">
6.value 属性(用于表单元素的值):
<input :value="inputValue">
7.readonly 属性(用于设置表单元素为只读):
<input :readonly="isReadOnly">
8.checked 属性(用于复选框和单选按钮):
<input type="checkbox" :checked="isChecked">
<input type="radio" :checked="isSelected">
9.data-属性(用于存储自定义数据):
<div :data-custom-value="customData"></div>
1 | <div id="app"> |
v-bind 操作 class 类名
语法 :class =”{对象}”
设置对象使用布尔值控制是否使用这个类名,比较常用动态设置类名
1 | <div id="app"> |
语法 :class=”[数组]”
使用数组一次性设置多个类名,或删除多个类名
1 | <div id="app"> |
v-bind 操作 style 类名
语法 :style = “{ 样式属性 }”
1 | <div id="app"> |
v-for
作用:基于数组循环,多次整个渲染整个元素
语法: v-for =”(item,index) in list”
- item 是数组中的每一项
- index 是每一项对应的索引,不需要可以省略
- list是被遍历的数组
1 | const app = new Vue({ |
key属性
当使用 v-for
来渲染一个列表时,Vue 需要一个唯一的 key
值来追踪每个循环项。这有助于 Vue 在更新列表时识别出哪些项被添加、删除或移动了,从而提供更快速的 DOM 更新以及更精准的变化追踪。
1 | <template> |
v-modal
作用:双向数据绑定,快速获取或设置表单元素内容
什么是双向数据绑定?
Vue是一个MV VM框架, 即数据双向绑定, 即当数据发生变化的时候, 视图也就发生变化, 当视图发生变化的时候,数据也会跟着同步变化。这也算是Vue的精髓之处了。
v-model 会根据控件类型自动选取正确的方法来更新元素。
1 | <div id="app"> |
复选框的数据绑定
复选框如果是一个为逻辑值
1 | <!DOCTYPE html> |
如果是多个则绑定到同一个数组,会把选中的选项里面的 value 值,添加到数组中
1 | <!DOCTYPE html> |
单选框的数据绑定
1 | <div id="app"> |
下拉菜单的数据绑定
1 | <div id="app"> |
指令修饰符
1.v-model修饰符
.lazy
在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步:
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >
.number
如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值:
<input v-model.number="age" type="number">
.trim
如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入:
<input v-model.trim="msg">
2.按键修饰符
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">
记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:
<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
全部的按键别名:
.enter
.tab
.delete
(捕获 “删除” 和 “退格” 键).esc
.space
.up
.down
.left
.right
系统修饰键:
.ctrl
.alt
.shift
.meta
鼠标按钮修饰符:
.left
.right
.middle
3.事件修饰符
Vue 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。
Vue 通过由点 . 表示的指令后缀来调用修饰符。
.stop
- 阻止冒泡.prevent
- 阻止默认事件.capture
- 阻止捕获.self
- 只监听触发该元素的事件.once
- 只触发一次.left
- 左键事件.right
- 右键事件.middle
- 中间滚轮事件
1 | <!-- 阻止单击事件冒泡 --> |
计算属性 computed
计算属性,字如其名,首先它是属性,其次有计算的“功能”
说的官方一点:计算属性就是当其依赖属性的值发生变化时,这个属性的值会自动变化,与之相关的DOM部分也会同步自动更新。
在computed配置项中添加我们的计算属性,在属性里面写我们的逻辑代码
注意:计算属性其实是属性,在页面上使用只需要用属性值,不要带(),不然就变成方法了
1 | <div id="app"> |
计算属性computed
和methods
的区别
computed是一个方法,而methods里面也是一个方法,那么他们之间的区别是什么呢?
我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
我们可以通过多次调用,打印出来看看结果有什么不一样
1 | <div id="app"> |
可以清晰地看到,用methods方法数据每更新一次就会被调用一次,而computed方法只被调用了一次
优点:计算属性最重要的特性: 带缓存
在第一次使用了该属性时进行计算,计算完了后他就会把结果存起来,后面有用到会直接在缓存里面把结果取出来
只在相关响应式依赖发生改变(相关的属性变化)时它们才会重新求值
这样做的主要目的也是为了提高性能
计算属性的完整写法
计算属性都包含有一个get和一个set,计算属性会默认使用 get函数,如果你要使用 set函数,那么你必须要手动写出 set 函数
1 | const app = new Vue({ |
watch侦听器
作用:监视数据变化,执行业务逻辑或是异步操作
1 | const app = new Vue({ |
完整写法:
deep: true
对复杂类型深度监视immediate: true
初始化立刻执行一次handler方法
1 | watch: {// watch 完整写法 |
生命周期
一个Vue实例从 创建 到 销毁 的整个过程
vue的生命周期分为四个阶段:
①创建 ②挂载 ③更新 ④销毁
Vue生命周期过程中,会自动运行一些函数,被称为【生命周期钩子】
这个时候我们就可以在【特定阶段】运行自己的代码
- 实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载,只是一个空壳,无法访问到数据和真实的dom,一般不做操作
- 挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
- 接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
- 接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情…
- 当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿
- 当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom
- 当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等
- 组件的数据绑定、监听…去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以
生命周期图示
生命周期钩子 | 实例阶段 | 说明 | 能否获取到data | 能否获取到 methods |
---|---|---|---|---|
beforeCreate | 创建前 | 实例已初始化,但数据观测,watch/event 事件回调还未配置 | NO | NO |
created | 创建后 | 已完成如下配置,数据观测 (data observer),property 和方法的运算,watch/event 事件回调 | NO | OK |
beforeMount | 挂载前 | dom已初始化,但并未挂载和渲染 | OK | OK |
mounted | 挂载后 | dom已完成挂载和渲染 | OK | OK |
beforeUpdate | 更新前 | 数据已改变,但dom为更新 | OK | OK |
updated | 更新后 | dom已更新 | OK | OK |
beforeDestroy | 销毁前 | 实例销毁前,实例仍然可用 | OK | OK |
destroyed | 销毁后 | 实例已销毁,所有指令被解绑,事件监听器被移除,子实例都被销毁 | OK | OK |