VUE3常用知识点总结

VUE3常用知识点总结

VUE3常用知识点总结

vue.js开发基础

数据绑定

1
2
3
4
5
6
7
8
9
10
<script>
export default{
setup(){
return{
数据名:data
...
}
}
}
</script>

setup语法糖

1
2
3
<script setup>
const 数据名=数据
</script>

响应式数据

ref()函数

响应式数据=ref(数据)

响应式数据.value=新值

reactive()函数

响应式对象或数组 = reactive(对象或者数组)

toRef()函数

将响应式对象的单个 属性转换为响应式数据

响应式数据=toRef(响应式对象,"属性名")

响应式数据.value=新值

toRefs()函数

将响应式对象中的所有属性转换为响应式数据

所有属性组成的响应式对象=toRefs(响应式对象)

属性绑定指令

v-model提供了3个修饰符

修饰符作用
.number自动转为数字类型
.trim自动删除首尾空白符
.lazy在change事件而不是 input事件触发

事件对象

$event是VUE提供的内置变量,可以获取事件对象

事件修饰符

修饰符作用
.prevent阻止默认行为
.stop阻止冒泡
.capture实现事件捕获,与冒泡顺序相反
.once只触发一次
.self只有DOM元素自身触发事件才执行,与stop的区别是:self不阻止冒泡,但是只有自己本身触发 才执行函数
.passive监听滚动事件@scroll.passive:优先响应滚动事件,而不是滚动事件 的回调函数完成才响应
.enter/.esc/.tab/.delete/.alt/.control/.shift/.meta捕捉特定建。@keyup.enter,如果只有按下Enter建才触发,使用.exact修饰符。@keyup.enter.exact
.left/.middle/.right鼠标按键捕捉,@click.left

计算属性

1
2
3
4
5
6
7
8
9
10
<template>
{{计算属性}}
</template>

<script setup>
import {computed} from 'vue'
const 计算属性 =computed(()=>{
return ...
})
</script>

侦听器

watch(侦听器数据来源 ,回调函数,可选参数)

其中可选参数是一个对象,该对象有下面两个常用属性:

  • deep:监听对象里面的属性
  • immediate:初次加载是否调用回调函数,默认false
1
2
3
watch(name,(newval,oldval)=>{
...
})

样式绑定

  • :class="calssName"
  • :class="{className:isActive,className1:true}"
  • :class="[className1, calssName2]"
  • :class="[isActive?className1:className2]"
  • :class="[{className:isActive},className2]"
  • :style="{color:'red',fontSize:fontSize+'px','font-size':'30px'}"
1
2
3
4
5
:style=[classobj1,classobj2]

const classobj1=reactive({
heigth:'10px'
})

组件

选项式API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
export default{
data(){
return{
...
}
},
methods:{
//定义方法
},
computed:{
//定义计算属性
},
watch:{
//定义侦听器
}
}
</script>

组合式API

1
2
3
4
5
6
7
8
9
10
11
12
<script>
import {computed,watch} from 'vue'
export default{
setup(){
const 数据=data
const 方法 =()=>{}
const 计算属性 = computed(()={})
watch(数据来源,回调函数,可选参数)
return {数据,方法,计算属性}
}
}
</script>

组合式API生命周期函数

函数说明
onBeforeMount()挂载前
onMounted()挂载后
onBeforeUpdate()更新 前
onUpdated()任意DOM更新后
onBeforeUnmount()销毁前
onUNmounted()销毁后

组件注册

全局 注册

在main.js中使用createApp(App).component('组件名称',需要注册的组件 )

局部 注册

在使用setup语法糖的情况下,直接import导入即可import comA from './comA.vue'

组件样式冲突解决

<style scoped>

如果使用了scoped属性后,还想让某些样式对子组件生效,可以使用深度选择器来实现,:deep(子组件选择器)

1
2
3
4
5
6
7
8
//子组件
<h5 class='title'></h5>
//使用子组件的父组件
<style scoped>
:deep(.title){
border:3px
}
</style>

父组件向子组件传递数据

子组件

1
2
3
4
<script setup>
const ps = defineProps({'自定义属性A':类型},{‘自定义属性B’:类型})
const ps = defineProps(['属性a','属性B'])
</script>

静态绑定属性

如果父组件传递的数据固定不变,可以使用静态绑定

<子组件标签名 自定义属性A=“数据”>

动态绑定属性

<子组件标签名 :自定义属性A=“name”>

验证props

1
2
3
4
5
6
7
8
9
10
props:{
自定义属性:{
type:number,
required:true,
default:0,
validator(value){
return true
}
}
}

