vue-cli+ts+iview单多页面的配置实践

简介

实现效果:常见的后台管理系统的 demo。地址:https://github.com/MaTonna/vue-cli-ts-ivew
新增了一个react版的。地址: https://github.com/MaTonna/react-ts-antd-router

在这里插入图片描述

项目启动

安装依赖

npm i

项目启动

npm run serve

http://127.0.0.1:3000/page1/index1/contentCenter2 是单页面的类似后台管理的页面,同时这个系统配置了多页面的
http://127.0.0.1:3000/index,是一个丑陋的首页

安装项

  1. 全局安装新包:npm install -g @vue/cli(要求 node 版本>=8.9,否则会报错要求升级 node,到官网重新下载即可)
  2. 创建项目:vue create hello-world
  3. 安装 less:npm install -D less-loader less
  4. 安装 ts:vue add @vue-typescript,可选用 vue-property-decorator
  5. 安装 babel:vue add @vue/cli-plugin-babel

vue.config.js 具体配置

const path = require('path');
const glob = require('glob');
const title = '测试页面';
const addStyleResource = rule => {
  rule
    .use('style-resource')
    .loader('style-resources-loader')
    .options({
      patterns: [path.resolve(__dirname, './src/css/config.less')]
    });
};

const getPages = () => {
  // 多页面配置,相当于配置html-webpack-plugin
  const pages = {};
  glob.sync('./src/page/**/*.[jt]s?(x)').forEach(item => {
    const filename = item.match(/\.\/src\/page\/(\S*).[jt]s?x?/)[1];
    pages[filename] = {
      title,
      entry: item,
      template: `public/${filename}.html`,
      filename: `${filename}`,
      chunks: ['common', filename],
      chunksSortMode: 'manual',
      inject: true
    };
  });
  return pages;
};

module.exports = {
  pages: getPages(),
  outputDir: './static', //执行build时会在static下生成编译后的文件
  assetsDir: './',
  filenameHashing: false,
  productionSourceMap: false,
  configureWebpack: {
    resolve: {
      alias: {
        '@css': path.join(__dirname, 'src/css'),
        '@router': path.join(__dirname, 'src/router'),
        '@component': path.join(__dirname, 'src/components'),
        '@page': path.join(__dirname, 'src/page')
      }
    }
  },
  chainWebpack: config => {
    // 移除 preload 插件
    config.plugins.delete('preload');
    config.plugins.delete('prefetch');

    // 增加图片超过80k就转成base64编码,否则就为原图片
    config.module
      .rule('images')
      .use('url-loader')
      .loader('url-loader')
      .tap(options => Object.assign(options, { limit: 1024 * 80, publicPath: '../../' }));

    // 压缩图片
    config.module
      .rule('images')
      .use('image-webpack-loader')
      .loader('image-webpack-loader')
      .options({
        quality: '65-80'
      })
      .end();

    // 每个单文件组件和less文件中导入config.less
    const types = ['vue-modules', 'vue', 'normal-modules', 'normal'];
    types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type)));

    // 加入ts
    config.module.rule('ts').use('babel-loader');

    // 移动端 px2rem-loader
    config.module
      .rule('less')
      .oneOf('normal')
      .use('px2rem-loader')
      .loader('px2rem-loader')
      .before('postcss-loader')
      .options({
        remUnit: 37.5,
        remPrecision: 8
      })
      .end();
  },
  css: {
    // 是否开启支持 foo.module.css 样式
    modules: false,
    // 是否使用 css 分离插件 ExtractTextPlugin,采用独立样式文件载入,不采用 <style> 方式内联至 html 文件中
    // 如果为true,iview的icon无法显示
    extract: false,
    // 是否构建样式地图,false 将提高构建速度
    sourceMap: false,
    // css预设器配置项
    loaderOptions: {
      css: {},
      postcss: {}
    }
  },
  // 配置webpack-dev-server
  devServer: {
    open: true,
    host: '127.0.0.1',
    port: 3000,
    https: false,
    hotOnly: false,
    proxy: null,
    before: app => {
      // 将路由加上路径前缀,否则刷新页面就会空白
      // const base = '/page1/index1'.replace(/\/+$/, ''); // 移除尾部斜杠
      // app.get(`${base}/:page/*`, (req, _, next) => {
      //   if (['router1', 'router2', 'router3'].includes(req.params.page)) {
      //     // 把 /<base>/<page>/* 重定向到 /<base>/<page>/
      //     req.url = `${base}/${req.params.page}/`;
      //     next('route');
      //   } else {
      //     next();
      //   }
      // });
    }
  },
  // 构建时开启多进程处理 babel 编译
  parallel: require('os').cpus().length > 1
};

问题的记录

  1. 多页面配置一直失败,filename 的路径一直访问不到,原因是 publicPath 写成了相对路径./,改为默认的/即可
  2. 查看内置配置项的具体配置 vue inspect --rule 要查询的 rule
    在这里插入图片描述
  3. css 无法加载出背景图片,在配置 url-loader 中加入 publicPath: '…/…/'即可
  4. ts 没有识别全局定义的 T,在 shims-tsx.d.ds 中加入
declare global {
  namespace T {
    const add: Function
  }
}
  1. 在配置里加了 router 的 alias,但是会报错@router 没有定义,在 tsconfig.js 加入
"paths": {
  "@/*": [
    "src/*"
  ],
  "@router/*" :["src/router/*"]
},
  1. iview 的 icon 没有生效,修改 vue.config.js 中的 css:{extract: false},但是会使 css 在页面内联 style

  2. 加入 Row、Col 组件 eslint 报错,原因是渲染成 html 标签本身是闭合标签和 iview 标签不匹配,所以在.eslintrc 关闭该条匹配

  "rules": {
    "x-invalid-end-tag": false
  }
  1. 路由传参不起作用,配置路由时加上
props: { default: true, sidebar: true },
  1. 将单页面的#去掉,让路由表现得像多页面,在实例化 router 时加入 mode:history,但是刷新后嵌套路由中的东西会失效,当前的做法是定义一个获取导航栏的 map,然后在 TopMenu 和 SideMenu 中循环获取当前的一级导航和二级导航列表
const router = new VueRouter({
  base: '/page1/index1',
  mode: 'history',
  routes
});
  1. 在切换一级导航时,二级导航的列表没有切换,原因是 route 变化了但是列表没有及时更新,所以在 watch 中监听$route,有变化了就及时更新列表
 watch: {
    $route(to, from) {
      this.getSideMenuList(to.name);
    }
  },
  mounted() {
    this.getSideMenuList(this.$route.name);
  },
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值