/fast-vue3

一个快速开箱即用,大厂必备,配置齐全的Vue3+vite模板

Primary LanguageVue

FastVue3

fast-vue3,是Vue3+Vite2.7+TypeScript+Pinia等Vue的开发工具链。融入了当前比较主流的工具链,可以直接开箱使用,方便小伙伴学习,最好的学习方式——边用边学边学边用~

image.png

特点

Vue Vite TypeScript Pinia ESLint Pnpm Axios Prettier Less Taiwind

  • 💕 fast-vue3就不赘述了,框架基座支持Vue3+Vite2.7+TypeScript+Pinia
  • 🔌 支持husky和 lint-staged,大厂团队代码规范协作必备
  • 🖼️ 支持svg图标,已封装一个简单的SvgIcon组件,可以直接读取文件下的svg
  • ⚙️ 支持Plop,代码文件自动生成,提供三种预设模板pages,components,store等可自定义
  • 📦 支持axios(ts版),已封装了主流的拦截器,请求调用等方法
  • 👽 支持router,store模块化,内置生成路由钩子
  • 🏗 支持vw/vh移动端布局兼容,也可以使用plop自己配置生成文件

使用

一键三连: Star 或 Fork 或 可视化仓库

# 拉取仓库代码
git clone  https://github.com/MaleWeb/fast-vue3.git

# 进入项目文件夹
cd fast-vue3 

# 安装项目依赖
pnpm install

# 运行
pnpm run dev

如果不报错,恭喜你点火成功。否则,请看下面常见问题。

如果你已经了解本模板,建议你拉取 template 分支进行项目开发,该分支不含任何示例代码。

# clone  template 分支
git clone -b template https://github.com/MaleWeb/fast-vue3.git

配置

为了方便其他小伙伴了解配置,这里简单介绍一些核心部分。资料部分也有详细的配置,建议大家直接阅读官方文档。关于vite vue pinia的配置见可视化仓库

TypeScript

TS几乎已然成为了大厂必备技能,这两年也频繁出现在面试题与高级前端考核中。所以,我果断默认了TS。可能对一些小伙伴比较残忍,学吧。

   # 安装ts相关依赖
   pnpm add @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser

根目录配置tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": [
      "esnext",
      "dom"
    ],
    "types": [
      "node"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "**/*.ts"
  ]
}

代码规范

目前多数大厂团队使用husky + lint-staged来约束代码规范,通过pre-commit实现lint检查、单元测试、代码格式化等。 IDE 配置(.editorconfig)、ESLint 配置(.eslintrc.js 和 .eslintignore)、StyleLint 配置(.stylelintrc 和 .stylelintignore),详细请看对应的配置文件。

关闭代码规范
如果不想使用,将 src/ 目录分别加入 .eslintignore 和 .stylelintignore 进行忽略即可。

SVG支持

随着浏览器兼容性的提升,SVG的性能逐渐凸显,很多大厂团队都在创建自己的SVG管理库,后面工具库会有推荐。

这里将svg组件化,正好算是一个小demo。创建文件夹src/asstes/icons/svg,将svg图标放在svg下面,通过name即可使用。

# 安装svg依赖
pnpm add vite-plugin-svg-icons

配置vite.config.ts

import viteSvgIcons from 'vite-plugin-svg-icons';
export default defineConfig({
plugins:[
...
 viteSvgIcons({
    // 指定需要缓存的图标文件夹
    iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
    // 指定symbolId格式
    symbolId: 'icon-[dir]-[name]',
  }),
]
...
})

封装SvgIcon组件

<template>
    <svg aria-hidden="true" class="svg-icon-spin" :class="calsses">
        <use :xlink:href="symbolId" :fill="color" />
    </svg>
</template>

<script lang="ts" setup>
import { computed, reactive } from 'vue'
const props = defineProps({
    prefix: {
        type: String,
        default: 'icon'
    },
    name: {
        type: String,
        required: true
    },
    color: {
        type: String,
        default: '#333'
    },
    size: {
        type: String,
        default: 'default'
    }
})
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
const calsses = computed(() => {
    return {
        [`sdms-size-${props.size}`]: props.size
    }
})
const fontSize = reactive({ default: '32px', small: '20px', large: '48px' });
</script>
<style lang="less" scoped>
.svg-icon-spin {
    width: v-bind("fontSize.default");
    height: v-bind("fontSize.default");
    fill: v-bind(color);
    vertical-align: middle;
    color: v-bind(color);
    &.sdms-size-small {
        font-size: v-bind("fontSize.small");
        height: v-bind("fontSize.small");
    }
    &.sdms-size-large {
        font-size: v-bind("fontSize.large");
        height: v-bind("fontSize.large");
    }
}
</style>

调用svg组件

import SvgIcon from '@/components/SvgIcon'
<SvgIcon name="svg-github" size="small" color="#999999" />

Plop自动生成

