使用vite创建vue3
npm create vite
或者 yarn create vite
composition API
- ref
- reactive
- torefs
- watch
- watch Effact
- computed
setup
它是组件内使用composition API的入口,执行时机是在beforecreate之前执行的
- setup的参数- props:值为对象,包含:组件外部传递过来,且组件内部声明接受了的属性- context:上下文对象 - attrs:值为对象,包含:组件外部传递过来,但没有在props声明接收了的函数- slots:收到的插槽内容,相当于this.$slots- emit:分发自定义事件的函数,相当于this.$emit
ref函数:定义普通类型数据
vue3中定义响应式数据:const name : ref(‘小明’);在js中操作:name.value=‘张三’
reactive函数:定义对象类型响应式数据
let obj =reactive({type:'前端工程师',
salary:'30k')functionchange(){
obj.type='后端工程师'//vue3可以直接增删改查数据this.$set(obj,'type','后端工程师')//vue2中想要修改数据并渲染必须要用$set,而vue3中可以直接改}
reactive对比ref
- 从定义数据角度对比1).ref用来定义:基本类型数据2).reactive用来定义:对象(或数组)类型数据3).ref也可以用来定义对象(或数组)类型数据,它内壁会自动通过reactive转为代理对象
- 从原理角度对比1).ref通过object.defineProperty()的get与set来实现响应式(数据劫持)****2)reactive通过使用proxy来实现数据劫持,并通过Reflect操作源对象内部的数据
- 从使用角度对比- ref定义数据:操作数据需要.value, 读取数据时模板中直接读取不需要.value- reactive定义数据:操作数据与读取数据都不需要.value
computed计算属性
setup(){let person =reactive({firstName:'张',lastName:'三',})//计算属性简写形式(没有考虑计算属性被修改的情况)
person.name =computed(()=>{return person.firstName+'-'+'person.lastName'})//计算属性完整写法(考虑读和写)
person.name =computed(()=>{get(){return person.firstName+'-'+'person.lastName'},set(value){//value是新的值const nameArr = value.split('-')
person.firstName = name[0]
person.lastName = name[1]}})return{
firstName,
lastName,
name
}}
父子传参
父传子:
在父组件中
子组件中用 defineProps({data:string})接受
子传父:
//在子组件中通过defineEmits派发一个事件const emit =defineEmits(['test'])constclickTap=()=>{emit('test',数据)//派发名为test}//在父组件中<Son @test="回调函数"></Son>
在回调函数中第一个参数就是传过来的数据
兄弟间传值
//1. 安装mitt npm install mitt//2.在main.js中注册挂载到全局import mitt from'mitt'
app.config.globalProperties.$mitt =newmitt()// 发送数据组件<button @click="sendMitt">$mitt发送数据</button>functionsendMitt(){
proxy.$mitt.emit('mittFn', 数据)}//接受数据
proxy.$mitt.on('mittFn',(res)=>{
console.log(res)//res就是传过来的数据})
配置全局组件
//在main.ts中配置import Card from'./components/Card/index.vue'createApp(App).component('Card',Card).mount('#app')//component中第一参数是组件名称,第二个参数是组件实例
动态组件
//让多个组件使用同一个挂载点,并动态切换,这就是动态组件importAfrom'./A.vue'importBfrom'./B.vue'<component :is="A"></component>// 通过js切换组件//如果你把组件实例放到Reactive Vue会给你一个警告runtime-core.esm-bundler.js//修改如下:const tab = reactive<Com[]>([{name:"A组件",comName:markRaw(A)},{name:"B组件",comName:markRaw(B)}])
异步组件 Suspense
// 在父组件中引入异步组件import{ defineAsyncComponent }from'vue'const Dialog =defineAsyncComponent(()=>import('../../components/Dialog/index.vue'))// <suspense> 组件有两个插槽。它们都只接收一个直接子节点。default 插槽里的节点会尽可能展示出来。如果不能,则展示 fallback 插槽里的节点。<Suspense><template #default><Dialog></Dialog></template><template #fallback><div>loading...</div></template></Suspense>
Teleport传送组件
Teleport 是一种能够将我们的模板渲染至指定DOM节点,不受父级style、v-show等属性影响,但data、prop数据依旧能够共用的技术;例如
<teleport to="body"><div class="teleport">我是teleport</div></teleport>//可以通过to将div放到body里面,也可以使用class或者id放到指定的dom节点里面
keep-alive缓存组件
有时候我们不希望组件被重新渲染影响使用体验;或者处于性能考虑,避免多次重复渲染降低性能。而是希望组件可以缓存下来,维持当前的状态。这时候就需要用到keep-alive组件。
keep-alive对应两个独有的生命周期 onActivated 和 deactivated
<!-- 基本 --><keep-alive><component:is="view"></component></keep-alive><!-- 多个条件判断的子组件 --><keep-alive><comp-av-if="a > 1"></comp-a><comp-bv-else></comp-b></keep-alive><!-- 和 `<transition>` 一起使用 --><transition><keep-alive><component:is="view"></component></keep-alive></transition>
keep-alive生命周期的变化:
初次进入时:OnMounted 和 onActivated
退出时:deactivated
再次进入时只会触发:onActivated
只执行一次的放在 onMounted中;组件每次进去执行的方法放在 onActivated中
<keep-alive:include="[]":exclude="":max=""></keep-alive>
// include数组中可以填入组件名称name,:include里面包含的组件才会被缓存,没有包含的不会被缓存
:exclude则相反; :max 则最大缓存的组件个数
transition 动画组件
自定义 transition 过度效果,你需要对transition组件的name属性自定义。并在css中写入对应的样式
transition标签中n的ame对应的css标签的设置
name-enter-from:定义进入过渡的开始状态。
name-enter-active:定义进入过渡生效时的状态
name-enter-to:定义进入过渡的结束状态
name-leave-from:定义离开过渡的开始状态。
name-leave-active:定义离开过渡生效时的状态
name-leave-to:离开过渡的结束状态。
<transition name='fade'>
<div v-if='flag' class="box"></div>
</transition>
//对应css
.fade-enter-from{
background:red;
width:0px;
height:0px;
transform:rotate(360deg)
}
//开始过度了
.fade-enter-active{
transition: all 2.5s linear;
}
//过度完成
.fade-enter-to{
background:yellow;
width:200px;
height:200px;
}
//离开的过度
.fade-leave-from{
width:200px;
height:200px;
transform:rotate(360deg)
}
//离开中过度
.fade-leave-active{
transition: all 1s linear;
}
//离开完成
.fade-leave-to{
width:0px;
height:0px;
}
也可以通过自定义过渡class类名;通过自定义class结合animate css动画库
<transition
leave-active-class="animate__animated animate__bounceInLeft"
enter-active-class="animate__animated animate__bounceInRight"
>
<div v-if="flag" class="box"></div>
</transition>
结合gsap动画库使用GreenSock
vue3全局定义函数和变量
由于Vue3没有prototype属性,是使用app.config.globalProperties代替,然后去定义变量和函数
vue2中: vue.prototype.$http = ()=>{}
vue3中: const app = createApp(APP)
app.config.globalProperties.$http = () => {}
CSS样式穿透
vue中使用了scoped后,会在dom结构上会以date-v-hash的方式加在标签上,以保证唯一,不会样式冲突,从而达到样式私有模块化。
在使用UI组件库的时候,很多时候需要改它默认的样式,就需要用到样式穿透:
在样式中使用 :deep(input) 这样就可以了
Pinia 全局状态管理工具 代替Vuex
Pinia.js 有如下特点:
完整的 ts 的支持;
足够轻量,压缩后的体积只有1kb左右;
去除 mutations,只有 state,getters,actions;
actions 支持同步和异步;
代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
无需手动添加 store,store 一旦创建便会自动添加;
支持Vue3 和 Vue2
使用:
1.安装 npm install pinia
2.main.js 引入注册
import {createPinia} from ‘pinia’
const store = createPinia()
app.use(store)
3.初始化仓库
import{ defineStore }from'pinia'exportconst useTestStore =defineStore(Names,{state:()=>{return{current:1}},//类似于computed 可以帮我们去修饰我们的值getters:{},//可以操作异步 和 同步提交stateactions:{}})
4.组件中使用 State是允许直接修改值的
<template><div><button @click="Add">+</button><div>{{Test.current}}</div></div></template><script setup lang='ts'>import{useTestStore}from'./store'const Test =useTestStore()constAdd=()=>{
Test.current++}</script>//批量修改constAdd=()=>{
Test.$patch({current:200,age:300})//批量修改函数形式constAdd=()=>{
Test.$patch((state)=>{
state.current++;
state.age =40})}//通过原始对象修改整个实例:$state您可以通过将store的属性设置为新对象来替换store的整个状态,缺点就是必须修改整个对象的所有属性constAdd=()=>{
Test.$state ={current:10,age:30}}// 通过actions修改,在cations中定义方法,然后直接调用actions中的方法constAdd=()=>{
Test.setCurrent()}
依赖注入(provide/inject)
在父组件中provide注入数据,在所有子孙组件中都能接收到
// 例如在APP.vue组件中import{provide}from'vue'provide('flag',shuju)// 这样数据就注入完成了,在所有子孙组件中都能接受到//在子组件中接受数据import{inject}from'vue'let data =inject('flag')// 这样就拿到了父组件的数据//当在子组件中修改数据的话,会影响所有子组件中的这个数据
TSX 类似于react写法
1.安装 npm install @vitejs/plugin-vue-jsx -D
2。配置vite.config.ts 、 tsconfig.json
自定义Hooks
优秀的开源库:hooks开源库
useAttrs、useSlots
版权归原作者 阿信呐 所有, 如有侵权,请联系我们删除。