Vite2+vue3+ts 使用 router,layout 搭建頁面框架,并做頁面自適應(yīng)

Vite2+vue3+ts 使用 router,layout 搭建頁面框架,并做頁面自適應(yīng)

vue3 對應(yīng)使用的是 vue-router@4 版本, 有新的用,但是向下兼容
本文檔源碼:Lzq811/vite-vue-ts-eslint at vite2+vue3+ts使用vue-router搭建頁面框架 (github.com)

1. 安裝使用 vue-router@4

  1. install

    yarn add vue-router@4 # 一定要@4哦,不然會安裝3版本導(dǎo)致不兼容vue3
    
  2. src 下新建 pages 文件夾,并添加 login/index.vue 、 home/index.vue 文件,并隨便初始化一下組件內(nèi)容。

  3. src 下新建 routes 文件夾,并添加 index.tsxroutesNames.tsx 文件

// index.tsx
import { createRouter, createWebHistory } from 'vue-router'
import * as RouteNames from './routesname'

interface RoutesItem {
  path: string
  component: any
  name?: string
  redirect?: string
}

const routes: Array<RoutesItem> = [
  {
    path: '/',
    redirect: '/home',
    component: () => import('@pages/home/index.vue'),
  },
  {
    path: '/default',
    name: RouteNames.HOME,
    component: () => import('@pages/home/index.vue'),
  },
  {
    path: '/home',
    name: RouteNames.HOME,
    component: () => import('@pages/home/index.vue'),
  },
  {
    path: '/login',
    name: RouteNames.LOGIN,
    component: () => import('@pages/login/index.vue'),
  },
]

// 配置路由
const router = createRouter({
  history: createWebHistory(),
  routes,
})

router.beforeEach((to, from) => {
  const { path: toPath } = to
  const { path: fromPath } = from
  if (toPath === fromPath) {
    return false
  }
})

export default router
// routesNames.tsx
// 管理所有路由名稱
export const LOGIN: string = 'LOGIN'
export const HOME: string = 'HOME'
  1. Login 組件中 點(diǎn)擊 跳轉(zhuǎn)到 Home 頁面

    // Login.vue
    import { useRouter } from 'vue-router'
    
    const router = useRouter()
    
    const jumpTohome: any = (): void => {
      router.replace('/home')
    }
    // 執(zhí)行jumpTohome方法就能跳轉(zhuǎn)到home頁面了
    

2. Home 頁面布局

  1. src/components 文件夾下創(chuàng)建文件 src/components/common/aside/index.vue 、 src/components/common/head/index.vue
// head.vue
<template>
  <div>
    <el-dropdown>
      <el-icon style="margin-right: 15px"><setting /></el-icon>
      <template #dropdown>
        <el-dropdown-menu>
          <el-dropdown-item>View</el-dropdown-item>
          <el-dropdown-item>Add</el-dropdown-item>
          <el-dropdown-item>Delete</el-dropdown-item>
        </el-dropdown-menu>
      </template>
    </el-dropdown>
    <span>Tom</span>
  </div>
</template>

<script lang="ts" setup></script>

<style lang="less" scoped></style>
// asise.vue
<template>
  <el-aside :width="asidewidth" class="aside-com">
    <div class="logo-box">LOGO</div>
    <el-button
      type="primary"
      @click="showCollapse"
      :icon="isCollapse ? Fold : Expand"
    ></el-button>
    <el-menu
      class="menus-box"
      active-text-color="#00A2D8"
      text-color="#fff"
      background-color="rgba(0,0,0,0)"
      :default-openeds="['1', '3']"
      :collapse="isCollapse"
    >
      <el-sub-menu v-for="item in Menus" :key="item.order" :index="item.order">
        <template #title>
          <el-icon :size="24" color="#fff">
            <component :is="item.icon"></component>
          </el-icon>
          <span>{{ item.title }}</span>
        </template>
        <el-menu-item
          v-for="menu in item.children"
          :key="menu.index"
          :index="menu.index"
          >{{ menu.name }}</el-menu-item
        >
      </el-sub-menu>
    </el-menu>
  </el-aside>
</template>

