作者:vita2333
链接:https://juejin.im/post/689231...
期待了很久的vue3,一发布就上手体验了一把,这里记录几个自己碰到的网上不常见的小坑~
自定义全局参数
定义:
// main.js
const app = createApp(App)
app.config.globalProperties.$test = 'test'
除了setup()
需要先获得实例,其他地方可以直接通过$test
使用:
<tempalte>
<div>{{ $test }}</div>
</tempalte>
<script>
import { getCurrentInstance } from 'vue'
export default {
setup() {
const test = getCurrentInstance()?.appContext.config.globalProperties.$test
console.log('test===')
console.log(test)
},
}
</script>
Vite通过alias别名引用
在webpack
中,配置src
的别名为@
,可以这么写:
// 引用src/views/PageOne.vue
import PageOne from '@/views/PageOne.vue'
复制代码
如果使用Vite
,则需要做以下修改:
// vite.config.js
module.exports={
alias: {
'/@/': path.resolve(__dirname, './src'),
},
}
// tsconfig.json
{
"compilerOptions": {
"paths": {
"@/*": ["src/*"],
"/@/views/*": ["src/views/*"]
}
}
}
import PageOne from '/@/views/PageOne.vue'
更加规范的props和emits
在vue3
中,父子组件传值的props
和emits
写法更加规范(命名更统一),体现在:
v-model
的变化
<template>
<child-component v-model:value="myValue"></child-component>
</template>
v-model:value
等同于props:'value'
和emits('update:value')
- 需要指定
emits
为了便于管理,建议在emits
中定义所有用到的emit
export default {
emits: ['update:value', 'otherEmit'],
setup(props, { emit }) {
emit('update:value')
emit('otherEmit')
},
}
跟踪attrs和slots
本来以为可以通过watch()
函数直接watch(()=>attrs.xxx)
,结果是不行。这里官网有些,一开始自己没注意:
attrs 和 slots 是有状态的对象,它们总是会随组件本身的更新而更新。这意味着你应该避免对它们进行解构,并始终以 attrs.x 或 slots.x 的方式引用 property。请注意,与 props 不同,attrs 和 slots 是非响应式的。如果你打算根据 attrs 或 slots 更改应用副作用,那么应该在 onUpdated 生命周期钩子中执行此操作。
所以要响应式处理attrs
和slots
,就需要:
import { onUpdated, reactive, watch, watchEffect } from 'vue'
export default {
setup(props, { attrs }) {
function _handleAttrsChange() {
console.log('attrs===')
console.log(attrs)
}
onUpdated(() => {
_handleAttrsChange()
})
// props和data可以正常使用watch函数
watchEffect(() => {
console.log('propsXxx===')
console.log(props.xxx)
})
const state = reactive({ count: 0 })
watch(() => state.count, (now, old) => {
//
})
},
}
VueRouter不能直接使用含有props的组件
我有一个地址列表AddressList
,需要通过props
接收父组件参数:
// router.js
export default {
name: 'AddressList',
props: {
propName: String,
},
}
通过组件调用,没有问题。但是配置为vue-router
项时会报错:
export default {
routes: [
{
path: 'address_list',
component: () => import( 'AddressList.vue'),
},
],
}
TypeError: Cannot add property __props, object is not extensible
既然不能直接将组件作为route
使用,那么就在其他页面中调用就好了
// router.js
export default {
routes: [
{
path: 'address_list',
component: () => import( 'Page.vue'),
meta: { component: 'AddressList' },
},
],
}
<!--Page.vue-->
<template>
<component :is="component" />
</template>
<script lang="ts">
import AddressList from '/@/views/AddressList.vue'
import { defineComponent } from 'vue'
export default defineComponent({
name: 'Page',
components: { AddressList },
computed: {
component () {
return this.$route.meta.component
},
},
})
</script>
相关文章
最后
关注公众号:前端开发博客,回复 1024,领取前端进阶资料
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。