- 发布时间
Vue@3
- 作者

- Name
- wenjuGao
- github
- @Github
Vue3 的使用
Vue3 带来的主要改变:
- Composition API + setup 使用 setup 语法糖,可以让代码更换解耦,独立的逻辑集中完成,不在收模板和生命周期的限制,书写更灵活。
- TypeScript Vue3 使用 ts 编写,提供了完整的 API type 等更好的兼容 ts 项目
- Treeshaking 主要 API 独立暴露,都能更好的减少运行时 Vue 包的大小
Vue3-API
主要 API 使用
1. ref & reactive
将数据处理为响应式数据
const foo = ref({ a: '111' })
const bar = reactive({ a: '222' })
// 读取:
console.log(foo.value.a, bar.a)
:::warning 通过结构读取响应式数据会让数据丢失响应式 :::
ref 内部虽然已经是响应式的了,单也支持 ref 嵌套:
const foo = ref({ a: '111' })
const newFoo = ref(foo)
console.log(foo.value === newFoo.value) // true
// == >
// const newFoo = ref(isRef(foo)?unRef(foo):foo)
2. props & emit
- setup 函数
<script>
export default defineComponent({
setup(props, context) {
// props => 传入的props值
// context => 组件上下文
// $attrs
console.log(context.attrs)
// $slots
console.log(context.slots)
// $emit
console.log(context.emit)
// 暴露
console.log(context.expose)
},
})
</script>
- Composition API
<script setup>
const foo = ref('')
const props = defineProps({
data: Number,
})
const emits = defineEmits(['fn-1', 'fn-2'])
// 提供给外部组件访问
defineExpose({
foo,
})
</script>
生命周期
provide、inject
Vue 提供了 readonly 来控制被嵌套(子-孙组件)来修改注入的值
// 注入值
const provideInfo = ref({ text: 'provide', value: '123' })
provide('provideInfoReadonly', readonly(provideInfo))
provide('provideInfo', provideInfo)
// 接收值
const provideInfo = inject('provideInfo')
const provideInfoReadonly = inject('provideInfoReadonly')
vue-router
- Composition API 中我们不在使用 this 来指代 Vue 是实例,当然也提供了 getCurrentInstance 来获得当前实例,但是感觉更换的方式是通过独立引入 API 的试下来实现路由的功能。如果觉得代码会繁琐的话可以使用(mixin)[https://v3.cn.vuejs.org/guide/mixins.html]来优化进入的代码。
const router = useRouter()
const route = useRoute()
onBeforeRouteLeave((to, from) => {
if (flag.number > 1) {
return true
} else {
flag.number += 1
return false
}
})
onBeforeRouteUpdate(async (to, from) => {
console.log('onBeforeRouteUpdate', to, from)
})
const handleChangeRouter = () => {
router.push({
path: route.path,
query: {
...route.query,
flag: flag.number,
},
})
}
style
<style scoped lang="scss">
.dome {
text-algin: center;
}
</style>
scoped添加后会限制成局部样式,不会渗透到子组件中,当需要改变子组件样式时,写法:
- /deep/
.dome {
text-algin: center;
/deep/ .el-label {
text-algin: center;
}
}
- >>> sass不支持
.dome {
text-algin: center;
>>> .el-label {
text-algin: center;
}
}
- ::v-deep
.dome {
text-algin: center;
::v-deep .el-label {
text-algin: center;
}
}
- :deep
.dome {
text-algin: center;
:deep(.el-label) {
text-algin: center;
}
}
那么问题来了,scoped 是谁的属性,是通过什么限制样式的,不同的修改子组件样式的写法有什么不同?
vue3
::v-slotted(.slot-class) {
background-color: #000;
}
::v-global(.my-class) {
background-color: #000;
}
【参考】