• JavaScript - 手写call、apply和bind函数


    一、使用vite初始化

    我这里是使用yarn包管理工具安装,使用npm或者pnpm的同理 执行下面shell命令创建一个新的项目模板

    yarn create vite 项目名称 --template vue-ts

    创建成功后我们使用vscode编辑器打开项目,其中目录结构如下图:

    此时我们执行yarn install安装所需要的依赖包,安装完必执行yarn dev会打开vite+vue的欢迎界面

    二、配置eslint,prettier

    1:eslint初始化
    // 执行下面命令
    eslint --init 
    
    • 1
    • 2

    按照提示我们依次选择以下几个主要选项

    ? 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 
    
    • 1
    • 2
    ? What type of modules does your project use? ... 
    > JavaScript modules (import/export)CommonJS (require/exports)None of these 
    
    • 1
    • 2
    ? Which framework does your project use? ... React
    > Vue.jsNone of these 
    
    • 1
    • 2
    ? Does your project use TypeScript? » No / Yes 
    
    • 1

    选择推荐风格,这里我们直接选第一个跟着引导去选择aribn或者standard

    > Use a popular style guideAnswer questions about your styleInspect your JavaScript file(s) 
    
    • 1

    选择完后,需要安装一些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"}
    
    } 
    
    • 1
    • 2
    • 3

    创建.eslintignore文件,忽略eslint不需要检查的文件

    /index.html
    /lambda/
    /scripts
    /config
    /plugins
    .history
    /tsconfig.json
    /src/vite-env.d.ts 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    2:配置prettier

    安装prettier

    yarn add prettier -D 
    
    • 1

    解决 eslint 和 prettier 冲突安装 eslint-config-prettier解决 ESLint 中的样式规范和 prettier 中样式规范的冲突,以 prettier 的样式规范为准,使 ESLint 中的样式规范自动失效eslint-plugin-prettiereslint-plugin-prettier插件会调用prettier对你的代码风格进行检查,其原理是先使用prettier对你的代码进行格式化,然后与格式化之前的代码进行对比,如果过出现了不一致,这个地方就会被prettier进行标记。接下来,我们需要在rules中添加,"prettier/prettier": "error",表示被prettier标记的地方抛出错误信息。\

    //.eslintrc.js
    {"plugins": ["prettier"],"rules": {"prettier/prettier": "error"}
    } 
    
    • 1
    • 2
    • 3

    项目下新建 .prettierrc.json 文件

    module.exports = {tabWidth: 2,jsxSingleQuote: true,jsxBracketSameLine: true,printWidth: 100,singleQuote: true,semi: false,overrides: [{files: '*.json',options: {printWidth: 200,},},],arrowParens: 'always',
    } 
    
    • 1
    • 2

    三、配置路径别名,处理import引入时ts报错

    在vite-config.ts中添加如下配置

     base: './', // 设置打包路径resolve: {alias: {'@': path.resolve(__dirname, 'src'),},extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'],} 
    
    • 1

    在tsconfig.json中增加配置

    "compilerOptions": {"baseUrl": ".","paths": {"@/*": ["./src/*"]},
    } 
    
    • 1
    • 2

    此时的@就可以指向我们的src目录了

    在src文件夹下创建shims-vue.d.ts文件 添加我们import引入时ts报错的模块

    // 例如
    declare module 'axios';
    declare module 'element-plus';
    declare module 'js-cookie'; 
    
    • 1
    • 2
    • 3
    • 4

    四、配置element-plus

    elementUi的配置非常简单这里我就不说了,直接参考官方的配置指南就可以了 element-plus.gitee.io/zh-CN/guide…

    五、配置vuex、vue-route、less开发环境

    // 我们一次把所有模块都安装上
    yarn add vuex vue-router less less-loader 
    
    • 1
    • 2

    less使用跟vue2没有区别,安装完loader可以直接在style里面制定lang=“less”

    1:配置vuex

    我们在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); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ps:我这里分别引入了三个store,还可以使用import.meta.globEager引入所有的文件,写个通用函数来解析最好,因为vite中乜有require,这个功能既类似于require.context

    配置完以上回到src/main.ts中,引入store

    挂在store

    import store from './store';
    app.use(store) 
    
    • 1
    • 2
    2:配置vue-router

    在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);});
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    回到main.ts,仍然是引入挂载

    import router from './router';
    app.use(router) 
    
    • 1
    • 2

    这里到了重点权限控制,我这里使用动态路由控制权限

    // 角色权限,动态路由
    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;}}
    }); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    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; 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    end:到这里我们基本完成了所有的配置,赶紧尝试一下吧!!!

    最后

    整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



    有需要的小伙伴,可以点击下方卡片领取,无偿分享

  • 相关阅读:
    看动画,学Java基础教程12:关键字
    【面试题精讲】Java包装类缓存机制
    2023/9/12 -- C++/QT
    光伏电站传统运维模式难点和解决方案
    WPF中动画教程(DoubleAnimation的基本使用)
    第二证券|行业重磅白皮书发布,超高清视频产业规模剑指3万亿
    目标检测YOLO实战应用案例100讲-基于改进YOLOv3的目标检测模型研究与应用(下)
    mysql的索引
    js组合键监听
    linux下,如何查看一个文件的哈希值md5以及sha264
  • 原文地址:https://blog.csdn.net/web2022050903/article/details/127429964