Vue3朝花夕拾(一)
vue3
setup语法糖
- setup()在beforeCreate()之前,因为setup中读取不到vue2的组合式API的内容但是vue2中的可以读到setup中的数据
ref和reactive
ref在ts中需要.value操作数据 如果是 a= ref() 然后让 a = b,失效
reactive无法定义基本类型,如果 a = reactive() 然后让 a = b,失效
上述两种都是破坏了响应式,a指向的地址都变了,但是页面上读取的是之前的所以,如果是ref定义的响应式对象,直接.value改变是可以的,
而reactive需要用 Object.assign(a,xxx)这样才可以生效
- toRefs是把reactive中每个属性变成响应式对象
- 泛型的使用
const data = reactive<a>
不要写成 const a:xxx =reactive()
computed
computed()返回的是一个
响应式对象
computedRefcomputed()默认返回直接是返回他的get,如果需要修改需要手动定义
watch
四种类型可以被监视
- ref定义的数据
- reactive定义的数据
- getter函数
- 包含上面内容的数组
但是要注意
reactive定义的响应式对象(默认开始深层监视,且无法取消)
getter()或者就是()=>{return xxx}即返回了响应式对象的地址
数组,需要合理用数组解构使用
ref属性
就是给节点打标识,获取dom解决id混乱问题
- h5标签上就是直接获取
- 组件上的ref属性,这样需要用 defineExpose 把子组件的data抛出去
props
- defineProps可以只接受数据
defineProps(["aaa"])
- defineProps接收数据 + 类型
defineProps<{aaa:type}>(["aaa"])
- defineProps接收数据 + 类型 + 限制必要性 + 默认值(withDefaluts)
withDefaluts(defineProps<{aaa?:type}>(["aaa"]),{getter(默认值)})
生命周期(*)
Vue2
8个vue的生命周期钩子
| 时刻 | 调用函数 |
| —- | —————————————– |
| 创建 | 创建前(beforeCreat) 创建后(created) |
| 挂载 | 挂载前(beforeMount) 挂载后(mounted) |
| 更新 | 更新前(beforeUpdate) 更新后(updated) |
| 销毁 | 销毁前(beforeDestory) 销毁后(destoryed) |
v-if 进行销毁 v-show保留dom
Vue3
setup()在beforeCreated()和Created()之前
| 时刻 | 调用函数 |
| —- | ——————————————— |
| 创建 | setup |
| 挂载 | 挂载前(onBeforeMount) 挂载完毕(onMounted) |
| 更新 | 更新前(onBeforeUpdate) 更新后(onUpdated) |
| 卸载 | 销毁前(onBeforeUnMount) 销毁后(onUnMounted) |
v-if 进行销毁 v-show保留dom
父子生命周期
子先挂载——父挂载,即APP则是最后挂载
自定义hooks
hooks就是封装 data 和 method 对比的是 vue2 的mixin
例如:useUser.ts中要 export 方法,且函数中要 return 暴露的 data 和 method
hooks里面可以写钩子
路由
工作模式
history:url不带 # 但是要配合服务端处理路径 否则 404
hash:兼容性好,带 # 不太美观,且在 SEO 优化叫差
<RouterLink to="/home" active-class="active"></RouterLink>
<RouterLink :to="{path:'/home'}" active-class="active"></RouterLink>
<RouterLink :to="{name:'zhuye'}" active-class="active"></RouterLink>
query参数
要用模板字符串
<RouterLink :to="{path:`'/news?id=${news.id}&name=${news.name}'}`" active-class="active"></RouterLink>
<RouterLink
:to="{
path:'/news',
query:{
id:xxx,
name:xxx
}
}" active-class="active"></RouterLink>
params参数
不能用 path
只能用 name
且 to的参数要11对应或者+ ?
1、<RouterLink :to="{path:`'/news/detail/${xxx}/${xxx}'`}" active-class="active"></RouterLink>
{
name:'xiang'
path:'/news/detail/:id/:name?'
component:Detail
}
2、<RouterLink
:to="{
name:'xiang',
params:{
id:xxx,
name:xxx
}
}" active-class="active"></RouterLink>
路由props
- 第一种 所有params参数作为props
{
name:'xiang'
path:'/news/detail/:id/:name?'
component:Detail
props:true
}
对应的组件直接用defineProps(['id'])
- 第二种 自定义相传的参数(推荐query)
{
name:'xiang'
path:'/news/detail/:id/:name?'
component:Detail
props(route){
return route.query/params
}
}
- 第三种 对象写法
{
name:'xiang'
path:'/news/detail/:id/:name?'
component:Detail
props:{
a:xxx
b:xxx
}
}
pinia
修改
符合直觉的修改
store.sum ++ 生效
批量修改
store.$patch(count:111,name:xxx)
action
store.add(value); store{ actions{ add(val){ this.num += val } } }
storeToRefs
const {sum,name,count} = countstore
这样就此丢失了响应式
不用toRefs
原因是代价太大,把store里面所有的属性都转成了ref
subscrible
类似 watchEffect
store.$subscrible((mutated,state)=>{
// mutated 本次修改信息,state本次修改的数据
localStorage.setItem(key,JSON.stringify(obj))
})
组件通信
props
parent
<Child :car="car" :sendToy="getToyCallBack"></Child>
<scripts>
function getToyCallBack(value)
</scripts>
child
<button @click="sendToy(xxx)"></button>
defineProps(['car','sendToy'])
<scripts>
function getToyCallBack(value)
</scripts>
自定义事件
会使用到$event
事件对象
<button @click="onClick">
</button>
<scripts>
function onClick(x){
console.log(x)
}
</scripts>
没有传参,这里的 x 就是 PointerEvent
parent
<Child @abc:"mmm" ></Child>
<scripts>
function mmm(value){
console.log(value)
}
</scripts>
child
<button @click="sendToy(xxx)"></button>
<scripts>
const emit = defineEmits(['abc'])
onMounted(()=>{
emit('abc',123)
})
</scripts>
mitt
pubsub $bus mitt
父:接收数据 绑定事件(接收回调) .on
子:提供数据 触发事件 .emit
*在onUnMounted 解绑事件 .off
v-model
常用UI组件库
v-model的实质是
<input v-model = "username" />
<input :value = "username" @input="(<HTMLInputElement>$event.target).value" />
现在Vue3中如果是组件上实质上
<CusInput v-model="username" />
<CusInput :modelValue="username" @update:modelValue="$event" />
子组件
<scripts>
<input :value="modelValue" @input="emit('update:modelValue',(<HTMLInputElement>$event.target).value)" >
defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</scripts>
$attrs
适用于 祖——>孙,但是要借助父
收到的是props,没有收到的就是$attrs
$refs 和 $parents
$refs父传子
$parents 子传父
父:@Click=change($refs)
父:@Click=change($parents)
子组件主要还是要defineExpose(['xxx','xx'])
provide 和 inject
祖孙传递数据
祖:
provide("name",xxx)
孙:
const name = inject("name",xxx默认值)
插槽
默认插槽
要在子组件的地方放<slot></slot>
具名插槽
在组件标签上添加<template v-slot:"xxx"></template>
<slot name="xxx"></slot>
作用域插槽
在子组件中给slot
<slot :games:games></slot>
父组件中
<Games>
<template v-slot="params">
<ol>
<li v-for="item in params.game" ></li>
</ol>
</template>
</Games>