本文已参与「新人创作礼」活动,一起开启掘金创作之路。
世间事,除了生死,哪一件不是闲事。
记 vite 项目创建的步骤
1. npm init @vitejs/app my-vue-app -- template vue-ts // 创建名为my-vue-app的vite项目,使用vue和ts
2. cd my-vue-app // 进入初始化完成的项目
3. npm install // 安装项目依赖
4. npm run dev // 运行项目
5. npm install less less-loader -s // 安装less
6. npm install vue-router@4.0 -s // 安装vue-router,这里选择了4.0以上的较高版本
7. npm install vuex@4.0 -s // 安装vuex,这里选择4.0以上较高版本
vue-router
安装完成vue-router之后,在项目src目录下面新建router目录,然后添加index.ts文件,在文件中添加以下内容。
import { createRouter, createWebHashHistory } from "vue-router";
// 在Vue-router新版本中,需要使用createRouter来创建路由
export default createRouter({
// 指定路由的模式,此处使用的是hash模式
history: createWebHashHistory(),
// 路由地址
routes: [],
});
vuex
安装完成vuex之后,在项目src目录下面新建store目录,并添加index.ts文件,文件中添加以下内容。
import { createStore } from "vuex";
interface State {
userName: String;
}
export default createStore({
state: {
userName: "yuan",
},
});
main.ts
在 main.ts 中引入 vuex 和 vue-router。
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router/index";
import vuex from "./store/index";
let app = createApp(App);
app.use(router);
app.use(vuex);
app.mount("#app");
页面自适应
页面自适应配置按如下步骤操作即可,详情可参照:http://10.10.38.40/b2binfo3/pages/normalQuestion/Code_Adaptation.html#%E7%A7%BB%E5%8A%A8%E7%AB%AF
1.下载 pxtorem 插件
npm install postcss-pxtorem
2.vite.config.ts
配置 pxtorem 插件
export default defineConfig({
plugins: [vue()],
css: {
postcss: {
plugins: [
require("postcss-pxtorem")({
rootValue: 75, //75px=1rem,这个值可以自行修改
propWhiteList: [],
minPixelValue: 2,
}),
],
},
},
});
3.解决 require 报错问题
在该文件中使用require报错找不到require。只需要按照报错提示安装以下包即可。
npm i --save-dev @types/node
4.创建并使用适配 js 文件
- 在
public目录下面,创建一个dprFlex.js,js 内容如下:
(function(win, lib) {
var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {});
if (metaEl) {
var match = metaEl
.getAttribute("content")
.match(/initial-scale=([\d.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = flexibleEl.getAttribute("content");
if (content) {
var initialDpr = content.match(/initial-dpr=([\d.]+)/);
var maximumDpr = content.match(/maximum-dpr=([\d.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
//可配置安卓和ios不同的适配
if (isIPhone) {
dpr = 1;
} else {
dpr = 1;
}
scale = 1 / dpr;
}
docEl.setAttribute("data-dpr", dpr);
if (!metaEl) {
metaEl = doc.createElement("meta");
metaEl.setAttribute("name", "viewport");
metaEl.setAttribute(
"content",
"initial-scale=" +
scale +
", maximum-scale=" +
scale +
", minimum-scale=" +
scale +
", user-scalable=no"
);
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement("div");
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
var rem = width / 10;
docEl.style.fontSize = rem + "px";
flexible.rem = win.rem = rem;
}
win.addEventListener(
"resize",
function() {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
},
false
);
win.addEventListener(
"pageshow",
function(e) {
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
},
false
);
if (doc.readyState === "complete") {
doc.body.style.fontSize = 12 * dpr + "px";
} else {
doc.addEventListener(
"DOMContentLoaded",
function() {
doc.body.style.fontSize = 12 * dpr + "px";
},
false
);
}
refreshRem();
flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function(d) {
var val = parseFloat(d) * this.rem;
if (typeof d === "string" && d.match(/rem$/)) {
val += "px";
}
return val;
};
flexible.px2rem = function(d) {
var val = parseFloat(d) / this.rem;
if (typeof d === "string" && d.match(/px$/)) {
val += "rem";
}
return val;
};
})(window, window["lib"] || (window["lib"] = {}));
- 在 index.html 中将该 js 文件引入(
<script src="/dprFlex.js"></script>) - 做到这里项目重新运行即可在控制台看到,
px单位都变成了rem单位。
配置全局样式
less
全局 less 变量文件需要在 vite.config.ts 中进行配置,这样在 less 文件中定义的变量就可以全局使用。
const { resolve } = require("path");
export default defineConfig({
plugins: [vue()],
css: {
preprocessorOptions: {
less: {
modifyVars: {
hack: `true; @import (reference) "${resolve(
"./src/style/variable.less"
)}";`,
},
javascriptEnabled: true,
},
},
},
});
scss
全局 scss 变量文件需要在 vite.config.ts 中进行配置,这样在 scss 文件中定义的变量就可以全局使用。
export default defineConfig({
plugins: [vue()],
css: {
cssPreprocessOptions: {
scss: {
additionalData: '@import "./src/assets/scss/style.scss";', // 添加公共样式
},
},
},
});
vite.config.js 配置
base
base是用于配置打包后文件的路径,合法取值如下:
- 绝对 URL 路径名,例如
/foo/; - 完整的 URL,例如
http://yuanchengcheng.com/; - 空字符串或
./(常用,记着项目一定要配,不然部署后获取不到文件)
build.outDir
outDir用于指定打包文件的输出路径,相对于根目录,默认为dist;