认识组件的嵌套
还可以将Main中内容再划分
scoped防止组件与组件之间的样式相互污染
组件的通信
父子组件之间通信的方式
父组件传递给子组件
给传过来的内容做限制
type为传的内容的属性类型,required为true表示该内容是必须传的,default为,如果没人传该类型,就会传123
type的类型
对象类型的其他写法
为Object类型时,需要是函数,然后返回一个对象
Prop的大小写命名
非Prop的Attribute
attribute就是class,id等属性。
这的class=‘why’
传递到了这的div上
禁用Attribute继承和多个根节点
使用禁用后,class=‘bol’就不在div中了,
你可以指定元素绑定属性,使用attrs将属性指定元素class绑定给h2了,,此时被禁用的attribute就被h2继承
如果要继承的属性比较多,比如要绑定class,id等,那么可以直接这样,就会将class,id等都绑定
多个跟节点也是在需要的地方指定即可
子组件传递给父组件
自定义事件流程
自定义事件的参数和验证
参数传递
验证
null代表不需要验证
一个参数时可以取名为payload
如果取值比10小还是会传过去,但是会报错
练习
父组件传递给子组件,
我们在父组件的data中定义了成员titles,他里面是一个数组。通过父组件传递给子组件,将其传入子组件,以便子组件使用。其中contens成员为元素对应要展示的内容。currentIndex为要展示的内容的下标
子组件传递给父组件
父组件中对应的方法titleClick中的参数index就是子组件传来的,这次的传递需要使父组件实现点击的title元素内容与contents内容相对应,所以获取,子组件的index,而子组件的index为当前点击的元素的下标
绑定class属性,设置样式,括号内容为,如果currentIndex与index相等,那么active为true,那么active样式就会展示,currentIndex的值为当前点击的元素的下标
使用v-for遍历使用从父组件获取到的titles数组内容,title为当前下标index时的内容。
点击事件,
将当前点击的元素的index传入方法itemClick中,将currentIndex的值设为当前点击的元素的index,然后将当前点击元素下标index传入到父组件
emits为传入父组件的内容,props为父组件传入子组件的内容,设置了内容的类型和如果没传入,默认为空数组
非父子组件的通信
Provide和Inject
Provide和Inject基本使用
Provide和inject函数的写法
想要拿到names的长度,这样是不对的,他是this指向的是个undefined,一个对象并不是作用域,所以这样肯定不行的
处理响应式数据
将他写成一个函数就可以解决这个问题,因为是函数,源码会将他的this与这个组件实例绑定起来。
通过这样给names添加元素,元素会变多,但是获取的length固定了不会再改变,所以需要length跟着一起改变这样是不行的
可以通过computed来实现,但是computed返回的是一个ref对象,值存在value中
不过可能是改了。我这使用,反而不用.value可以得到值
全局事件总线mitt库
使用事件总线工具
homeContent会根据这里的内容,获取对应的值,如果emitter.on的第一个参数为why,那么info对应的内容就是emitter.emit第一个参数为why的第二参数的内容
Mitt的事件取消
认识插槽Slot
如何使用插槽slot
插槽的默认内容
多个插槽的效果
具名插槽的使用
动态插槽名
具名插槽使用的时候缩写
渲染作用域
认识作用域插槽
作用域插槽的案例
1.先通过prop从父组件中获取数组names的值
2.使用v-for循环获取到的names的值,
3.将names中获取的值绑定在插槽中。
4.父组件先绑定默认插槽default,之所以默认,是因为没有命名,然后将其赋值,值的名字slotProps为自定义的,里面可以获取到绑定在插槽中的内容。
这样就可以根据获取到的names中的值个数而调用相应个数的插槽。
slotprop可以自己取
独占默认插槽的缩写
默认插条可以这么写
默认插槽和具名插槽混合
如果有两个插条,就不能默认
动态组件的实现
1.遍历es数组,数组中的值是 需要动态添加的组件名
2.按钮点击ClickINt中是将es当前遍历到的内容赋值给变量Content,is前面添加:才是动态的,
使用动态组件实现,如果不加:就给写死了绑定的组件,
给动态组件传递数据
动态组件切换后是会销毁的,比如,点击about来到这个组件,使用他的累加按钮,加到任意数字,再切换到其他组件,然后再切回来就会发现原来累加的数字为0了,重新开始了
需要加冒号是为了不被识别成字符串
最后给每个组件加上name属性,因为include是根据name来确定组件的
Webpack的代码分包
通过import函数的方式去导入Math.vue模块,只有通过该方法导入的模块,后续就会进行分包的操作。因为一般,所有自己敲的模块都会打包到一个.js文件中
Vue中实现异步组件
异步组件的写法二
这是第二种方法,loadingComponent表示如果当前组件还没加载除了,就让Loading组件先占位展示
异步组件和Supense
如果default的内容显示不了,就显示fallback下的
$refs的使用
想要访问子组件的内容只需要用 . 即可
对子组件的方法调用也不在话下
$parent和$root
也可以拿到跟组件
就算一个组件被几个组件引用,那么他也只有一个父组件,因为是按单个算的,比如左边引用他,那么在在左边里,他就左边那一个父组件,反之,右边也是
el拿到的是根元素
认识生命周期
生命周期流程
一开始组件组件创建之前会进行初始化操作,然后在初始化后,创建组件前会回调一个beforeCreate,然后再开始初始化,注入和响应性,初始化,注入和响应性就创建了实例instant,之后又会回调created,created之后开始进行真正的挂载,判断是否有template,如果有则编译模版至渲染函数,如果没有就编译el的InnerHTML至模版,编译完后,又回调一个beforeMount生命周期 , 然后开始把内容放入dom中,再回调mounted,挂载真正成功。 如果该组件不再使用了,则回调一个beforeUmount,然后再开始卸载,卸载后,回调一个umounted, 如果还是用,不卸载,改变了数据内容,那么就会回调一个beforeUpdate, 刷新完后就会回调update
点击按钮后
、
查看更新前后的内容
v-if为fasle则内容会被删除,不会显示,也就是卸载该元素
混存组件的生命周期
‘
v-model
在组件中使用了v-model相当于用了这一串语句效果,所以我们是需要去组件写上modelValue元素的,并且写上需要的事件,event在这里传过来的不是元素而是对应的值
使用input绑定input的value,可以更改值,
想要 input中也使用v-model那么就需要设置一个computed,自定义一个属性,让input绑定,然后在该属性中写上get和set,get是当调用该属性时使用,set是修改时使用
认识动画
Vue的transition动画
进来和离开后透明度为0,进来后和离开透明度为1
transition是设置指定样式的过度效果,这里设置了opacity的效果 2s为过度时间,还可以设置先快后慢还是先慢后快,这里设置了ease
Transition组件的原理
过渡动画Class
点击时对应的属性就会添加上
如果没有给指定的name,那么就会默认为v
class添加的时机和命名规则
不写这个也可以浏览器默认会给这个值
过度css动画
只不使用transition使用的是animation,bounce为效果使用的部分,1s为时间,ease动画执行曲线
bounce中的百分数为帧,里面设置相应帧时的大小,因为我们开始和结束需要有一样的效果和样式,但是离开时,帧为百分比,所以需要加上翻转,分开写,才能达到想要的效果
以上说到的效果可以一起使用。实现放大缩小淡出效果
同时设置过度和动画
但是需要注意当两个动画同时出现时,需要添加属性type,而type指定要按哪个效果走,
显示的指定动画时间
也可以指定效果时间,一旦指定了,那么代表下面再设置的时间就无效了
过度的模式mode
in-out属性为先进入动画在出去动画
组件的使用
appear初次渲染
使用属性appear,将他原本的默认值false设为true,那么在加载该内容时,就会有设置好的相应效果
认识animate.css
自定义过度class
一般除了加需要的效果的class,还会加这个
但是有些效果是需要翻转才可以完美展示
认识gsap库
隐藏显示前三个,
gsap库的使用
target是给谁执行动画,to是从默认状态达到某个状态,
el为元素,拿到要动画的元素,done是默认你不去执行done的回调,在你还没执行{}中的内容就会默认去调用done了
from是从{}中所写的状态达到默认状态
所以一般会这么使用该内容。在onComplete中回调done。
这段意味着,从这个状态回到初始状态,从初始状态到
这个状态
gsap实现数字变化
set的值为点击之后会加那么多,当我们使用这个方法实现点击上升号数字从原本的值多了指定的100时,他是立刻就改变的,没有一个过渡的状态,比如,值为0时,一改变就立刻从0变成100,而不是0,1,2,3.....转变成为100,所以我们不能直接用counter来展示变化,需要重新写一个方式实现
要实现该效果就需要再定义一个showNumber和使用侦听器,侦听我们得counter,当我们得counter有新值的时候,使用gsap对this的某个属性赋值,我们对象中的内容表示,属性showNumber在1s内newvalue一点点改变值赋值到showNumber。这样就实现了所需效果,但是值得一点点改变是小数的改变。需要使用tofixed来设置保留几位小数点,我们设置保留0位就是整数
可以不用computed的内容。也可以实现
认识列表的过渡
指定tag的意思就是你指定tag=‘div’,那么就会把元素包裹在div中
span为行内元素,在他显示出来之前无法对他进行太多的操作,所以为了让行内元素实现一系列效果,就不要将他设为inline-block效果,加absolute是因为删除时要等要删的元素完全消失才能移动,影响美观,所以设置成absolute可以在没完全消失时剩余的就开始慢慢移动
移除动画要加
列表过渡的移动动画
给元素做重新排序
befor-enter是写死一个进入的初始状态,为了更好的效果,让消失的元素按序号一个个消失,那么我们需要获取序号并且对于每个不同元素的延迟时间依次递增才能实现依次消失,所以我们使用了v-for的index拿到每个元素序号,然后通过自定义属性data并取名为index给每个元素设置他们对应的序号的值的data,通过js的知识可知所有自定义data都会放入到dataset中,所以我们只需要dataset.index就可以拿到对应的值,然后乘以我们需要的大小。,就可以设置递增的延迟时间
filter高阶函数,用来过滤的,indexof后判断返回布尔值,为false时调用者不保留,true保留
认识Mixin
Mixin的合并规则
全局混入Mixin
extends
Options API的弊端
大组件的逻辑分散
认识Composition API
setup函数参数
想要拿到pops值那么就只需要将其传入该函数即可
结构方式
当data和setup中有同名属性,会使用setup的
在setup中定义一个变量。对他进行操作,他不会在界面上有响应式效果,之前返回的属性都是对象成员属性,会通过reactive()进行处理
setup不可以使用this
在执行setup时把setup传给了该函数
此时者的fn就为setup,会判断fn中是否有参数,如果有则是个数组,mei
Reactive API
如果我们想要之前定义的变量在时显示也要响应式,我们也可以让他用reactive包裹
Ref API
Ref自动解包
因为拿到的是对象,所以按理来说需要.value拿到对应的值,但是template会对ref的对象进行解包,所以直接就可以使用
但是setup不会自动解包,所以就需要.value拿到值
当counter本身为对象时会进行解包。但是被赋给另一个对象时,不会对他进行解包
但是如果最外层包裹的是reactive可响应式对象,那么内容ref可以对couter进行解包
认识readonly
响应式和普通对象都不可修改
Reactive判断的API
toRefs
使用后,直接使用结构后的那么name,age也是响应式
这样结构后内容也是响应式的
toRef
这个返回的就是一个值,所以不需要结构,但是toRefs返回的是一个对象所以需要
ref其他的API
浅层响应式,也就是直接改值不会做出响应
如果浅层的想要触发响应式,那么就需要使用triggerref
customRef
customRef案例
如果这样的话,那么到时候导入的时候就需要这个方式导入
这样就不用自定义函数名
然后导入customRef,因为custRef参数是函数,所以不可直接将value传入,trank和tigger为收集依赖的时候,触发依赖的时候
函数需要返回 get和set函数,
增加定时器就能实现防抖
computed
通过computed实现响应式,也是可以写在setup中
通过按钮调用chnageName实现内容的更改
computed返回值是一个ref对象
第二种方式
watchEffect
运行后watchEffect会立即执行一次,然后会自动收集响应式,他在立即执行的时候会看一下里面使用到了哪些可响应式内容,比如如下代码中使用了name,那么就会把watchEffect中函数添加到name的依赖中,如果一开始不执行的话,就收集不了依赖。
获取两个值
当年龄为25时,停止监听
watchEffect清除副作用
aaaa为自定义的一个名字,作为watchEffect的参数,他是一个函数,他的参数也是一个函数,在里面写清楚额外副作用的操作
运行立刻会打印网络请求成功,一直改变内容,不会,除非暂停几秒
setup中使用ref
watchEffect的执行时机
一开始titile为null,执行到return语句时,将title内容挂载成功,此时title内容为h2内容
调整watchEffect的执行时机
想要内容更新完挂载完,再执行watchEffect内容,那么就需要添加参数flush。flush默认值为pre,为提前进行调用,现在设置为post,就会等内容挂载完毕,更新完毕才会执行
此时就不会再为null时调用,而是只有最终结果时内容
Watch的使用
侦听单个数据源
需要写一个个体函数,也就是这个,拿到需要侦听的对象的内容,这里是拿到了侦听对象info的name
watch本身调用了dowatch,
在dowatch中将所有source转为getter,对source进行了判断,其中判断了如果是reactive就转换成reactive的getter值,所以代表可以直接拿到reactive的类型,如果是reactive类型会直接通过getter返回source的,而source就是本reactive对象,所以后面拿到的newvalue或者oldvalue都是reactive对象
判断的类型
ref对象类型,是直接拿到ref的值,
因为源码通过getter是直接返回value的
如果希望是普通对象,那么就进行解构,此时会来到该判断对该函数调用
如果你需要侦听多个对象,那么就需要将source值写成数组,此时就会来到这个判断语句,通过map函数对source进行遍历,然后再对每个元素进行类型的判断
还可以进行解构
如果你不想他是reactive对象,那么你就可以这么写,但是需要注意的是,不要少了小括号
侦听响应式对象
watch的选择
默认是可以深度监听的,因为当我们类型为reactive时就把deep设为true了
但是你写成普通对象,他就侦听不到了
如果你想进行深度侦听那么就需要添加deep并将他置为true
如果希望第一次也进行侦听,也就是一来就侦听,那么可以添加一个immediate,将其置为true
生命周期钩子
在setup使用生命周期函数,需要导入所需函数,并且,函数名在之前所学过的函数名前面多加一个on
给内容做更改就会调用onUpdata,这里是添加了内容
注册多个相同的什么周期会同时都调用
Provide函数
Inject函数
将App.vue中数据提供给Home.vue,导入provide函数,函数中两个参数为key和value,是键值对
Home.vue想使用App.vue通过provide传输的值时,需要使用inject来接收,inject参数可以有两个,第一个为key第二个为默认值,默认值也可以不设置
数据响应式
但是上面App.vue中传过来的值为不可响应的,所以就可以使用ref进行包裹将内容设置为可响应式
修改响应式Property
子组件对父组件进行更改操作是非常不好的,我们可以通过readonly阻止这个行为
将原本在setup写的内容放入新建的.js文件中
在需要引用刚建的文件导入刚建的文件
然后再调用chu
也可以通过展开运算符。调用
title的改变等待3秒从默认值coderwhy变成kobe
可以给传入的title设置默认值,然后为了使title能够修改,是响应式的,所以需要使用到ref,设置侦听,因为我们只需要侦听到他的新值并将title改为新值,所以就只需要newValue,又因为watch是惰性的他不会立即执行,所以为了能显示默认值,我们需要增加属性immediate
useScrollPosition
实现滚动值的显示
也可以抽取出来写
首先还是需要导入
useLocalStorage
对你传入的数据进行判断,当你传入的数据有value,那么就是需要保存该value,如果没有value那么你可能会需要取出该key对应的value,如果是需要改变对应的key所对应的value,那么就需要使用watch侦听,将新value与对应的key存入
保存后,可以直接用key拿到相应内容,进行更改
导文件太多,也可以将所有导入语句放入一个单独的.js文件中
此时用到所需的文件导入就只需要这样即可
知识补充:
可以在script标签添加setup,这样也可以实现需要的效果
如果要进行父组件子组件传输需要这样
认识h函数
将template抓换成VNode,然后再转换成elment,如果只使用template就无法充分使用到JavaScript的特性了,所以在template到VNode会经过编译compile转成render函数,render函数返回值是VNode,执行render函数就会转换成VNode,render为函数那么就是JavaScript能力,所以我们自己去编写render函数
h函数的基本用法
render是绑定this的,写在setup中,那么h中的counter'就不要this了,但是在setup中的counter不会接包,所以就需要.value拿到值
如果你想给该App传入插条,传入一个就在h函数最后一个参数,传入一个对象,如果多个插条就传入一个数组
default对应的是函数,可以接收其他属性的参数,这是表示我们插条为默认插条,传入h函数内容信息,通过props传给子组件HelloWorld
子组件接收,先使用this.$slots拿到所有的插槽,然后再.default拿到默认插条,通过三元运算符,判断该插条是否存在,存在就直接通过拿到所有插槽去调用默认插槽函数,拿到相应内容,不存在就拿设置的默认内容
调用这个default函数是可以传参数的
父组件可以通过${props.参数名}拿到传入的值
我们编写的jsx代码会通过bable转换成我们写的rander代码。以前不支持需要配置,现在好像支持了,可以直接使用。另外需要换行最好使用()
也可以添加组件
也可以实现插槽效果
调用.facus()可以自动获取焦点
自定义v-focus,先确定是全局的还是局部的,然后在里面自定义名字,名字不需要加v-因为默认都会有,然后就可以写内容了,这里写的内容是挂载后调用的生命周期函数,
该生命周期函数有四个参数,目前只需要第一个,第一个为element元素,第二个是个对象,第三个为虚拟节点,第四个为前一个虚拟节点
el为绑定的元素,用其调用focus()即可
全局该指令设置
v-why为自定义命令,后面的aaa和bbb为自定义的修饰符,这些都i会放入到bindings,可以通过bindings.value拿到赋的值,.modifiers拿到修饰符
创建一个文件夹,在该文件夹中放入全局可使用的文件内容
判断是否为秒为单位,如果是的就让他✖一千,换算成毫秒单位,统一单位便于计算和设计
下载该库,可以进行应用格式化函数
设置格式的时候,使用大写的HH才是24小时制
实现输入什么格式就实现什么格式
、
bindings.value可以渠道语句的值,所以就可以判断是否有设置,有就按照有的内容进行设置,没有就按照设置了默认格式操作
也可以这样写
但是上面的方式如果多次使用该自定义指令,会发现格式都为第一次传入的样子了,所以需要修改
把他加入到bindings中
认识Teleport
首先要在index中加上div的id为why的元素
自定义对象类型插件,在导入该插件时会默认传入一个参数,这里叫app,后拿到该参数就可以自定义对该参数进行操作
在main.js中导入该插件,然后.use(插件名),该操作会自动下载该插件
这是给app的全局配置添加属性name,并将coderwhy赋值过去
为了区分全局属性和局部属性,一般全局属性会在前面加$
由于setup没有绑定this,所以想要在setup中拿到刚刚设置的全局属性,就需要导入给内容,可以通过他拿到组件实例
在通过该语句才可以拿到,因为Instance通过该函数已相当于App了,那么这串语句就等同
同样也可以是函数类型
同样导入加use