Giter VIP home page Giter VIP logo

vue3-vite-vant-ts-h5's Introduction

Table of Contents generated with DocToc

Vue3-Vite-Vant-TS-H5

基于Vue3 + Vite + Vant + Sass+ rem适配方案 + Axios封装,构建手机端模板脚手架 

预览

查看 demo 建议手机端查看

关注我的掘金

掘金:Vue3 Vite Vant TS rem 移动端H5框架方案

贡献代码

使用过程中发现任何问题都可以提Issue 给我,也非常欢迎 PR 或 Pull Request

Node 版本要求

Vite 需要 Node.js 12.0.0 或更高版本 (推荐 14.0.0+)。你可以使用 nvmnvm-windows 在同一台电脑中管理多个 Node 版本。

本示例 Node.js 14.18.1

启动项目

git clone https://github.com/talktao/Vue3-Vite-Vant-TS-H5.git

cd Vue3-Vite-Vant-TS-H5

yarn

npm run dev
复制代码

目录

rem适配方案

Vant 中的样式默认使用px作为单位,如果需要使用rem单位,推荐使用以下两个工具:

更多详细信息: vant

VantUI组件按需加载

项目采 用Vant 自动按需引入组件 (推荐)下 面安装插件介绍:

安装插件

yarn add vite-plugin-style-import -D
复制代码

vite.config.ts 设置

import vue from '@vitejs/plugin-vue';
import styleImport, { VantResolve } from 'vite-plugin-style-import';

export default {
  plugins: [
    vue(),
    styleImport({
      resolves: [VantResolve()],
    }),
  ],
};

但是每次页面使用的时候还是要引入,很麻烦,项目在 src/plugins/vant.ts 下统一管理组件,无需在main.ts文件中多次use()

image.png

image.png

Sass 全局样式

首先 你可能会遇到 node-sass 安装不成功,别放弃多试几次!!!

每个页面自己对应的样式都写在自己的 .vue 文件之中 scoped 它顾名思义给 css 加了一个域的概念。

<style lang="scss">
    /* global styles */
</style>

<style lang="scss" scoped>
    /* local styles */
</style>
复制代码

目录结构

vue-h5-template 所有全局样式都在 @/src/assets/css 目录下设置

├── assets
│   ├── scss
│   │   ├── index.scss               # 全局通用样式
│   │   ├── mixin.scss               # 全局mixin
│   │   └── reset.scss               # 清除标签默认样式
│   │   └── variables.scss           # 全局变量
复制代码

父组件改变子组件样式 深度选择器

当你子组件使用了 scoped 但在父组件又想修改子组件的样式可以 通过 >>> 来实现:

<style scoped>
.a >>> .b { /* ... */ }
</style>
复制代码

全局变量

// 引入全局样式
import '@/assets/css/index.scss'

Vuex 状态管理

目录结构

├── store
│   ├── index.ts
复制代码

main.ts 引入

image.png

使用

image.png

Pinia 状态管理

1.安装

node版本需>=14.0.0

yarn add pinia 
# or with npm 
npm install pinia

2. 创建Pinia的Store

src/store/index.ts 文件中,导出 piniaStore

// src/store/index.ts

import { createPinia } from 'pinia'

export const piniaStore = createPinia()

3.在main.ts文件中引用

image.png

3. 定义State

src/store目录下新建有个testPinia.ts文件

i. 传统的options API方式

import { defineStore } from "pinia"
export const usePiniaState = defineStore({
    id: 'textPinia',
    state: () => {
        return {
            userName: ''
        }
    },
    getters: {

    },
    actions: {
        getUserNmae(data) {
            this.userName = data
        }
    }
})

ii.Vue3 setup的编程模式

import { ref } from 'vue'
import { defineStore } from "pinia"
export const usePiniaState = defineStore('pinia', ()=>{
    const userName = ref('')
    // 修改userName的方法
    const getUserNmae = (data) => {
        userName.value = data
    }
    return { userName, getUserNmae}
})

4.获取/修改 state

<script setup lang="ts">
	import { storeToRefs  } from 'pinia'
	import { usePiniaState } from '@/store/testPinia'
        
	// pinia
	const piniaStore = usePiniaState()
        
	// 通过storeToRefs方法将存储在pinia里的数据解构出来,保持state响应性
	const { userName } = storeToRefs(piniaStore)
	const { getUserNmae } = piniaStore
	

        const handleBtn = () =>{
            // pinia
            getUserNmae('真乖,如果对您有帮助请在github上点个星星哦~')
        }

</script>

Vue-router

本案例采用 hash 模式,开发者根据需求修改 mode base

自动化导入路由

import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";

// 通过Vite的import.meta.glob()方法实现自动化导入路由
const mainRouterModules = import.meta.glob('../layout/*.vue')
const viewRouterModules = import.meta.glob('../views/**/*.vue')

