resolve.alias配置别名@别名可在<template> <script> <style>直接使用assets等别名在<template> <style>内使用前需加~(loader会将其作为模块解析)#作为别名在<template> <style>中无效 仍需将图片等资源作为模块导入
三种异步组件:
- 普通函数异步组件
Vue.component('async-example', function(resolve, reject) {
// require(dependencies: String[], [callback: function(...)])
// webpack module方法
// 类似`require.ensure` 将拆分给定的依赖到不同的bundle中,用以异步加载
// `callback`将通过dependencies数组中的每个依赖项的导出进行调用
require(['./my-async-component'], resolve)
})Promise异步组件
// `import` 返回一个 `Promise` 对象
Vue.component('async-promise', () => import('./my-async-component'))- 高级异步组件
Vue.component('async-higher', () => ({
// 要加载的组件(应该是个Promise)
component: import('./MyComp'),
// 当异步组件在加载时使用的组件
loading: LoadingComponent,
// 加载失败使用的组件
error: ErrorComponent,
// Delay before showing the loading component. Default: 200ms.
delay: 200,
// The error component will be displayed if a timeout is provided and exceeded. Default: Infinity.
timeout: 3000
}))Object.defineProperty定义响应式对象(getter setter)
- 全局注册
RouterView和RouterLink组件 - 添加全局
$router和$route属性 - 启用
useRouter()和useRoute()组合式函数 - 触发路由器解析初始路由
- 导航被触发
- 在失活的组件里调用
beforeRouteLeave守卫 - 调用全局的
beforeEach - 在重用的组件里调用
beforeRouteUpdate(2.2+) - 在路由配置里调用
beforeEnter - 解析异步路由组件
- 在被激活的组件里调用
beforeRouteEnter - 调用全局的
beforeResolve(2.5+) - 导航被确认
- 调用全局的
afterEach - 触发DOM更新
- 调用
beforeRouteEnter守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入
- v3
// @/router/index.js
// 避免服务器端渲染内存溢出
import Router from 'vue-router'
export default () => {
return new Router({
})
}- v4
// @/router/index.js
import { createRouter, createWebHashHistory } from 'vue-router'
export default createRouter({
history: createWebHashHistory()
})import { createApp } from 'vue'
import router from '@/router/index'
const app = createApp({})
app.use(router)- v3
<transition name="fade">
<router-view />
</transition>- v4
<router-view v-slot="{ Component }">
<transition name="fade">
<Component :is="Component" />
</transition>
</router-view>- 弃用
mutation - 无需动态添加
Store,默认都是动态的 - 不再有嵌套结构的模块
- 不再有可命名的模块
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// 破坏了响应性
// const { name, doubleCount } = store
const { name, doubleCount } = storeToRefs(store)
// 作为 action 的 increment 可以直接解构
const { increment } = store- 选项式API
$reset()内部,会调用state()函数来创建一个新的状态对象,并用它替换当前状态
const store = useStore();
store.$reset();- 组合式API
const useCounterStore = defineStore('counter', () => {
const count = ref(0);
function $reset() {
count.value = 0;
}
return { count, $reset };
});mapWritableState() 不能像 mapState() 一样传递一个函数
import { mapWritableState } from 'pinia';
import { useCounterStore } from '../stores/counter';
export default {
computed: {
// 可以访问组件中的 `this.count` 并允许设置它
// this.count++
// 与从 store.count 中读取的数据相同
...mapWritableState(useCounterStore, ['count']),
// 与上述相同,但将其注册为 this.myOwnName
...mapWritableState(useCounterStore, {
myOwnName: 'count'
})
}
}- 可同时更改多个属性
store.$patch({
count: store.count + 1,
age: 120,
name: 'DIO'
});- 接受函数
store.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 }),
state.hasChanged = true
});$subscrible() 相比 watch() 在patch后只触发一次
cartStore.$subscrible((mutation, state) => {
// import { MutationType } from 'pinia'
mutation.type // 'direct' | 'patch object' | 'patch function'
// 和 cartStore.$id 一样
mutation.storeId // 'cart'
// 只有 mutation.type === 'patch object' 的情况下才可用
mutation.payload // 传递给 cartStore.$patch()的补丁对象
}, {
// 在组件卸载之后仍会保留
detached: true
});import { mapActions } from 'pinia';
import { useCounterStore } from '../stores/counter';
export default {
methods: {
// 访问组件内的 this.increment()
// 与从 store.increment() 调用相同
...mapActions(useCounterStore, ['increment'])
...mapActions(useCounterStore, { myOwnName: 'increment' })
}
}