vue.config.js配置、集成vue-router、集成vuex、集成Element-Plus

357 阅读5分钟

1. vue.config.js配置

我们都知道vue-cli是基于webpack来配置的,但是有时候我们对于vue-cli的默认配置不是很满意,这时候我们可以通过修改webpack源码(不推荐)来达到我们的目的,另外一种方式就是通过vue.config.js来配置,最后vue.config.js的配置会被合并到webpack里面的。如果不知道怎么配置,可以参考官网:cli.vuejs.org/zh/config/

vue.config.js有三种配置方式:

  1. 方式一:直接通过CLI提供给我们的选项来配置,这些配置可能和webpack配置名字不一样,但是都是一一对应的

    • publicPath:配置应用程序部署的子目录(默认是/,相当于部署在 https://www.my-app.com/),如果想修改成https://www.my-app.com/why,就配置publicPath:'/why'
    • outputDir:修改输出的文件夹,默认是dist文件夹,如果想修改成build文件夹,可以配置outputDir:'./bulid'
  2. 方式二:通过configureWebpack修改webpack的配置

    • 可以是一个对象,这里的属性和webpack的属性名字是一样的,最后会被合并
    • 可以是一个函数,会接收一个config,config就是原来的webpack配置,我们可以拿到config去修改原来的配置
  3. 方式三:通过chainWebpack可以链式修改webpack的配置

    • 也是一个函数, 返回config, 我们可以链式修改webpack原来的配置
const path = require('path')

module.exports = {
  // 配置方式1: CLI提供的属性
  outputDir: './build', // 输入文件夹,默认dist文件夹
  // publicPath: './',

  devServer: {
    // open: true, //执行命令之后自动打开浏览器
    host: 'localhost',
    port: 8888, //设置端口
    https: false,
    hotOnly: false,
    // 使用devServer里面的proxy配置跨域访问的问题
    // proxy: {
    //   '^/api': {
    //     target: 'http://152.136.185.210:4000',
    //     pathRewrite: {
    //       '^/api': ''
    //     },
    //     changeOrigin: true
    //   }
    // }
  },
  // 配置方式2.1: 可以是一个对象,这里的属性和webpack的属性名字是一样的,最后会被合并
  configureWebpack: {
    resolve: {
      alias: {
        // 因为webpack默认已经配置了@为src,所以可以直接写@/components
        components: '@/components'
      }
    }
  }

  // 配置方式2.2
  // 可以是一个函数,会接收一个config,config就是原来的webpack配置,我们可以拿到config去修改原来的配置
  // configureWebpack: (config) => {
  //   config.resolve.alias = {
  //     //做了覆盖之后webpack默认配置的src就没了,我们要重新配置
  //     '@': path.resolve(__dirname, 'src'),
  //     components: '@/components'
  //   }
  // }

  // 配置方式3:也是一个函数,返回config,我们可以链式修改webpack原来的配置
  // chainWebpack: (config) => {
  //   config.resolve.alias
  //     .set('@', path.resolve(__dirname, 'src'))
  //     .set('components', '@/components')
  // }
}

这三种方式使用哪一种都可以,只要达到修改的目的就行。

2. 集成vue-router

刚开始创建项目的时候我们没有选择路由,现在我们手动集成路由。

  1. 安装vue-router的最新版本
npm install vue-router@next
  1. 创建router对象

创建router文件夹,router文件夹里面创建index.ts文件,代码如下:

import { createRouter, createWebHashHistory } from 'vue-router'
// 导入类型注解,添加一个type代表我们导入的东西不是其他,而是一个类型,不加也没事
import type { RouteRecordRaw } from 'vue-router'

// 使用类型注解,代表数组里面装的都是RouteRecordRaw
const routes: RouteRecordRaw[] = [
  {
    path: '/',
    redirect: '/login'
  },
  {
    path: '/login',
    // 路由懒加载
    component: () => import('@/views/login/login.vue')
  },
  {
    path: '/main',
    component: () => import('@/views/main/main.vue')
  }
]

const router = createRouter({
  routes,
  history: createWebHashHistory()
})

export default router

3. 使用router

在main.ts里面使用router,代码如下:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router)
app.mount('#app')
  1. 在App.vue中配置跳转
<template>
  <div id="app">
    <router-link to="/login">登录</router-link>
    <router-link to="/main">首页</router-link>
    <router-view></router-view>
  </div>
</template>

3. 集成vuex

  1. 安装vuex
npm install vuex@next
  1. 创建store对象

创建store文件夹,store文件夹里面创建index.js文件,代码如下:

import { createStore } from 'vuex'

const store = createStore({
  state: () => {
    return {
      name: 'coderwhy'
    }
  },
  mutations: {},
  getters: {},
  actions: {}
})

export default store

3. 使用store

在main.ts里面使用store,如下:

createApp(App).use(router).use(store).mount('#app')
  1. 在App.vue中使用
<h2>{{ $store.state.name }}</h2>