子组件向父组件传递数据

子组件

const emit = defineEmits(['Demo']);emit('Demo')//触发

如场景 简单,可以直接使用$emit触发 自定义的事件<button @click='$emit("demo",1)'>触发</button>

父组件

<子组件标签名 @Demo='func'/>

跨组件数据传递

父组件

1
2
3
4
<script setup>
import {provide} from 'vue'
provide('注入名',值)
</script>

后代组件

inject(注入名,默认值,布尔值)

参数1:与父组件对应的 注入名称

参数2:可选,当没有匹配值 时使用,可以是值、函数

参数3:可选,当参数2位函数时,参数3需要 设置为false,表示该函数就是默认值,如果是ture,则函数的返回值为默认值(也就是工厂函数)。

1
2
3
4
<script setup>
import {inject} from 'vue'
const count = inject('注入名')
</script>

动态组件

实现动态切换页面中需要显示的组件

<component is='需要渲染的组件'></component>

is表示要渲染的组件,需要配合shallowRef()来使用

1
2
<component is="showComponent"></component>
const showComponent = shallowRef(组件)

组件缓存

防止动态组件来回切换时,隐藏的组件会销毁的情况

1
2
3
<KeepAlive>
需要被缓存的组件
</KeepAlive>

被缓存的组件有激活和未激活的生命周期

1
2
3
4
5
6
onActived(()=>{
...
})
onDeactivated(()=>{
...
})

KeepAlive常用属性

属性类型说明
include正则只缓存名称匹配的组件
exclude正则不缓存 名称匹配的组件
max数字最多可缓存的组件个数
1
2
3
<KeepAlive include="mycom">
<component :is="showComponent"/>
</KeepAlive>

插槽

子组件

1
2
3
4
5
<template>
<button>
<slot></slot>
</button>
</template>

使用子组件的组件

1
2
3
<MyButton>
按钮
</MyButton>

具名插槽

子组件

1
2
3
4
5
6
7
<template>
<div>
<slot name="header"></slot>
<slot name="body"></slot>
<slot name="footer"></slot>
</div>
</template>

使用子组件的组件

1
2
3
4
5
6
7
8
9
10
<template>
<ArticleInfo>
<template v-slot:header>
</template>
<template #:body>
</template>
<template #:footer>
</template>
</ArticleInfo>
</template>

作用域插槽

父组件获得子组件中的数据

  • 默认插槽

子组件定义数据

<slot message="hello"></slot>

父组件接受数据

1
2
3
4
5
6
7
<mycom  v-slot="data">
<P>{{ data.message}}</P>
</mycom>

<mycom v-slot="{message}">
<P>{{ message}}</P>
</mycom>
  • 具名插槽

每个插槽都是name属性,如果没有定义,则默认default

定义插槽

1
2
3
4
5
<template>
<slot message="a"></slot>
<slot name ="header" message="a"></slot>
<slot name ="footer" message="a"></slot>
</template>

使用插槽

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<SubScopeSlot>
<template #default="data">
<p>{{data.message}}</p>
</template>
<template #header="data">
<p>{{data.message}}</p>
</template>
<template #footer="{message}">
<p>{{message}}</p>
</template>
</SubScopeSlot>
</template>

自定义指令

自定义指令生命周期函数

函数说明
created绑定元素属性前调用
beforeMount绑定元素挂载前
mounted绑定元素的父组件及自身所有子节点都挂载完成后
beforeUpdate绑定元素的父组件更新前
updated绑定元素的父组件及自身所有子节点都更新后
beforeUnmount绑定元素父组件卸载前
Unmounted绑定元素的父组件卸载后

常用周期函数参数

参数说明
el所绑定元素
binding一个对象,包含多个属性,用于接受属性的参数值
vnode绑定元素底层虚拟节点
prevNode之前页面渲染中指令所绑定元素的虚拟节点

参数binding常用的6个常用属性

属性说明
value传递给指令的值
arg传递给指令的参数
old之前的值,尽在beforeUpdate和update中使用
modifiers一个包含修饰符的对象,如:v-my.foo.bar,修饰符对象为{foo:true,bar:true}
instance使用该指令的组件实例
dir指令的定义对象

私有自定义指令

1
2
3
4
5
export default{
dirctives:{
color:{}
}
}

使用自定义指令,必须以v-开头

<h1 v-color></h1>

如果使用setup语法糖,任何以v开头的驼峰式命名变量都可以当做自定义指令

1
2
3
4
5
6
7
8
9
10
<template>
<span v-color></span>
</template>
<script setup>
const vColor ={
mounted:el=>{
el.style.fontSize = '23px'
}
}
</script>