// 子路由
const childRoutes = Object.keys(viewRouterModules).map((path)=>{	
	const childName = path.match(/\.\.\/views\/(.*)\.vue$/)[1].split('/')[1];
	return {
		path: `/${childName.toLowerCase()}`,
		name: childName,
		component: viewRouterModules[path]
	} 
})

console.log(childRoutes,'childRouter');

// 根路由
const rootRoutes = Object.keys(mainRouterModules).map((path) => {
    const name = path.match(/\.\.\/layout\/(.*)\.vue$/)[1].toLowerCase();
    const routePath = `/${name}`;
    if (routePath === '/index') {
		return {
			path: '/',
			name,
			redirect: '/home',
			component: mainRouterModules[path],
			children: childRoutes
		};
    }
})

const routes: Array<RouteRecordRaw> = rootRoutes

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

export default router

普通设置

import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";

const routes: Array<RouteRecordRaw> = [
   {
        path: '/',
        name: 'Index',
        component: () => import ('@/layout/index.vue'),
        redirect: '/home',
        meta: {
            title: '首页',
            keepAlive:false
        },
        children: [
            {
                path: '/home',
                name: 'Home',
                component: () => import('@/views/home/Home.vue')
            },
            {
                path: '/about',
                name: 'About',
                component: () => import('@/views/about/About.vue')
            },
        ]
    },    
]


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

export default router

更多:Vue Router

Axios 封装及接口管理

utils/request.js 封装 axios ,开发者需要根据后台接口做修改。

image.png

接口管理

src/api 文件夹下统一管理接口

image.png

image.png

通过引入axios库的ts版本即可配置

import axiosInstance, { AxiosResponseProps } from '@/uitls/request'

export const getList = (params: any) => {
	return axiosInstance.get("/common/code/logisticsInfo/getOrderByPhone", { params: params || {} });
}

如何调用

// 请求接口
import { getUserInfo } from '@/api/home'

const params = {user: 'talktao'}
getUserInfo(params)
  .then(() => {})
  .catch(() => {})
复制代码

vite.config.ts 基础配置

image.png

检查文件中的env路径

image.png

配置 alias 别名

resolve: {
    alias:{
    // 配置src目录
    "@": path.resolve(__dirname,"src"),
    // 导入其他目录
    "components": path.resolve(__dirname, "components")
    }
},

配置 proxy 跨域

如果你的项目需要跨域设置,你需要打开 vite.config.ts proxy 注释 并且配置相应参数

注意:你还需要将 src/env.development 里的 VITE_BASE_URL 设置成 '/'

module.exports = {
  // 跨域代理
    server:{
        proxy:{
              //这里是通过请求/api 来转发到 https://api.pingping6.com/
             //假如你要请求https://api.*.com/a/a
             //那么axios的url,可以配置为 /api/a/a
            '/api': ''
        }   
    }
}

Eslint+Pettier 统一开发规范

VScode安装 eslint prettier vetur 插件 .vue 文件使用 vetur 进行格式化,其他使用prettier

批量全局注册公共组件

文件地址在 src/plugins/components

const modules = import.meta.globEager('../components/*.vue')

export default {
  install(app) {
    Object.keys(modules).forEach(componentPath => {

    let splitPart1 = componentPath.split("/")
    let componentName = splitPart1[splitPart1.length - 1].split(".vue")[0]

    // 获取所有组件的实例对象,它是个数组
    let modulesData = Object.values(modules).map((v) => v.default)

    // 过滤出当前组件的实例对象与注册组件匹配一致
    let curComponent = modulesData.filter(
        item=>item.__file.split("/")[item.__file.split("/").length-1].split(".vue")[0] === componentName
    )[0]          

    app.component(componentName, curComponent);
    })
  }
}

上面的批量全局注册公共组件在本地启动中正常,但是上生产打包后,会有问题,具体是__file该组件路径找不到,可以修改成如下代码:

  
const modules = import.meta.globEager('../components/*.vue')

export default {
  install(app) {
      Object.keys(modules).forEach(componentPath => {

          // 获取遍历的当前组件实例对象
          let curComponent = modules[componentPath]?.default 

          app.component(curComponent.name, curComponent);
      })
  }
 
}

注意:

由于sfc语法糖没有携带组件的name属性,上面的curComponent.name会报curComponent下没有name属性,此时需要在注册的公共组件中加上如下代码,比如在src/components/CustomHeader.vue中加上如下代码,这样组件的实例对象中就会有name属性

image.png

关于我

如果对你有帮助送我一颗小星星(づ ̄3 ̄)づ╭❤~

转载请联系作者!

vue3-vite-vant-ts-h5's People

Contributors

talktao avatar tantaodev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

vue3-vite-vant-ts-h5's Issues

tsconfig.json报错

Cannot find type definition file for 'node'.
The file is in the program because:
Entry point of type library 'node' specified in compilerOptions

没有使用默认的yarn,用的pnpm,不知道有没有影响

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.