vite px转rem (vite+vant+vue3 demo)
注:如果是ts项目,postcss.config.js需重命名为postcss.config.cjs
vite+vue3+ts+eslint编写移动端rem自适应
创建项目
1 | npm create vite@latest |
1 | √ Project name: ... vue3-vite-vant |
1 | cd vue3-vite-vant |
使用vant
1 | npm i vant |
按需引入组件(推荐)
1 | npm i unplugin-vue-components -D |
配置vite.config.ts
1 | import { defineConfig } from 'vite' |
引入vant的样式
1 | import 'vant/lib/index.css'; |
引入函数组件的样式
Vant 中有个别组件是以函数的形式提供的,包括 Toast
,Dialog
,Notify
和 ImagePreview
组件。在使用函数组件时,unplugin-vue-components
无法自动引入对应的样式,因此需要手动引入样式。
使用方法1
在 <script setup>
中可以直接使用 Vant 组件,不需要进行组件注册。
1 | <script setup> |
使用方法2
1 | <script setup lang="ts"> |
移动端适配写法-设计稿尺寸(750*1624px)
一、rem写法
1.
1 | html, body{ |
2.元素在750宽的设计稿中,多少px,就写多少rem
二、viewport插件的写法
元素在750宽的设计稿中,*px
,就写*/2px
(要除以2)
Rem适配
1 | npm install postcss postcss-pxtorem --save-dev |
1 | npm i -S amfe-flexible |
https://github.com/amfe/lib-flexible
由于
viewport
单位得到众多浏览器的兼容,lib-flexible
这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport
来替代此方。
Viewport 布局—推荐—本项目使用
1 | npm install postcss-px-to-viewport --save-dev |
viewport布局的相关配置
在项目根目录添加postcss.config.cjs
1 | // postcss.config.js |
注意:添加完文件之后,要重启项目
报错:
1 | This file is being treated as an ES module because it has |
解决:1.将postcss.config.js
改为postcss.config.cjs
; 2.重启服务
使用less
1 | cnpm i less less-loader -D |
使用
1 | <style lang='less' scoped> |
在main.ts中引入reset.less
1 | import './assets/css/reset.less' |
reset.less
1 | /* http://meyerweb.com/eric/tools/css/reset/ |
配置手机可访问本地电脑项目
使用vite新建的项目默认访问链接:http://127.0.0.1:5173/
修改
vite.config.js
文件,添加server
配置1
2
3
4
5server: {
host: '0.0.0.0',
port: 8888,
open: true
},1
2
3
4
5
6
7
8
9export default defineConfig({
plugins: [vue()],
base:'./', // 处理打包后放正式环境的相对路径的问题
server: { // 处理使用本地ip访问页面
host: '0.0.0.0',
port: 8888,
open: true
},
})若使用手机访问本地ip页面,访问不成功(显示“服务器已停用”)。即要将本地电脑的防火墙“关闭”即可。手机和电脑连接同一wifi,手机访问不了电脑起的项目
2.1电脑的“设置”——“网络和共享中心”——“Windows Defender 防火墙”(左下角)——“启用或关闭Windows Defender 防火墙”(左侧)——选择“关闭”(专用网络和公用网络都关闭)
注意:使用完,最好重新“启用”防火墙。
2.2 如果手机连接的当前wifi那里的
HTTP代理
-配置代理
是开启的,将其关闭
vite.config.js之resolve.alias配置
vue实现动态改变title
自定义主题颜色
1.
1 | import { ConfigProvider } from 'vant'; |
2.
1 | <van-config-provider :theme-vars="themeVars"> |
3.
1 | const themeVars = { |
原来:background: var(–van-nav-bar-background-color);
自定义写法:navBarBackgroundColor,会转换成–van-nav-bar-background-color
样式覆盖报错处理
1 | [@vue/compiler-sfc] the >>> and /deep/ combinators have been deprecated. Use :deep() instead. |
在Vue2中 我们经常使用 >>> 或 /deep/ 样式穿透 修改elementui里面的样式
但是Vue3中 弃用了 >>> 和 /deep/ 使用 :deep() 代替
1 | /deep/ .van-cell__title{ |
改为:
1 | :deep(.van-cell__title){ |
路由配置
1.安装
1 | npm install vue-router@4 |
2.src目录中新建router目录,新建index.ts
1 | import {createRouter, createWebHashHistory} from 'vue-router' |
3.修改mian.ts
1 | import router from './router'; |
4.App.vue
1 | <template> |
动态修改页面Title
1 | router.beforeEach((to, from) => { |
页面跳转组件-router-link
1 | <router-link to="/withdraw"> |
自定义主题放在App.vue
1 | <script setup lang="ts"> |
父子组件传值-defineProps
参考:vue3:语法糖内的defineProps及defineEmits、defineExpose
属性:
1.
1 | const props = defineProps({ |
- 采用ts专有声明,无默认值
1 | const props = defineProps<{ // 采用ts专有声明,无默认值 |
- 采用ts专有声明,有默认值
1 | interface Props { |
子组件:
1 | <van-nav-bar |
父组件:
1 | <!-- 顶部导航 --> |
注意:如果传值是字符串要加上单引号(:title="'红包活动'"),否则不生效
或使用变量:
1 | import { ref } from 'vue'; |
子组件传父组件-defineEmits
子组件:
1 | <van-nav-bar |
父组件:
1 | <TopNav :title="'提现'" :rightText="'提现明细'" @navRightClick="handleRightClick"/> |
1 | const handleRightClick = () => { |
编程式路由跳转
1 | import { useRouter } from 'vue-router' |
导航栏父子传值-也可改为插槽的用法
子组件:
1 | <van-nav-bar |
不能写:
1 | <van-nav-bar |
父组件:
1 | <TopNav :title="'提现'"> |
或:
1 | <TopNav :title="'提现'"> |
Vite热更新的开启
vite.config.ts:
1 | server: { |
参考:vite热更新(vue3) | Vite 是如何做热更新的
项目的热更新存在延迟,每次都要重启项目
做了以上配置还是不起作用:
原因:组件引入的路径大小写写错
1 | import Withdraw from '../pages/Withdraw/index.vue'; |
解决:将Withdraw
改为withdraw
即可
1 | import Withdraw from '../pages/withdraw/index.vue'; |
提示:文件夹名称严格注意大小写
router 路由中名称 和文件夹(目录), 文件名需要保证大小写一致
‘v-model’ directives require no argument
解决方法:
解决方法:
在VScode中,打开 “文件>首选项>设置” 找到右侧用户设置
搜索vetur.validation,找到下面这句
1 | "vetur.validation.template": true |
将true改成false
//如果没有可以直接添加该句 (将检查关闭)
1 | "vetur.validation.template": false |
vue3:复制功能(vue-clipboard3)
1 | npm install --save vue-clipboard3 |
1 | import useClipboard from 'vue-clipboard3' |
1 | <van-button color="#fe7c1a" @click="copy('bcJcB9')">复制并前往绑定</van-button> |
页面布局
左右有padding,元素之间间距相等(加gutter="15"
),元素宽度一样(span="6"
),换行(每行相加够24)
1 | <van-row justify="space-between" gutter="15"> |
注:这样写,按钮看起来还是不平均配分,因没有给按钮设置宽度(width: 100%;
1 | .van-button{ |
动态绑定class
:class
1 | :class="{active: amount === i.amount} |
mock数据
- vite-plugin-mock
- mockjs
- axios
https://github.com/nuysoft/Mock/wiki/Getting-Started
步骤:
1.安装
1 | npm i vite-plugin-mock mockjs -D |
2.在vite.config.ts中引入
1 | import { viteMockServe } from 'vite-plugin-mock' |
3.在项目根目录新建mock目录-mock/index.ts:
1 | // test.ts |
4.安装axios
1 | npm i axios |
5.使用
1 | import axios from 'axios' |
6.使用mock来模拟更多数据
7.将mock模拟的数据放到接口返回中
mock/index.ts:
1 | // test.ts |
使用示例:
1 | import Mock from 'mockjs' |
vue项目,svn提交代码时忽略node_modules文件夹提交
8.将数据和接口方法分开
mock/data.ts:
1 | import Mock from 'mockjs' |
mock/index.ts:
1 | import { MockMethod } from 'vite-plugin-mock' |
reactive的做法
1 | // reactive的做法 |
ref的做法
1 | import { ref } from 'vue'; |
枚举的使用-enum
1 | // 枚举 |
数据
1 | // 红包数据 |
页面
1 | import axios from 'axios'; |
解决报错信息
控制台报以下警告信息:
1 | Added non-passive event listener to a scroll-blocking ‘touchstart‘ event. Consider marking event... |
解决:
1 | // 安装插件 |
打包报错
注意: 写v-for循环时,要对循环的列表进行判断,以免数据还没有返回就进行渲染,获取不到值
1 | <div class="content" v-if="list.length > 0"> |
Property 'id' does not exist on type 'never'.
解决:加上类型限制
1 | interface List { |