我这里是使用yarn包管理工具安装,使用npm或者pnpm的同理 执行下面shell命令创建一个新的项目模板
yarn create vite 项目名称 --template vue-ts
创建成功后我们使用vscode编辑器打开项目,其中目录结构如下图:
此时我们执行yarn install安装所需要的依赖包,安装完必执行yarn dev会打开vite+vue的欢迎界面
// 执行下面命令
eslint --init
按照提示我们依次选择以下几个主要选项
? How would you like to use ESLint? ... To check syntax onlyTo check syntax and find problems
> To check syntax, find problems, and enforce code style
? What type of modules does your project use? ...
> JavaScript modules (import/export)CommonJS (require/exports)None of these
? Which framework does your project use? ... React
> Vue.jsNone of these
? Does your project use TypeScript? » No / Yes
选择推荐风格,这里我们直接选第一个跟着引导去选择aribn或者standard
> Use a popular style guideAnswer questions about your styleInspect your JavaScript file(s)
选择完后,需要安装一些eslint相关的依赖包,默认是用npm安装,安装完会自动生成一个eslintrc.js,内容如下
{"env": {"browser": true,"es2021": true,"node": true},"extends": ["eslint:recommended","plugin:vue/vue3-essential","plugin:@typescript-eslint/recommended","plugin:prettier/recommended"],"overrides": [],"parser": "vue-eslint-parser","parserOptions": {"ecmaVersion": "latest","parser": "@typescript-eslint/parser","sourceType": "module"},"plugins": ["vue","@typescript-eslint"],"rules": {"@typescript-eslint/ban-types": ["error",{"extendDefaults": true,"types": {"{}": false}}],"vue/multi-word-component-names":"off"}
}
创建.eslintignore文件,忽略eslint不需要检查的文件
/index.html
/lambda/
/scripts
/config
/plugins
.history
/tsconfig.json
/src/vite-env.d.ts
安装prettier
yarn add prettier -D
解决 eslint 和 prettier 冲突安装 eslint-config-prettier
解决 ESLint
中的样式规范和 prettier
中样式规范的冲突
,以 prettier
的样式规范为准
,使 ESLint 中的样式规范自动失效eslint-plugin-prettier
eslint-plugin-prettier插件会调用prettier对你的代码风格进行检查,其原理是先使用prettier对你的代码进行格式化,然后与格式化之前的代码进行对比,如果过出现了不一致,这个地方就会被prettier进行标记。接下来,我们需要在rules中添加,"prettier/prettier": "error"
,表示被prettier标记的地方抛出错误信息。\
//.eslintrc.js
{"plugins": ["prettier"],"rules": {"prettier/prettier": "error"}
}
项目下新建 .prettierrc.json
文件
module.exports = {tabWidth: 2,jsxSingleQuote: true,jsxBracketSameLine: true,printWidth: 100,singleQuote: true,semi: false,overrides: [{files: '*.json',options: {printWidth: 200,},},],arrowParens: 'always',
}
在vite-config.ts中添加如下配置
base: './', // 设置打包路径resolve: {alias: {'@': path.resolve(__dirname, 'src'),},extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'],}
在tsconfig.json中增加配置
"compilerOptions": {"baseUrl": ".","paths": {"@/*": ["./src/*"]},
}
此时的@就可以指向我们的src目录了
在src文件夹下创建shims-vue.d.ts文件 添加我们import引入时ts报错的模块
// 例如
declare module 'axios';
declare module 'element-plus';
declare module 'js-cookie';
elementUi的配置非常简单这里我就不说了,直接参考官方的配置指南就可以了 element-plus.gitee.io/zh-CN/guide…
// 我们一次把所有模块都安装上
yarn add vuex vue-router less less-loader
less使用跟vue2没有区别,安装完loader可以直接在style里面制定lang=“less”
我们在src目录下创建store文件夹,store文件夹下分别创建index.ts 和modules文件夹,其中modules下面是我们的每个不通的store
因为vuex修改了初始化的方法,这里给vue2使用时略有区别,使用createStore创建store仓库
import { createStore } from 'vuex';
import getters from './getters';
import userStore from './modules/user';
import systemStore from './modules/system';
import permissionStore from './modules/permission';
const storeObj: any = {modules: {user: userStore,system: systemStore,permission: permissionStore,},getters,
};
export default createStore(storeObj);
ps:我这里分别引入了三个store,还可以使用import.meta.globEager引入所有的文件,写个通用函数来解析最好,因为vite中乜有require,这个功能既类似于require.context
配置完以上回到src/main.ts中,引入store
挂在store
import store from './store';
app.use(store)
在src文件夹下创建router文件夹
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
const constantRoutes: Array = [{path: '/',name: 'layout',component: () => import('@/pages/layout/index.vue'),},{path: '/login',name: 'login',component: () => import('@/pages/login/index.vue'),},{path: '/404',name: '404',component: () => import('@/pages/error-page/404.vue'),},
];
// 权限用动态路由添加
export const asyncRoutes: any = [];
export const router = createRouter({history: createWebHistory(),routes: constantRoutes,
});
// 权限用动态路由移除
export function resetRouter() {asyncRoutes.forEach((route: any) => {router.removeRoute(route.name);});
}
回到main.ts,仍然是引入挂载
import router from './router';
app.use(router)
这里到了重点权限控制,我这里使用动态路由控制权限
// 角色权限,动态路由
const whiteList = ['/login', '/404'];
let pageRefresh = true;
router.beforeEach(async (to, from) => {// 如果是login或者404页面直接跳转过去if (whiteList.indexOf(to.path) !== -1) {if (to.path == '/login') {pageRefresh = true;}return true;}// 获取token,如果用户没登录,则跳转登录页面const token = store.getters.token;if (!token) {router.push({path: 'login',query: {redirect: to.path,},});} else {//如果为true说明已添加过直接跳过if (!pageRefresh) {return true;} else {//后端获取动态路由await store.dispatch('permission/generateRoutes') // 到store下的permission中执行路由添加.then((res: any) => {console.log(router.getRoutes());// 没有子路由时则回首页if (res && to.matched.length === 0) {router.push(to.fullPath);}});pageRefresh = false;}}
});
import { asyncRoutes, router } from '@/router';
import { RouteRecordRaw } from 'vue-router';
const _modules = import.meta.glob('@/pages/**/*.vue');
/**
* 后台查询的菜单数据拼装成路由格式的数据
* @param routes
*/
export function generaMenu(routes: any, data: any) {data.forEach((item: any) => {const menu = {path: item.path,component: () => _modules[`/src/pages${item.component}.vue`],// 这里有坑,动态引入的组件无法添加,我尝试了很多方式,最后使用## defineAsyncComponent引入解决的children: [],name: item.menuName,meta: {title: item.title,icon: item.icon,noCache: item.noCache,},};if (item.children) {generaMenu(menu.children, item.children);}routes.push(menu);});
}
const permission = {namespaced: true,state() {return {routes: [],};},mutations: {SET_ROUTES: (state: any, routes: any) => {state.routes = routes;},},actions: {generateRoutes({ commit }: any) {return new Promise((resolve) => {getRoutes().then((res: any) => {if (res.code === 200) {const { data } = res;const list = data[0].children;//获取router添加到asyncrouter中generaMenu(asyncRoutes, list);console.log('调整好的路由', asyncRoutes);// 添加路由asyncRoutes.forEach((itemRouter: RouteRecordRaw) => {router.addRoute('layout', itemRouter);});commit('SET_ROUTES', list);resolve(list);} else {ElMessage.error('菜单数据获取异常');}});});},},
};
export default permission;
end:到这里我们基本完成了所有的配置,赶紧尝试一下吧!!!
整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。
有需要的小伙伴,可以点击下方卡片领取,无偿分享