Vue核心
介绍
Vue是一款用于构建用户界面的 JavaScript 框架。
它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。
无论是简单还是复杂的界面,Vue 都可以胜任。
特性
- 声明式渲染和组件系统是Vue的核心库
- Vue.js的核心是一个允许采用简洁的模板语法来声明式的将数据渲染进DOM的系统,
自动跟踪 JavaScript 状态变化并在改变发生时响应式地更新 DOM。
创建一个vue3应用
1.引入vue库 CDN在线引入或者npm i vue
2. Vue类对象
创建vue实例对象
//相当于vue的模板,准备好一个容器;
<div id="app">
<h1>{{message}}</h1>
</div>
const app = Vue.createApp({
data() { //data用于存储数据,值写成对象
return {
message:'helloworld'
}
},
})
app.mount('#app')
- data: 数据对象 --初始化数据(页面可以访问);变量,可以在里面写对象、字符串、数值、数组;data函数形式:****保证一个vue实例对象应用一个数据对象 (组件是深入),
- mount:挂载应用—应用实例必须在调用了 .mount() 方法后才会渲染出来。让vue实例与html元素关联;该方法接收一个“容器”参数,可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串;当使用mount挂载app节点后,节点及内部的所有元素成为vue模板
- {{变量}} 模板插值语法 ,能使用vue实例所有的属性与方法 变量来自于data选项定义的数据;变量可以是表达式,三目 ;vue模板里的模板插值只能去实例对象里寻找属性,不能拿到window里的
如:点击就不会出现alert()
Vue模板语法有两大类
插值语法
指令语法
常用指令
指令 (Directives) 是带有 v- 前缀的特殊属性
vue.js的指令是以v-开头的,它们作用于HTML元素,
指令提供了一些特殊的特性,将指令绑定在元素上时,
指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性(attribute)。
1. 文本类指令
v-html指令
v-text指令
v-pre指令 所有vue模板语法会被保留按照原样直接显示;即包裹什么就显示什么;常用与显示原始双大括号标签及内容
注:
v-html指令 标签会作为html元素渲染出来![在这里插入图片描述](https://img-blog.csdnimg.cn/370c6fffdd35479caccf2287404d772f.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/f104c59bb9f44aa3b60f0ea57ac0a744.png)
解决html指令存在的xss漏洞问题
- 使用一个xss的npm包来过滤xss攻击代码,给指令的value包上一层xss函数
- 在编译前会将我们从vue-loader传入的compilerOptions.directives和baseOptions.directives进行了合并。 这样我们就能覆盖html指令。
2. 操作属性v-bind指令: 属于单向绑定
用于绑定标签属性;简写 :href=“xxx” ; 可以直接读取data所有属性
什么是attribute?html标签的预定义和自定义属性我们统称为attribute
3. 表单处理v-model指令 属于双向绑定
v-model只能应用在表单类元素上(输入类元素:input 单选多选 select下拉框 多行输入,因为它们都有value值)
<h2 v-model:x="name">不能这么使用</h2>
表单数据操作 ----data选项数据 < - > input表单数据 表单双向数据绑定
实现 input输入框内容更改 data选项数据自动更新,负责监听用户的输入事件以更新数据
表单 、 及 元素上创建双向数据绑定
文本类型的 和 元素会绑定 value, property 并侦听 input 事件;
和 会绑定 checked(布尔类型值), property 并侦听 change 事件;
会绑定 value ,property 并侦听 change 事件;
原生:
1. 获取input输入框数据
- 监听input事件或change事件
- 获取输入框内容
event.target.value
2. 赋值给inputValue
vue:
<div id="app">
//1、绑定input事件,获取输入值,赋值给message,message值绑定在value属性上,message变化,输入框值变化
<input type="text" v-model="message">
{{message}}
</div>
<script src="../day1/lib/vue.global.js"></script>
<script>
const {createApp} = Vue
createApp({
data() {
return {
inputValue: 'rose',
message:''
};
},
}).mount('#app')
</script>
我们也可以将多个复选框绑定到同一个数组或集合的值
<div id="app">
<!-- 获取多个复选框值 -->
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label>
<p>{{checkedNames}}</p>
</div>
<script src="../day1/lib/vue.global.js"></script>
<script>
const { createApp } = Vue
createApp({
data() {
return {
inputValue: '',
checked: false,
checkedNames:[]
}
},
methods: {},
}).mount('#app')
</script>
data的两种写法
3. 操作样式:class和:style
Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
Class 与 Style 如何动态绑定样式?
可以通过对象语法和数组语法进行动态绑定
4. 操作事件v-on简写@
v-on指令 - 绑定事件
vue选项参数 - methods 定义事件处理方法
5. 条件显示指令v-if和v-show
v-show 与 v-if 有什么区别?
<div id="app">
<p v-if="online == 0">在线</p>
<p v-else-if="online == 1">离线</p>
<p v-else>隐身</p>
<!-- v-show 隐身 -->
<h2 v-show="isShow">v-show指令</h2>
</div>
<script src="../lib/vue.global.js"></script>
<script>
const { createApp } = Vue
createApp({
data() {
return {
online: 8,
isShow:false
}
},
}).mount('#app')
</script>
6. 循环指令v-for
<div id="app">
<!-- index是数组的下标 -->
<p v-for="item in list">{{item}}</p>
<p v-for="(item,index) in list">{{item}} - {{index}}</p>
</div>
<script src="../day1/lib/vue.global.js"></script>
<script>
const { createApp } = Vue
createApp({
data() {
return {
list:['javascript','css','html','vue']
}
},
}).mount('#app')
</script>
8. v-for与v-if合用
vue示例中的this
- this就是当前实例化出来的vue对象(vue实例)
- vue构造函数内部解析时会把data、methods等中的值直接设置给这个实例化出来的vue实例对象
- 最终直接通过这个vue实例对象即可访问data中的属性以及methods中的方法等
示例-vue实现通过this可以操作data选项中的数据和methods选项中的方法
vue框架监听data选项中的数据,只要数据变化,自动异步更新界面
<body>
<div id="app">
<p>{{count}}</p>
<button @click="plus">加一</button>
<button @click="minus">减一</button>
</div>
<script src="../lib/vue.global.js"></script>
<script>
//创建vue实例
const { createApp } = Vue
const app = createApp({
//定义数据
data() {
return {
count:0,
title:'vue中 this关键字'
}
},
// 定义方法
methods: {
plus() {
console.log('plus方法',this.title)
this.count++
// this.minus()
},
minus(){
console.log('minus方法');
this.count--
}
},
})
app.mount('#app')
</script>
</body>
vue框架响应式原理—数据劫持
每次更改数据,通过getter,setter拦截,通知watcher触发更新。
1、 Object.defineProperty()实现
<div id="app">
<p></p>
<button onclick="onPlus()">加一</button>
<button onclick="onMinus()">减一</button>
</div>
<script>
let data = {
message: 'hello',
count: 0,
}
const divELe = document.querySelector('#app>p')
divELe.innerHTML = data.count
// 将data数据 通过Object.defineProperty方法转变成具有getter和setter方法的新对象,
// 新对象数据变化,自动getter和setter方法,
// 数据劫持
let vm = {}
for (const key in data) {
Object.defineProperty(vm, key, {
get() {
return data[key]
},
set(newValue) {
data[key] = newValue
divELe.innerHTML = newValue //更新界面
},
})
}
function onPlus() {
vm.count = vm.count + 1
}
function onMinus() {
vm.count = vm.count - 1
}
</script>
</body>
2、 Proxy代理实现
<script>
//目标对象
let data = {
message: 'hello',
count: 0,
}
const divELe = document.querySelector('#app>p')
divELe.innerHTML = data.count
//创建代理对象
const proxy = new Proxy(data,{
get(target,propery){
return target[propery]
},
set(target,propery,newvalue){
target[propery] = newvalue
divELe.innerHTML = newvalue
}
})
function onPlus() {
proxy.count++
}
function onMinus() {
proxy.count--
}
</script>
</body>
todolist示例
<!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>
<!--
todoList应用
点击确定按钮时获取输入框内容,显示到ul列表下
1. 确定按钮绑定事件
2. 获取输入框内容
3. 显示内容到列表
3.1 定义一个数组存储数据
确定时存储数组元素
3.2 遍历数组显示数据
-->
<body>
<div id="app">
<input type="text" v-model="content" placeholder="请输入内容">
<button @click="add()">添加</button>
<ul>
<!-- /**循环遍历数组**/ -->
<li v-for="(item,index) in list">
<input type="checkbox" v-model="item.state">
{{item.name}} - {{index}}
<button @click="onDelete(index)">删除</button></br>
<!-- state为true就是选中状态,false就是未选中 -->
<button @click="onChecked(index)">{{item.state?'选中':'未选中'}}</button>
</li>
</ul>
</div>
<script src="../day1/lib/vue.global.js"></script>
<script>
const {createApp} = Vue
createApp({
data() {
return {
content:'', //输入框内容
list:[{ name: 'javascript', state: false },
{ name: 'css', state: false },],
};
},
methods:{
//添加
add(){
let obj = {
name: this.content,
state:false
}
this.list.push(obj);
//清空输入框
this.content = '';
},
//删除
onDelete(index){
this.list.splice(index,1);
},
//多选框
onChangeState(index){
let item = this.list[index]
item.state = !item.state
}
}
}).mount('#app')
</script>
</body>
</body>
</html>
MVVM模型
数据代理
回顾 Object.defineProperty()
给对象添加属性
Object.defineProperty(对象名,‘添加的属性名’,{配置项value: })
即通过此方法,可以对属性进行更高级的操作,可以控制是否枚举,是否被修改,是否被删除
Object.defineProperty(person,'age',{value: 17})
但是这种方式创建的属性不能枚举;枚举:即不参与遍历
console.log(Object.keys(person))
这个方法是遍历person对象的所有属性名,以数组输出
Object.defineProperty()的应用
== for in 既能遍历数组也能遍历对象==
//遍历数组
for (let index in arr){
console.log(arr[index])
}
//遍历对象
for (let key in person){
console.log(person[key])
}
数据代理
通过一个对象代理对另一个对象中属性的操作(读/写操作)
即通过obj2 也可以操作obj
vue里的数据代理
实例里自带setter getter 代理
事件处理
事件基本使用
事件修饰符
passive 更多用于移动端
@wheel 叫鼠标滚轮触发事件
@scroll 叫滚动条滚动触发事件
键盘事件
- 大多是按键都是可以绑定事件的;@keyup.按键名
如大小写键触发:@keyup.caps-lock=’ ’ ;(名字为两个单词,需要小写并 - 连接) - tab 键有一个功能就是将光标从当前元素身上切走;所以需要搭配键盘 按下时触发事件
- keyCode会因为键盘不同,按键也不同
事件总结
既阻止事件冒泡也阻止事件默认行为
系统修饰键也可以连写
计算属性
一般来说计算属性用于获取值(get()) ,少用于修改值(set()),所以,当只完成获取值时,可以用如下简写方式:
== 插值模板里什么时候写函数名什么时候写函数==
如上:fullName 是 fullName()调用的结果
监视属性watch
天气切换案例
watch的使用:两种方式
如果很明确知道监视谁,就写在实例里;如果后期会根据用户行为才知道监视谁,就采用第二种
深度监听—deep: true
vue自身是可以监控对象内部的值的
监视属性简写
第一种
第二种
至于什么时候用什么写法,就根据情况而定,需要深度监听,就正常写法,如果不需要,就简写
computed 和 watch 对比
(上述:即最终让vue实例里的this都指向实例对象)
如果不进行异步操作,计算属性使用更简单
不需要准备显示的属性,直接进行计算return出来
开发者工具显示:
需要准备好被监视的初始值,此方式是命令式,并且重复
开发者工具显示:
如:watch中可以加定时器,让结果等一会出现;computed就无法实现
(val是newValue的简写形式)
如果用计算属性写:(无法实现)
计算属性靠的是返回值拿到结果;但是我们不能让计算属性的函数延时拿到返回值;
== 即计算属性不能开启异步操作==
绑定样式
- == : class=’ ’ ==
类样式的绑定:
行类样式的绑定:
总结:(下图对象写法和数组写法写反了)
样式对象:key值都是存在的属性名,并且去掉 -
条件渲染—显示与隐藏
(3. 是因为 v-if 为false时 dom节点就销毁了,就找不到了)
v-show v-if
需要注意,使用v-if v-else时,中间不允许打断,打断后只i执行打断前的代码
v-show不能与template使用;template不破坏html结构
列表渲染
基本列表
遍历数组
<ul>
<li v-for='(item,index) in persons' :key="index">
{{item.name}}--{{item.age}}
</li></ul>
遍历对象 (v-for=‘(item,index) in car’ 与v-for=‘(item,index) of car’) 一样
即循环遍历输出1-5的数字
key的原理
元素身上的key都被vue内部用了,在渲染成真实dom时就被销毁了,所以不要体现在html元素上。
- 遍历列表以index作为key;在打乱数组顺序时会出现的问题
操作都需要在真实dom完成,所以 input 输入的内容存在于真实dom,diff算法比较的是虚拟dom - 以id作为key的好处—大多数都可以复用
(下面是在列表前添加一个li)
- 不写key
就会把遍历的index作为key
面试:vue中的key有什么作用?
列表过滤
- 用watch实现
即一个字符串都包含空字符串,并且下标为0;当输入框不输入按下回车,就会将所有数据过滤出来,因为列表数据都包含空字符串,所以都满足条件
- 用computed实现—推荐
vscode代码折叠:
#region 折叠的代码 #endregion
计算属性的流程:
1、代码第一次执行就调用一次
2、所依赖的数据发生变化时调用
所以不需要去监视数据的变化,只要参与了计算属性,当监视数据的变化时就会重新执行计算属性的内容,就拿到了新的值
列表排序
更新时的问题
引出:
vue监测数据改变的原理
收集表单数据
保持一致,当点击账号也能获取焦点
过滤器—对时间格式化
时间戳使用
注册:全局注册、局部注册
使用方式:
- 计算属性实现
- methods方法实现
- 过滤器实现
==过滤器其实就是一个函数 ==
多个过滤器串联
上述是局部注册 - 全局过滤器