其实vuex对于TS的支持相对来说差一点,所以很多人使用第三方库Pinia,第三方库会好一点点。

Pinia:['pi:nə]

4. 集成Element-Plus

相信很多同学在Vue2中都使用过Element-UI,Element-Plus是一套为开发者、设计师和产品经理准备的基于 Vue 3.0 的桌面端组件库。它的使用方式和很多其他的组件库是一样的,所以学会Element-Plus,其他类似于VantUI、NaiveUI、ant-design-vue都是差不多的。

安装element-plus:

npm install element-plus

1 - 全局引入

一种引入element-plus的方式是全局引入,代表的含义是所有的组件和插件都会被自动注册。

优点:集成简单,缺点:全部会打包(不推荐)

main.ts文件:

// 1. 引入包
import ElementPlus from 'element-plus'
// 2. 引入样式
import 'element-plus/lib/theme-chalk/index.css'

import router from './router'
import store from './store'

// 3. 挂载
createApp(App).use(router).use(store).use(ElementPlus).mount('#app')

在App.vue里面直接使用即可:

<el-button type="danger"> 哈哈哈哈  </el-button>

2 - 按需引入

按需引入也就是在开发中用到某个组件对某个组件进行引入。

优点:包会小一些,缺点:集成起来麻烦一些(推荐)

<template>
  <div id="app">
    // 3. 使用组件
    <el-button>默认按钮</el-button>
    <el-button type="primary">主要按钮</el-button>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
// 1. 引入组件
import { ElButton } from 'element-plus'

// 2. 注册组件
export default defineComponent({
  name: 'App',
  components: {
    ElButton
  }
})
</script>

<style lang="less">
</style>

但是我们会发现是没有对应的样式的,引入样式有两种方式:

  1. 全局引用样式(像之前做的那样),不推荐,因为一些没用到的样式也会被打包进来
  2. 局部引用样式

局部引用样式我们可以使用如下方式单独引入,但是一个一个引入太麻烦了。

截屏2023-10-30 14.38.24.png

如果我们想要引入组件的时候自动引入对应的样式,可以使用babel的插件。

  1. 安装babel的插件
npm install babel-plugin-import -D
  1. 配置babel.config.js
module.exports = {
  plugins: [
    // 表示的意思是当我们通过import引入element-plus的组件的时候,同时引入对应的样式
    [
      'import',
      {
        libraryName: 'element-plus',
        customStyleName: (name) => {
          return `element-plus/lib/theme-chalk/${name}.css`
        }
      }
    ]
  ],
  presets: ['@vue/cli-plugin-babel/preset']
}

这个插件只会在我们用到某个组件的时候同时给我们引用对应的css,但是我们的base或者说一些icon图标是不会帮我们引用进去的,所以对于基本的东西,我们可以全局进行引用。

import 'element-plus/lib/theme-chalk/base.css'

但是这里依然有个弊端,这些组件我们在多个页面或者组件中使用的时候,都需要导入并且在components中进行注册,所以我们可以使用app.component进行全局注册。

为了防止main.ts里面代码太多,这里我们可以封装一下。我们新建global文件夹,在里面新建register-element.ts文件和index.ts文件。

register-element.ts文件代码如下:

import { App } from 'vue'
// 导入base
import 'element-plus/lib/theme-chalk/base.css'
import {
  ElButton,
  ElCheckbox,
  ElForm,
  ElFormItem,
  ElInput,
  ElLink,
  ElRadio,
  ElTabPane,
  ElTabs
} from 'element-plus'

const components = [
  ElButton,
  ElForm,
  ElFormItem,
  ElInput,
  ElRadio,
  ElTabs,
  ElTabPane,
  ElCheckbox,
  ElLink
]

export default function (app: App): void {
  for (const component of components) {
    // 第一个参数是组件的名字,第二个参数是组件
    app.component(component.name, component)
  }
}

index.ts文件代码如下:

import { App } from 'vue'
import registerElement from './register-element'

export function registerApp(app: App): void {
  registerElement(app)
}

main.ts代码如下:

import { createApp } from 'vue'
import { registerApp } from './global'
import App from './App.vue'

const app = createApp(App)
registerApp(app)
app.mount('#app')

如果我们想通过插件的方式,也就是使用app.use()的方式,那么如何写代码呢? 前面我们说过,app.use()如果传入一个function,那么这个function默认 会有个app参数,如果传入一个对象,那么默认会执行这个对象的install方法,install方法也有一个app参数。所以,代码修改如下:

index.ts代码如下:

import { App } from 'vue'
import registerElement from './register-element'

export function globalRegister(app: App): void {
  // 调用registerElement, 并把app传进去
  app.use(registerElement)
}

main.ts代码如下:

import { createApp } from 'vue'
import { globalRegister } from './global'
import App from './App.vue'

const app = createApp(App)
// 调用globalRegister,并把app传进去
app.use(globalRegister)
app.mount('#app')