Vue2.0 + Vue3.0 ⭐️
1. Vue的核心
1.1 Vue简介
1.1.1 什么是Vue?
-
Vue 作者尤雨溪根据其他框架所创造出来的新前端c框架
-
.vue是Vue打造的全新文件 包括了html + css + js 所有的文件
1.1.2 Vue有哪些特点?
- Vue采用组件化模式,提高代码的复用率,且让代码更好的维护
- 由于一个vue组件包括html + css + js全部文件,所以一个组件包括了所有其他组件,当进行修改的时候,不仅能提高代码复用率,还能更好的维护代码
- 声明式编码 ,让编码人员无需直接操作DOM,提高了开发效率
1.1.3 VScode中Vue的插件推荐
Vue 3 Snippets
-> 简化代码 提高效率
1.2 安装Vue
在Vue官网>中下载Vue的js文件,如果下载的是用于开发的js文件,并导入程序中之后打开页面控制台会有两个错误
- 解决第一个没有安装Vuetools的错误,在Github中找到[Vue Devtools](GitHub - vuejs/devtools)并添加该插件,然后修改浏览器插件中的开发者模式为开启状态,这里演示的是Edge浏览器
- 解决第二个提示当前js为开发的消息,只需要在修改vue的配置文件即可
<script type="text/javascript">
Vue.config.productionTip = false; // 阻止vue在启动时发送提示
</script>
1.3 Vue的Hello World!
<div id="root">
<h1>hello, {{name}}</h1>
</div>
<script type="text/javascript">
// 创建Vue实例
new Vue({
el: '#root', // 获取元素对象并且指定作用域
data: {
name: 'Vue!'
}
});
Vue.config.productionTip = false; // 阻止vue在启动时发送提示
</script>
1.4 Vue 的语法规则
{{}}
符号中不仅仅可以存储实例化之后的键值对,它的本质就是能够存储js的表达式
js表达式和js代码的区别
- js表达式:
- 一个表达式会生成一个值,可以放在任何一个需要值的地方
- 形如:a、Date.now()、x === y ? ‘a’ : ‘b’
- js代码
- js代码其实就是js语句
- 形如: if() {} 、for() {}
一个容器只能接收一个Vue实例,一个Vue实例的容器也只能作用于一个容器.
new Vue({})实例中的key
必须是指定的Vue中的Key
- 下划线要去掉,并使用小驼峰命名法
- font-size 要写为fontSize
- background-color 要写为 backgroundColor
1.5 Vue的模板语法
1.5.1 插值语法
{{xxxx}}
简单的插值语法
功能:用于解析标签体内容、xxx是表达式、可以直接读取到data中的所有属性
1.5.2 指令语法
<a v-bind:href="xxx">点击跳转</a>
冒泡语法 v-bind 可以动态的给任何值赋予属性(vue绑定)附加:v-bind: 可以简写为 :
功能:用于解析标签、不加入冒泡语法只是普通的字符串,加上之后vue会将其变为js表达式
1.6 Vue 的绑定机制
1.6.1 单向数据绑定机制
<input type="text" v-bind:value="name">
v-bind 单向数据绑定
从data中找到name表达式的值更新容器模板,但是容器模板中的值改变不会影响到data中的name表达式的值。只允许单向传递
1.6.2 双向数据绑定机制
<input type="text" v-model:value="name">
v-model 双向数据绑定
从data中找到name表达式的值更新容器模板,并且容器模板中的值会影响到data中的name表达式中的值,而且此时如果其他地方也用到该表达式,则全部数据都发生改变。允许双向传递
1.6.3 对比v-bind和v-model
- v-model 并不能在所有的标签下都能够被使用
- 并不是所有能被v-model使用的标签都有输入,从而造成双向影响
v-bind:value
可以简写为 :valuev-model:value
因为其局限性所以默认收集的是value值 所以可以简写为 v-model
1.7 el和data的两种写法
el : 个人认为这种写法类似于封装了一个对象,然后可以调用这个对象给哪个类使用
const v = new Vue({
data:{
name:'第二种'
}
})
v.$mount('#root');
建议使用第二种
new Vue({
el:'#root',
data:function(){
return{
name:'第二种'
}
}
})
1.8 MVVM模型
- M:模型(Model):对应data中的数据
- V:视图(View):模板
- VM:视图模型(ViewModel):Vue实例对象
1.9 数据代理
通过Object.defineProperty
修改属性值
<script type="text/javascript">
let number = 18;
let person = {
name:'张三',
sex:'男'
}
Object.defineProperty(person, 'age',{
value:18,
enumerable:true, // 控制属性是否可以被枚举,默认为false
writable:true, // 控制属性是否可以被修改,默认为false
configurable:true, // 控制属性是否可以被删除, 默认为false
// 当有人调用age这个属性,函数被调用
get() {
// 当number修改后,每次调用age时,age都会改变为number
return number
},
set(value){
// 当有人调用age时,可以通过set修改number的值
number = value,
}
})
</script>
1.9.1 什么是数据代理?
通过一个对象代理对另一个对象中的属性操作 读/写
1.9.2 Vue中的数据代理
个人理解为 java中的 setter和getter方法
只要一个实例化容器里 data中的数据存在,那么这个数据就会拥有getter和setter
实例化容器中的数据就是配置数据
1.10 事件处理
1.10.1 事件基本使用
所有自定义函数必须封装进实例化容器中才能生效 v-on 简化为 @
<button v-on:click="showInfo">点我提示信息</button>
<button @click="showInfo2(66, $event)">点我提示信息2</button>
<script>
const vm = new Vue({
el:'#root',
methods:{
showinfo(event){
console.log()
},
showinfo2(number, event){
console.log(number)
}
}
})
</script>
1.10.2 事件修饰符
修饰符可以连接写
@click.stop.prevent
-> 阻止事件冒泡的同时阻止默认事件发生
- Vue中的时间修饰符:
prevent:
:阻止默认事件 比如a标签自动跳转stop
:阻止事件冒泡once
:事件单次触发capture
:使用事件的捕获模式self
:只有event.target是当前操作的元素时才触发事件passive
:事件的默认行为立即执行,无需等待事件回调完毕
1.10.3 键盘事件
生效时间:
@keydown
按下键盘上的按钮、@keyup
按下键盘上的按钮后弹起来
1.10.3.1 Vue中常用的一些按键别名
- 回车 => enter
- 删除 => delete (捕获删除或者退格键)
- 退出 => esc
- 空格 => space
- 换行 => tab 比较特殊,只能配合keydown使用
- 上 => up
- 右 => right
- 下 => down
- 左 => left
demo : @keyup.enter ===> 效果在回车键按下之后抬起时生效
keyCode -> 输出按键名称 和 ASCII码值
1.11 计算属性与监视
1.11.1 什么是计算属性?
计算属性就是用你已经实现的成员属性与其他成员属性进行计算从而得到的新属性。
1.11.2 计算属性实现
new Vue({
el:'#root',
data:{
firstName:'1',
lastName:'2'
},
computed:{ // 计算属性 完整写法
fullName:{
get(){
// 当有人使用fullName 就会调用get 返回 组合值
return this.firstName + '-' + this.lastName;
},
set(){
...
}
},
fullName(){ // 简写
return ...
}
}
})
1.11.3 监视属性实现
监视属性Watch:
- 当监视属性变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视!
<script type="text/javascript">
const vm = new Vue({
el:'#root',
data:{
firstName:'1',
lastName:'2'
},
watch:{
isHot:{
deep:true, // 开启深度监视模式,能够监测多级数据改变
immediate:true,// 初始化时调用handler
handler(newValue, oldValue){
// 能够看到修改前和修改后的值
}
}
}
});
vm.$watch('isHot',{
...
})
</script>
1.11.4 计算属性和监视属性区别
- 监视属性能开启异步任务,但是计算属性不能开启异步任务
- 计算属性能做的事情,监视属性一定能够做到
- 计算属性做一些非异步任务时特别简易和便捷
- 一般来说尽量不要用箭头函数。但是一些特别的函数,例如:定时器的回调函数、ajax的回调函数、Promise的回调函数,最好写为箭头函数,因为他们不被Vue所管理!
1.12 绑定样式
绑定字符串写法:绑定样式适用于样式的类名不确定,需要动态去指定
绑定数组写法:要绑定的样式个数不确定,名字也不确定
绑定对象写法:要绑定的样式个数确定,名字也确定,但是要动态决定用不用
绑定样式: basic、happy、sad、normal、atguitu1、atguitu2、atguitu3
<div class="basic" :class="mood" @click="changeMood">{{name}}</div>
<div class="basic" :class="arr" @click="changeMood">{{name}}</div>
<div class="basic" :class="classObj" @click="changeMood">{{name}}</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'我是谁?',
mood:'normal',
arr: ['atguigu1', 'atguigu2'], // 用于绑定多个效果
classObj: {
atguigu1:false, // 决定该对象中的类使用不使用
atguigu2:false
}
},
methods:{
changeMood(){
const arr = ['happy', 'sad, 'normal']
const index = Math.floor(Math.random() * 3)
this.mood = arr[index]
}
}
})
</script>
1.13 渲染
1.13.1 条件渲染
使用v-show 做条件渲染 适用于高频率开发
<h2 v-show="false">h2标签消失</h2>
使用v-if做条件渲染 适用于低频率开发 逻辑用语 和 其他语言if-else同样用法
<h2 v-if="false">h2标签完全消失</h2>
<h2 v-else-if="1 === 2">h2标签完全消失</h2>
<script type="text/javascript">
// template 只能配合v-if使用,并且渲染后的代码中不会出现template标签
<template v-if="n === 1">
<h2>你好</h2>
<h2>世界!</h2>
</template>
</script>
1.13.2 列表渲染
<li v-for="p in persons" :key="p.id">
{{p.name}}-{{p.age}}
</li>
<li v-for="(p,index) of persons" :key="index">
{{p.name}}-{{p.age}}
</li>
<script type="text/javascript">
// template 只能配合v-if使用,并且渲染后的代码中不会出现template标签
persons:[
{id:'001', name:'张三', age:18},
{id:'002', name:'李四', age:20}
]
</script>
1.13.3 Key 的原理
当index的排列顺序被打乱,那么这个时就不能使用index作为Key进行排序处理
当Vue 中没有写指定的key作为排列顺序,那么会默认以下标(index)作为索引
无论key=id (唯一标识)时顺序怎样被打乱,他都不会影响唯一标识的排序
总结:遍历过程中会出现虚拟DOM对比算法(diff算法)进行以key值作为标识的排序
1.13.4 列表过滤
<li v-for="p in persons" :key="p.id">
{{p.name}}-{{p.age}}
</li>
<li v-for="(p,index) of fillPerson" :key="p.id">
{{p.name}}-{{p.age}}
</li>
<script type="text/javascript">
// template 只能配合v-if使用,并且渲染后的代码中不会出现template标签
new Vue({
data:{
persons:[
{id:'001', name:'张三', age:18},
{id:'002', name:'李四', age:20}
],
filPerson:[]
},
watch:{
keyWord(val){
this.filPerson = this.persons.filter((p)=>{
return p.name.indexOf(val) !== -1;
})
}
},
computed:{
filPerson(){
return this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1;
})
}
},
})
</script>
1.13.4+ 列表排序
<button @click="sortType = 2">点击升序</button>
<button @click="sortType = 1">点击降序</button>
<button @click="sortType = 0">原顺序</button>
<script type="text/javascript">
new Vue({
data:{
sortType:0, // 0表示原顺序、1表示降序、2表示升序
},
computed:{
filPerson(){
const arr = this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1;
})
if(this.sortType){
arr.sort(0, arr.length + 1);
}
return arr;
}
}
})
</script>
Vue中的数据监测小结:
Vue监测数据的原理:
- vue会监视data中所有层次的数据
- 如何监测对象中的数据?
- 通过setter实现监视、且要在new Vue时就传入要监测的数据
- 对象后追加的属性,Vue默认不做处理,也就是该属性无get set 方法
- 如果需要添加响应式属性,那么需要用以下API
Vue.set(target, propertyName, value);
vm.$set(target, propertyName, value);
- 如何监测数组中的数据?
- 通过包裹数组更新元素的方法实现,本质就是做了两件事:
- 调用原生对应的方法对数组进行更新
- 重新解析模板、进行页面更新
- 通过包裹数组更新元素的方法实现,本质就是做了两件事:
- 在Vue中修改数组的某个元素一定要用如下方法:
- 使用这些API:
push()
、pop()
、shifr()
、unshift()
、splice()
、sort()
、reverse()
Vue.set()
或者vm.$set()
- 使用这些API:
- 特别注意:
Vue.set()
和vm.$set()
不能给vm 或 vm的根数据对象(data)添加属性!!
1.14 内置指令
v-test
向指定节点中渲染文本内容
<div>{{name}}</div>
<div v-text="name"></div>
与插值语法的区别
- 两种写法都能够渲染文本内容
- 但是第一种写法更加灵活,可以手动添加新的文本内容
- 第二种写法是将指定的name文本替换掉之前的文本内容,从而降低了灵活性
v-html
向指定节点中渲染文本内容
与插值语法的区别
- v-html会替换掉节点中所有的内容
- v-html可以识别html结构(你放进去一个a标签的href,他会将这个url覆盖掉原内容)
- 特别注意:
- v-html拥有安全性问题,容易受到XSS攻击
- 一定要在可信内容上使用v-html,永远不要用在用户提交的内容上
v-cloak
配合css使用在加载较慢时有奇效
- 本质是一个特殊属性,当Vue实例创建完毕并且覆盖模板后,会删除v-cloak
- 因为v-cloak会被删除,所以如果给v-cloak指定属性,也会同时被删除
demo :
<style>
[v-cloak]{
display:none;
}
</style>
<h2 v-cloak>{{name}}</h2>
这时页面加载很慢,并且script写在该标签之下,浏览器会先加载h2标签。
当script被加载后,v-cloak会被删除,display也会失效
v-once
一次性赋值,只允许初始时渲染一次,后续不再改变
v-pre
跳过所在节点的编译过程
功能:隔绝Vue的加载,提高编译速率。
避免:不要和使用了Vue解析的语法一起使用!
1.15 自定义指令
两种不同的写法,应用场景不同,都放置在directives
中
<h2>放大十倍后的n为:<span v-big="n"></span></h2>
<button @click="n++">点我自动加1</button>
<input type="text" v-fbind="n">
<script type="text/javascript">
new Vue({
data:{
n:1
},
directives:{
big(element, binging){
element.innerText = binding.value * 10;
},
fbind:{
// 指令与元素成功绑定时(初始情况)
bind(element, binding){
element.value = binding.value
},
// 当指令所在的元素重新覆盖模板时
inserted(element, binding){
element.focus()
},
// 当所在的模板被解析时
update(element, binding){
element.value = binding.value
}
}
}
})
</script>
注意事项:
- 如果指令名是多单词组成,注意不能写为小驼峰
- 指令名必须用’’ 单引号包括
- directives中的 this 为 window对象 !!!
- 要想定义全局变量,需要在 实例化容器 外 写上 Vue.directive 类似于过滤器
<script type="text/javascript">
// 全局变量
Vue.directive('fbind',{
// 指令与元素成功绑定时(初始情况)
bind(element, binding){
element.value = binding.value
},
// 当指令所在的元素重新覆盖模板时
inserted(element, binding){
element.focus()
},
// 当所在的模板被解析时
update(element, binding){
element.value = binding.value
}
}),
new Vue({
data:{
n:1
},
directives:{
big(element, binging){
element.innerText = binding.value * 10;
},
}
})
</script>
自定义指令总结
- 配置对象中常用的三个回调:
- bind: 指令与元素成功绑定时调用
- inserted:指令与元素被插入页面时调用
- update:指令所在的模板结构被重新解析时被调用
- 指令在定义时可以不加
v-
但是在使用的时候一定要加入v-
- 如果指令名是多单词组成,注意不能写为小驼峰,要用class-case写法
1.16 生命周期
这部分建议在官网查看解析并且查看相关知识加深理解!
值得注意: 生命周期回调函数
- Vue在特殊时候帮助我们调用一些特殊的名称的函数
- 生命周期函数的名字不可更改,但函数的具体内容是程序员需要编写的
- 生命周期函数中的this 指向vm或者组件实例对象
Vue的核心正式结束!