plop是一个脚手架工具,其实大厂为了进一步规范团队协作,自动生成是最好的init初始化选择。这其实在后端早已屡见不鲜,比如CURDApi的自动生成,甚至controll、module都是可视化或命令行生成。又如流行的数据库迁移工具migration,也是进一步规范多人协作数据表管理。由此可见,技术发展的终点是一个圆,也说明前端还有很长一段路要走。

# 安装plop
pnpm add plop

根目录创建plopfile.ts

import { NodePlopAPI } from 'plop';
export default function (plop: NodePlopAPI) {
    plop.setWelcomeMessage('请选择需要创建的模式:')
    plop.setGenerator('page', require('./plop-tpls/page/prompt'))
    plop.setGenerator('component', require('./plop-tpls/component/prompt'))
    plop.setGenerator('store', require('./plop-tpls/store/prompt'))
}

在根目录下创建plop-tpls/page文件夹,并创建index.hbsprompt.js

// index.hbs 一种模板文件
<template>
    <div>
        <!-- Your content -->
    </div>
</template>

<script setup name="{{ properCase componentName }}">
// const { proxy } = getCurrentInstance()
// const router = useRouter()
// const route = useRoute()
</script>

<style lang="less" scoped>

</style>
// prompt.js执行函数
const path = require('path')
const fs = require('fs')

function getFolder(path) {
    let components = []
    const files = fs.readdirSync(path)
    files.forEach(function (item) {
        let stat = fs.lstatSync(path + '/' + item)
        if (stat.isDirectory() === true && item != 'components') {
            components.push(path + '/' + item)
            components.push.apply(components, getFolder(path + '/' + item))
        }
    })
    return components
}

module.exports = {
    description: '创建页面',
    prompts: [
        {
            type: 'list',
            name: 'path',
            message: '请选择页面创建目录',
            choices: getFolder('src/pages')
        },
        {
            type: 'input',
            name: 'name',
            message: '请输入文件名',
            validate: v => {
                if (!v || v.trim === '') {
                    return '文件名不能为空'
                } else {
                    return true
                }
            }
        }
    ],
    actions: data => {
        let relativePath = path.relative('src/pages', data.path)
        const actions = [
            {
                type: 'add',
                path: `${data.path}/{{dotCase name}}.vue`,
                templateFile: 'plop-templates/page/index.hbs',
                data: {
                    componentName: `${relativePath} ${data.name}`
                }
            }
        ]
        return actions
    }
}

运行调试

// 在package.json里面配置启动命令行
"scripts": {
...
"plop": "plop"
...
}
// 启动命令
pnpm run plop

image.png

移动端的支持

移动端默认集成postcss-px-to-viewport 插件,使用时将.postcss.config.js文件修改为postcss.config.js即可。开发正常使用px,最终转化为vw

工具库

学会使用适当的工具库,让coding事半功倍。尤其是开源的工具库,值得每个人学习,因为这本身就是你应该达到的层次。这里推荐一些大厂常用的类库,因为我喜新...,以下工具均可直接引入。

JS库

  • pnpm,一个依赖包全局管理的工具,老板再也不用担心我的C盘不够用。Vite官方推荐,字节官方前端团队大规模项目考验

image-20220110125758056

  • mitt 全局事件监听库,Vue3官方推荐

  • Hammer,可以识别由触摸、鼠标和指针事件做出的手势,只有 7.34kb

  • outils,开发中常用的函数集,也可以使用lodash

  • tailwindcss,艾玛香的一塌糊涂,一行css不写,3分钟出一个页面。不适合初中级前端,建议还是先踏实学基础再用框架。

    tailwindcss-1

    tailwindcss-2

  • Vue I18n 是 Vue.js 的国际化插件,如果你想做开源框架,国际化首选插件。

  • ViteSSG,SEO优化,这个项目有点意思,大家可以玩玩这个方案,之前我都是通过服务端渲染搞SEO,后来了解到这个可以直接在Vue3的服务器上生成。

  • Vitest,基于Vite的单元测试工具,目前迭代比较快,尤大金牌赞助。可以持续关注,不建议使用在小项目中。

    image-20220110125605172

UI库

  • arco-design,字节团队新出的UI框架,配置层面更为灵活,fast-vue3使用的就是这个,不喜欢的小伙伴可以移除
  • semi-design,抖音前端出的框架,面向经常撕逼UI和FE,可以尝鲜玩玩
  • nutui,京东前端团队出的UI框架,已升级到3.X,个人认为颜值最高并接受反驳
  • naive-ui,尤大推荐,TypeScript语法,主题可调,这家公司挺厉害
  • 暂时就这些吧,困了,回头再补

资料

最后

  • 欢迎加群前端水友群,划水,大家一起划水,现在粉丝群甚少讨论技术,那么我们就一起水吧。欢迎关注我的公众号扫地盲僧
  • 前沿技术,各类体验、互动相关的技术,各类译文、研报的提前透视。
  • 白嫖,承诺发布的所有付费资源,粉丝群统统免费白嫖,不然大家谁有时间跟你玩,嘿嘿。