<script lang="ts" setup>
  import { Location, Fold, Expand } from '@element-plus/icons'
  import { onMounted, ref } from 'vue'

  const Menus = ref([
    {
      title: '基礎(chǔ)配置',
      order: 'base',
      icon: Location,
      children: [
        { name: '二級菜單1', index: '1-1' },
        { name: '二級菜單2', index: '1-2' },
      ],
    },
    {
      title: '收發(fā)貨管理',
      order: 'manage',
      icon: Location,
      children: [
        { name: '二級菜單1', index: '2-1' },
        { name: '二級菜單2', index: '2-2' },
      ],
    },
    {
      title: '運(yùn)營監(jiān)控',
      order: 'control',
      icon: Location,
      children: [
        { name: '二級菜單1', index: '2-1' },
        { name: '二級菜單2', index: '2-2' },
      ],
    },
  ])
  const isCollapse = ref(false)
  const asidewidth = ref('180px')

  onMounted(() => {})

  const handleOpen = (key: any, keyPath: any): void => {
    console.log(key, keyPath)
  }
  const handleClose = (key: any, keyPath: any): void => {
    console.log(key, keyPath)
  }
  const showCollapse = (): void => {
    isCollapse.value = !isCollapse.value
    asidewidth.value = !isCollapse.value ? '180px' : '60px'
  }
</script>

<style lang="less">
  .aside-com {
    height: 100%;
    box-sizing: border-box;
    overflow: hidden;
    transition: all 0.25s linear;
    background-color: #1f2f48;
    .logo-box {
      width: 100%;
      height: 60px;
      background-color: rgba(255, 255, 255, 0.4);
      text-align: center;
      line-height: 60px;
    }
    .menus-box {
      border: none;
      transition: all 0.2s linear;
    }
  }
</style>
  1. 修改 home/index.vue
<template>
  <el-container class="home-page">
    <aside></aside>
    <el-container>
      <el-header class="head-com"><head></head></el-header>
      <el-main> 主體內(nèi)容 </el-main>
    </el-container>
  </el-container>
</template>
<script lang="ts" setup>
  import Aside from '@components/common/aside/index.vue'
  import Head from '@components/common/head/index.vue'
</script>

<style lang="less" scoped>
  .home-page {
    height: 100%;
  }
  .head-com {
    width: 100%;
    background-color: #1f2f48;
  }
</style>
  1. 其中 __dirname找不到的解決辦法

    yarn add @types/node --save-dev
    
  2. 配置 alias 路徑別名

    // vite.config.ts
    resolve: {
        alias: {
          // 如何 __dirname 找不到 需要 yarn add @types/node --save-dev
          '@': path.resolve(__dirname, 'src'),
          '@api': path.resolve(__dirname, 'src/api'),
          '@pages': path.resolve(__dirname, 'src/pages'),
          '@routes': path.resolve(__dirname, 'src/routes'),
          '@components': path.resolve(__dirname, 'src/components')
        }
      },
    

3. 頁面自適應(yīng)

  1. 安裝
yarn add postcss-plugin-px2rem
yarn add amfe-flexible
  1. 修改配置

    // main.ts
    import 'amfe-flexible'
    
    // vite.config.ts  一定要注意 postcss 的位置,不要寫在了 preprocessorOptions 對象里面
    css: {
        preprocessorOptions: {
          less: {
            javascriptEnabled: true,
            // 這樣就能全局使用 src/assets/styles/base.less 定義的 變量
            additionalData: `@import "${path.resolve(__dirname, 'src/assets/styles/reset.less')}";`
          }
        },
        postcss: {
          plugins: [
            require('postcss-plugin-px2rem')({
              rootValue: 192, //換算基數(shù), 默認(rèn)100  ,這樣的話把根標(biāo)簽的字體規(guī)定為1rem為50px,這樣就可以從設(shè)計(jì)稿上量出多少個px直接在代碼中寫多上px了。
              // unitPrecision: 5, //允許REM單位增長到的十進(jìn)制數(shù)字。
              //propWhiteList: [],  //默認(rèn)值是一個空數(shù)組,這意味著禁用白名單并啟用所有屬性。
              // propBlackList: [], //黑名單
              exclude: /(node_module)/, //默認(rèn)false,可以(reg)利用正則表達(dá)式排除某些文件夾的方法,例如/(node_module)/ 。如果想把前端UI框架內(nèi)的px也轉(zhuǎn)換成rem,請把此屬性設(shè)為默認(rèn)值
              // selectorBlackList: [], //要忽略并保留為px的選擇器
              // ignoreIdentifier: false,  //(boolean/string)忽略單個屬性的方法,啟用ignoreidentifier后,replace將自動設(shè)置為true。
              // replace: true, // (布爾值)替換包含REM的規(guī)則,而不是添加回退。
              mediaQuery: false, //(布爾值)允許在媒體查詢中轉(zhuǎn)換px。
              minPixelValue: 3 //設(shè)置要替換的最小像素值(3px會被轉(zhuǎn)rem)。 默認(rèn) 0
            })
          ]
        }
      }
    
  2. 查看頁面的文字或者盒子大小是否已經(jīng)從 px 單位 變成了 rem 單位。

本文的對應(yīng)源碼地址: Lzq811/vite-vue-ts-eslint at vite2+vue3+ts使用vue-router搭建頁面框架 (github.com)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容