Vue2.7 如何使用Vue3新增的useStore、useRouter、useRoute
在 Vue 2.7 中,从 Vue 3 移植回了的一些特性,使得 Vue 2 用户也可以享有Vue3的便利。但是很多Vue3的东西是不能直接使用的。最常用的就是Vue3中的useStore、useRouter、useRoute几个hook。以下将介绍如何在Vue2.7中使用这些hook。(参考了网上其他大佬的内容和github上的部分源码):
1、新建VueApi.ts文件。useStore、useRouter、useRoute 都从这个模块中引用(区别于Vue3直接从Vue模块中引用)
2、实现:
/** 对 vue-router 和 vuex 做兼容处理,以便使用组合式API */
import { effectScope, getCurrentInstance, reactive } from 'vue';
import { Route } from 'vue-router';
import { Store } from 'vuex';
/**
* 使用vuex的$store
* @returns this.$store
*/
export const useStore = () => {
const vm = getCurrentInstance();
if (!vm) throw new Error('useStore() can only be used inside setup() or functional components.');
return vm.proxy.$store;
};
/**
* 使用vue-router的$router
* @returns this.$router
*/
export const useRouter = () => {
const vm = getCurrentInstance();
if (!vm) throw new Error('useRouter() can only be used inside setup() or functional components.');
return vm.proxy.$router;
};
let currentRoute: Route;
/**
* 使用vue-router的$route
* @returns this.$route
*/
export function useRoute() {
const router = useRouter();
if (!router) {
return undefined;
}
if (!currentRoute) {
const scope = effectScope(true);
scope.run(() => {
currentRoute = reactive(assign({}, router.currentRoute));
router.afterEach((to) => {
assign(currentRoute, to);
});
});
}
return currentRoute;
}
/**
* 合并对象
* @param {object} target 原对象
* @param {object} source 新对象
* @returns {object} 合并后的对象
*/
function assign(target: any, source: any) {
for (const key of Object.keys(source)) {
target[key] = source[key];
}
return target;
}
3、代码中使用(在选项式api中不能使用hook,请直接使用this.xxx的方式)
<script setup>
import { useRoute, useRouter, useStore } from '@/utils/vueApi';
const store = useStore();
const router = useRouter();
const route = useRoute();
...
</script>