全局自定义指令

在main.js中声明

1
2
3
4
5
6
const app = createApp(APP)
app.directive('fontSize',{
mounted:el=>{
el.style.fontSize = '33px'
}
})

自定义指令绑定参数

<h1 v-fontSize></h1>

1
2
3
4
5
6
7
<script setup>
const vFontSize={
mounted:(el,binding)=>{
el.style.fontSize = binding.value
}
}
</script>

自定义指令的函数形式

对于自定义指令来说,通常在mounted和updated函数操作元素,所以可以直接进行简写

1
2
3
const vFontSize = (el,binding)=>{
el.style.fontSize = binding.value
}

或者

1
2
3
app.directive('fontSzie',(el,binding)=>{
el.style.fontSize = binding.value
})

引用资源

引用public中的资源

该目录的文件使用绝对路径

<img scr="/demo.png">

引用ssrc/assets资源

该目录的文件使用相对路径

一般用import导入后使用

1
2
3
4
5
6
<template>
<img :src="icon"/>
</template>
<script setup>
import icon from '../assets/vue.svg'
</script>

路由

Router基本使用

  1. 定义路由链接及路由视图
1
2
3
4
<template>
<router-link to="/home">首页</router-link>
<router-view></router-view>
</template>
  1. 创建路由模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const router = createRouter({
history:createWebHistory(),
routes:[
{path:'/home',component:Home}
]
})
//懒加载方式
const router = createRouter({
history:createWebHistory(),
routes:[
{path:'/home',component:()=>{import('./home.vue')}}
]
})

createApp(app).use(router)

重定向

1
2
3
4
5
6
7
const router = createRouter({
history:createWebHistory(),
routes:[
{path:'/',redirect:'/home'}
{path:'/home',component:Home}
]
})

路由嵌套

<router-link to="/父路径/子路径"></router-link>

1
2
3
4
5
6
7
8
9
10
11
12
const router = createRouter({
history:createWebHistory(),
routes:[
{
path:'父路径',
component:父组件,
children:[
{path:'子路径'component:子组件}
]
}
]
})

动态路由

{path:'路径/:id',component:组件}

也可以使用嵌套路由的方式来定义

1
2
3
4
5
6
7
8
9
10
11
12
const router = createRouter({
history:createWebHistory(),
routes:[
{
path:'父路径',
component:父组件,
children:[
{path:':id'component:子组件}
]
}
]
})

获取路径参数可以直接使用$route.params.id

同时支持使用props接受路由规则中匹配的参数,如果这样用,需要使用在定义路径时开启props为true,{path:':id',component:子组件,props:true}

1
2
3
4
5
<script setup>
const p = defineProps({
id:string
})
</script>

路由命名

{path:'路由路径',name:'路由名称',component:组件}

<router-link :to="{name:路由名称,params:{参数名:参数值 }}"></router-link>

编程式导航

push

以编程方式进入下一个路径

1
2
3
4
5
const router = userRouter()

router.push('/about')
router.push({name:'user',params:{id:2}})
router.push({name:'user',query:{id:1})

如果在参数的对象中提供了path属性,则会忽略params属性只能手动拼接router.push({path:/user/3})

replace

与push效果相同,区别是replace不会在历史记录中添加记录

router.replace({path:/user/3})

go

实现前进和后退效果

router.go(-1)后退到上一步

导航守卫

类型说明
全局导航守卫前置守卫beforeEach()、后置守卫afterEach(),在路由即将改变前后 触发
导航独享守卫beforeEnter(),路由导航到一个不同页面触发,只适用于单个路由
组件导航守卫beforeRouteEnter()、beforeRouteUpdate()、beforeRouteLeave()在进入、更新 、离开之前触发
1
2
3
4
5
6
7
const router =createRouter()
router.beforeEach((to,form,next)=>{
...
})
router.afterEach((to,form,next)=>{
...
})

to:目标路由对象

from:当前导航正要离开的路由对象

next:函数,如果不接受next函数,则默认允许访问路由,如果接受了next函数,必须 调用,并且不允许访问任何一个路由。next具有3中调用方式

  • next(),执行下一个钩子函数
  • next(false),强制停留在 当前页面
  • next(‘/‘),跳转到其他地址
1
2
3
4
5
6
7
8
9
router.beforeEach((to,from,next)=>{
if(to.name ==="move"){
if(isLogin){
next()
}else{
next({name:'login'})
}
}
})
作者

步步为营

发布于

2024-07-14

更新于

2025-03-15

许可协议