注意:proxy代理的内容是有返回值的,所以前面data需要用let来声明
new Proxy(target, handler)
target:
需要被代理的对象,它可以是任何类型的对象,比如数组、函数等等,注意不能是基础数据类型。
handler:
它是一个对象,该对象的属性通常都是一些函数,handler 对象中的这些函数也就是我们的处理器函数,主要定义我们在代理对象后的拦截或者自定义的行为。
new Proxy(data, {
/*
target:被代理的目标对象
property:将要被设置的属性名
value:新的属性值
简:目标对象 key value
*/
set(target, key, value) {
...
},
get(target) {
return ...
}
})
v-bind可以绑定属性和类名 :
v-on绑定事件 @
内置参数event,两者互存$event
计算属性与侦听器区别与原理
概念:基于现有的数据,计算出来的新属性。 依赖的数据变化,自动重新计算。
计算属性的目的:简化模板语法中的逻辑编写,使视图更加清晰,并具备语义化
计算属性跟方法相比,具备缓存的能力,而方法不具备缓存
split字符串分割成数组 reverse翻转数组 join数组转换为字符串
计算属性虽然是对象方法,但是以属性的方式进行使用,并且默认是只读的
Object.defineproperty 的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
Object.defineproperty(obj, prop, desc)
obj : 第一个参数就是要在哪个对象身上添加或者修改属性
prop : 第二个参数就是添加或修改的属性名
desc : 配置项,一般是一个对象
第三个参数里面还有6个配置控住属性
-
writable: 是否可重写
-
value: 当前值
-
get: 读取时内部调用的函数
-
set: 写入时内部调用的函数
-
enumerable: 是否可以遍历
-
configurable: 控制属性是否可以被删除
模拟计算属性
// computed对象
const computed = {
num() {
return 123
}
}
// 空对象
const vm = {}
for (const property in computed) {
Object.defineProperty(vm, property, {
value: computed[property](),
// writable: true
})
}
完整写法有 getter 和 setter
不要在 getter 中做异步请求或者更改 DOM
避免直接修改计算属性值
侦听器的基本使用:
特点:默认只有依赖项发生改变的时候才会触发
// watch是一个函数
// 第一个参数: 要监听的响应式变量(数据源)
// 第二个参数:执行的回调函数
// 第三个参数: 配置(例如deep深度监听/immediate是否立即监听等)
// 注意:当监听一个对象时,第一个参数数据源必须是函数且返回一个值即 "() => 对象.要监听的属性"
计算属性与侦听器区别与原理
侦听器的目的:侦听器用来观察和响应Vue实例上的数据变动,类似于临听机制+事件机制。当有一些数据需要随着其它数据变化而变化时,就可以使用侦听器
计昇属任与侦听器区别
计算属性适合:多个值去影响一个值的应用;而侦听器适合:一个值去影响多个值的应用
侦听器支持异步的程序,而计算属性不支持异步的程序
计算属性适用场景:
1.多个值去响应一个值的应用
2.不适合异步的场景(计算属性往往需要return,return是瞬间的,它并不会等待异步执行完成之后再return)
侦听器的适用场景:
1.一个值去响应多个值的应用
2.适用于异步场景(可以不使用return)
条件渲染
v-if 是通过删除DOM元素来实现元素的显示/隐藏的
适用于不太频繁的切换显示/隐藏(因为真实删除DOM会触发reflow,非常消耗性能)
v-show 是通过是否添加行内样式display:none来实现元素显示/隐藏
是通过是否添加行内样式display:none来实现元素显示/隐藏适用于频繁切换显示/隐藏的
v-for 列表渲染
渲染目标→数组
两个形参 item,index
渲染目标→对象
三个形参 value,key,index
渲染目标→数字 从1开始
一个形参 item
渲染目标→字符串
两个形参 item,index
key的值要确保是唯一的,才能实现真正的性能优化
使用template来替换div容器作用:避免生成冗余的DOM元素
class的三种形态:字符串、数组、对象
style的三种形态:字符串、数组、对象
一般通过类名来控制样式,除非样式很简单
v-model本质是语法糖
:value
属性关联到响应式数据
@input
输入事件将输入的内容重新赋值给响应式数据
label>input
复选框checkbox 单选框radio 下拉框select
select>options
第一组声明周期函数(响应式数据)
- beforeCreate 在响应式数据(data)还没有准备的时候触发
- created 响应式数据准备好了,所以经常在这个生命周期函数来发起ajax请求
第二组声明周期函数(DOM元素)
- beforeMount 在DOM元素加载完毕之前触发
- mounted DOM元素加载完毕适用于操控dom节点
第三组声明周期函数(数据更新)
-
beforeUpdate 数据更新之前:拿到更新后的响应式数据,也能拿到更新前的DOM元素
-
updated 数据更新之后:拿到更新后的响应式数据,也能拿到更新后的DOM元素
第四组声明周期函数(组件卸载触发)
- beforeUnmount 可以拿到首次渲染的响应式数据,也可以拿到首次渲染的DOM元素,适用于组件卸载后,解绑一些事件或者关闭事件总线
- unmounted 可以拿到首次渲染的响应式数据,拿不到首次渲染的DOM元素
查询filter结合includes
组件的概念及组件的基本使用方式
组件是带有名称的可复用实例,通常一个应用会以一棵嵌套的组件树的形式来组织,比如:页头、侧边栏、内容区等组件
关于命名方式及规范:
1.命名方式:建议至少两个单词,可以有效的避免和原生html结构起冲突
2.命名的时候可以短横线分隔或者大驼峰写法:my-head |I MyHead(大驼峰)
3.使用组件的时候,在.html文件下只能是短横线
app.component全局注册:
优点:不用考虑组件层级,可以直接使用
缺点:无法树摇晃,即使全局组件没有被使用了,也依然被会打包进去,体积较大
组件之间的数据是单向流动的,子组件不能直接修改传递过来的值
但是有时候也需要数据的双向流动,可利用v-model来实现
如果用v-model绑定组件
<my-head v-model="count"></my-head>
<my-head :model-value="count" @update:model-value="count = $event"></my-head>
组件的属性与事件是如何进行处理的
-
默认不通过props接收的话,属性会直接挂载到组件容器上
-
事件也是如此,会直接挂载到组件容器上
-
可通过 inheritAttrs:false 选项阻止这种行为
-
可通过 $attrs 内置语法,给指定元素传递属性和事件
渲染作用域 插槽只能获取当前组件的作用域
具名插槽 处理多个插槽的需求
作用域插槽 希望插槽能访问子组件的数据
webpack
npm init -y pacgkage.json
npm i -D webpack webpack-cli
npm run build 需配置 “build”: "webpack"在package.json
先放下以后再说
组件大驼峰
将ref属性添加到标签上,可以获取原生的DOM元素
将ref属性添加到组件上,可以获取vm(实例对象)
利用nextTick监听DOM更新后的情况
- 将回调推迟到下一个DOM更新周期之后执行。在更改了一些数据以等待DOM更新后立即使用它
回调函数风格
this.$nextTick(()=>{...})
promise风格
this.$nextTick().then(()=>{...})
自定义指令与自定义全局属性及应用场景
除了核心功能默认内置的指令(例如v-model和v-show),Vue也允许注册自定义指令,来实现一些封装功能
常见钩子函数mounted, updated …
函数简写(el, binding) =>{}
挂载全局属性 app.config.globalProperties. h t t p = h t t p 已淘汰 t h i s . http = http 已淘汰 this. http=http已淘汰this.http.get()
推荐provide(提供)
app.provide(‘$http’, http)
复用组件功能之Mixin混入 组件复用
- Mixin提供了一种非常灵活的方式,来分发Vue组件中的可复用功能
myMixin={} mixins:[myMixin]
插件的概念及插件的实现
- 插件是自包含的代码,通常向Vue添加全局级功能。例如:全局方法、全局组件、全局指令、全局mixin等等
install(app,option){}
app.use(myPlugins)
transition动画与过渡的实现在
- Vue中推荐使用CSS3来完成动画效果。当在插入、更新或从DOM中移除项时,Vue提供了多种应用转换效果的方法
动态组件与keep-alive组件缓存
- 渲染一个”元组件”为动态组件。依is的值,来决定哪个组件被渲染
component 完成动态组件
keep-alive 对动态组件进行缓存
异步组件与Suspense一起使用
- 在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块
defineAsyncComponent(()=>import('xxx.vue'))
Suspense 首次加载异步组件插入自定义dom结构
<suspense>
<component :is='nowCom'></component>
<template #fallback>
<h2>
Loading...
</h2>
</template>
</suspense>
跨组件通信provide和inject
写法:对象写法(不可以传递响应式),工厂函数写法(可以传递响应式)
Teleport实现传送门功能
- Teleport可以实现传送门功能,也就是说逻辑属于当前组件中,而结构需要在组件外进行渲染,例如:按钮模态框组件
<teleport to='body'>...</teleport>
逻辑组件实现
function isShowModal(){
const div = document.createElement('div')
createApp(Modal).mount(div)
// 将这个模态框挂载到div元素挂载上去,再将div追加到body中
document.body.append(div)
}
虚拟DOM与render函数及Diff算法
{{message}} → render函数&AST语法树 → 虚拟DOM(js对象)
使用两个核心函数:h函数和render函数
(1)h函数,它是来自于vue核心
(2)render也可以直接使用
使用h函数:创建虚拟节点(多个虚拟节点可以构成虚拟DOM)
render(){
return h('div',h(...))
}
toRefs用来解构
watch和watcheffect
watcheffect
1.立即触发一次,然后在响应式数据发生改变时,会再次触发一次
2.触发时机:响应完成后,DOM更新前(可以通过配置:{flush:‘post’},将它更改为DOM更新后)
3.watchEffect可以返回一个stop方法,调用stop方法可以立即停止watchEffect的监听
4.有一个形参callback,它可以处理一些特殊的行为,如取消上一次的ajax请求,解绑事件,清除定时器等等 cb这个回调函数是在响应式数据更新前触发的(组件卸载前触发)
watch
1.默认触发时机是响应依赖发生改变时触发
2.通过配置:{immediate:true},可以设置立即触发,newValue就是响应式数据首次渲染的值,oldvalue是undefined,也就是响应式数据还没有准备好的时候
跨组件通信方案provide_inject
provide(‘count’,0) → inject('count")
注意:不要在inject中修改响应式数据
1.可利用回调函数修改
2.为了防止可设置成 readonly
复用组件功能之use函数
- 为了更好的组合代码,可以创建统一规范的use函数,从而抽象可复用的代码逻辑
利用defineProps与defineEmits进行组件通信
- 在组合式APl中,完成父子组件通信操作
路由的基本搭建与嵌套路由模式
1.定义路由组件也可以从其他文件导入
2.配置路由表每个路由都映射到一个组件
3.创建路由实例并传递routes
配置
4.创建并挂载根实例插件生效
动态路由模式与编程式路由模式
声明式路由 不够灵活
编程式路由 $router.push()灵活控制
需要区分路径