更新脚手架

This commit is contained in:
Andy Leong 2023-12-31 01:45:02 +08:00
parent c0871a9b1f
commit fab1b96137
12 changed files with 615 additions and 494 deletions

View File

@ -7,13 +7,15 @@
"dev": "vite", "dev": "vite",
"test": "vite --mode test", "test": "vite --mode test",
"build:test": "vite build --mode test", "build:test": "vite build --mode test",
"build:pro": "vite build --mode production", "build:prod": "vite build --mode production",
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"axios": "^1.6.3", "axios": "^1.6.3",
"gsap": "^3.12.4", "gsap": "^3.12.4",
"howler": "^2.2.4", "howler": "^2.2.4",
"lodash": "^4.17.21",
"lodash.debounce": "^4.0.8",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"qs": "^6.11.2", "qs": "^6.11.2",
"vant": "^3.6.12", "vant": "^3.6.12",
@ -33,4 +35,4 @@
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vite-plugin-html": "^3.2.1" "vite-plugin-html": "^3.2.1"
} }
} }

View File

@ -1,46 +0,0 @@
<script setup>
import { ref } from 'vue'
import { Button, Toast } from 'vant';
defineProps({
msg: String
})
const count = ref(0)
const show = () => {
Toast.success('成功文案');
}
</script>
<template>
<h1 class="msg">{{ msg }}</h1>
<Button @click="show" type="primary">警告按钮</Button>
<div class="card">
<button type="button" @click="count++">count is {{ count }}</button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test HMR
</p>
</div>
<p>
Check out
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank">create-vue</a>, the official Vue + Vite
starter
</p>
<p>
Install
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
in your IDE for a better DX
</p>
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
.msg {
font-size: 20px;
}
</style>

37
src/components/Index.vue Normal file
View File

@ -0,0 +1,37 @@
<script setup>
import { Button, Toast } from "vant";
import { debounceTap } from "@/plugins";
const emit = defineEmits(["IndexPage"]);
const count = ref(0);
const show = (event) => {
debounceTap(event.target, () => {
Toast.success("开发中!");
});
};
</script>
<template>
<div class="IndexPage">
<div class="index-bg"></div>
<div class="index-container">
<Button @click="show">首页</Button>
</div>
</div>
</template>
<style lang="scss" scoped>
.IndexPage {
@include pos(100%, 100vh, 0px, 0px);
background-color: rgb(0, 7, 198);
.index-bg {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
}
.index-container {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
}
}
</style>

View File

@ -0,0 +1,57 @@
<script setup>
import { ref } from "vue";
import { Button, Toast } from "vant";
import gsap from "gsap";
import { debounceTap } from "@/plugins";
//
const emit = defineEmits(["LoadPage"]);
const show = (event) => {
const e = event.target;
debounceTap(e, () => {
console.log(1);
emit("LoadPage", { action: "hide" });
});
};
</script>
<template>
<div class="LoadPage">
<div class="load-bg"></div>
<div class="load-container">
<div class="box">
<Button @click="show">to index</Button>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.LoadPage {
@include pos(100%, 100%, 0px, 0px);
background-color: rgb(223, 15, 60);
overflow: hidden;
.load-bg {
@include pos(750px, 100%, 0px, 50%);
transform: translateY(-50%);
}
.load-container {
@include pos(750px, 100%, 0px, 50%);
transform: translateY(-50%);
@include flexCen();
.box {
@include box(300px, 300px);
@include flexCen();
}
.btn {
@include box(200px, 40px);
line-height: 40px;
text-align: center;
background-color: aliceblue;
}
}
}
</style>

View File

@ -1,14 +1,41 @@
<template> <template>
<HelloWorld></HelloWorld> <div class="home">
<Loading v-if="showLoad" @LoadPage="loadFn"></Loading>
<Index v-if="showIndex" @IndexPage="indexFn"></Index>
</div>
</template> </template>
<script setup> <script setup>
import Loading from "@/components/HelloWorld"; import Loading from "@/components/Loading.vue";
import Index from "@/components/Index.vue";
onMounted(() => { const showLoad = ref(true);
const loadFn = (item) => {
if (item.action == "hide") {
showLoad.value = false;
showIndex.value = true;
}
};
const showIndex = ref(false);
const indexFn = (item) => {
if (item.action == "hide") {
showIndex.value = false;
}
};
}) onMounted(() => {});
</script> </script>
<style lang="scss" ></style> <style lang="scss" >
#app {
overflow: hidden;
background-color: rgb(255, 255, 255);
}
.home {
@include box(750px, 100vh);
// position: relative;
overflow: hidden;
margin: 0 auto;
}
</style>

View File

@ -2,11 +2,9 @@ import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import { createPinia } from "pinia" import { createPinia } from "pinia"
import 'vant/lib/index.css'; import 'vant/lib/index.css';
import h5plugin from '@/plugins/plugin'; import { isMobile } from '@/plugins';
import { wxShare } from '@/plugins/wxshare'; import { wxShare } from '@/plugins/wxshare';
// import VConsole from 'vconsole'; import VConsole from 'vconsole';
const app = createApp(App) const app = createApp(App)
@ -15,8 +13,10 @@ const app = createApp(App)
app.config.globalProperties.imgUrl = (url) => { app.config.globalProperties.imgUrl = (url) => {
return new URL(`./assets/images/${url}`, import.meta.url).href return new URL(`./assets/images/${url}`, import.meta.url).href
} }
// 初始化我的方法 // 初始化我的方法
app.config.globalProperties.myPlugin = h5plugin // app.config.globalProperties.myPlugin = h5plugin
// 微信分享配置 // 微信分享配置
wxShare({ wxShare({
@ -26,7 +26,7 @@ wxShare({
}) })
// 测试环境开vconsole // 测试环境开vconsole
if (h5plugin.isMobile()) { if (isMobile()) {
// const vConsole = new VConsole(); // const vConsole = new VConsole();
} }

View File

@ -1,7 +1,7 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import { createPinia } from "pinia" import { createPinia } from "pinia"
import h5plugin from '@/plugins/plugin'; // import h5plugin from '@/plugins';
import { wxShare } from '@/plugins/wxshare'; import { wxShare } from '@/plugins/wxshare';
const app = createApp(App) const app = createApp(App)
@ -10,7 +10,7 @@ app.config.globalProperties.imgUrl = (url) => {
return new URL(`./assets/images/${url}`, import.meta.url).href return new URL(`./assets/images/${url}`, import.meta.url).href
} }
// 初始化我的方法 // 初始化我的方法
app.config.globalProperties.myPlugin = h5plugin // app.config.globalProperties.myPlugin = h5plugin
// 微信分享配置 // 微信分享配置
wxShare({ wxShare({

View File

@ -1,13 +0,0 @@
// 洗牌算法
export function FYShuffle(arr) {
let len = arr.length;
while (len > 1) {
let rand = Math.floor(Math.random() * len);
len--;
[arr[len], arr[rand]] = [arr[rand], arr[len]] // 采用的数组的结构赋值
}
return arr;
}

344
src/plugins/index.js Normal file
View File

@ -0,0 +1,344 @@
// 常用的方法
import gsap from 'gsap'
//是否在微信环境
export function isWX() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;
} else {
return false;
}
}
// 判断是否移动端
export function isMobile() {
let userAgentInfo = navigator.userAgent;
let Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
let getArr = Agents.filter(i => userAgentInfo.includes(i));
return getArr.length ? true : false;
}
// 判断微博环境
export function isWeibo() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/WeiBo/i) == "weibo") {
console.log("微博环境");
return true;
} else {
console.log("非微博环境");
return false;
}
}
// 判断Safari环境
export function isSafari() {
var ua = window.navigator.userAgent.toLowerCase();
if ((/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent))) {
console.log("Safari环境");
return true;
} else {
console.log("非Safari环境");
return false;
}
}
//是否为安卓
export function isAndriod() {
var naviga = navigator.userAgent;
if (naviga.indexOf('Android') > -1 || naviga.indexOf('Adr') > -1) {
console.log("Andriod环境");
return true;
} else {
console.log("非Andriod环境");
return false;
}
}
//路径获取关键字
export function getQueryString(name) {
//截取页面传递字符串
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
// 判断全面屏和非全面屏true为全面屏
export function judgeBigScreen() {
let result = false;
const rate = window.screen.height / window.screen.width;
let limit = window.screen.height == window.screen.availHeight ? 1.8 : 1.65; // 临界判断值
// window.screen.height为屏幕高度
// window.screen.availHeight 为浏览器 可用高度
if (rate > limit) {
// console.log("全面屏");
result = true;
return result;
}
// console.log("非面屏");
return result;
}
// 获取url html名称
export function getUrlHtml() {
//获取url地址
var ts_href = window.location.href;
var ts_mainText = "";
//获取地址最后一个“/”的下标
var ts_indexof = ts_href.lastIndexOf("/");
//获取地址“/”之后的的内容
var ts_indexText = ts_href.substring(ts_indexof + 1);
//获取地址“.html”的下标
var ts_htmlBeforeText = ts_indexText.indexOf(".html");
//获取 “/”到".html"之间的内容
ts_mainText = ts_indexText.substring(0, ts_htmlBeforeText);
console.log("当前入口:", ts_mainText);
return ts_mainText;
}
// 获取cookie中的值
export function getSetCookie(name, value, options) {
if (typeof value != 'undefined') {
options = options || {};
if (value === null) {
value = '';
options = this._extend({}, options, true);
options.expires = -1;
}
var expires = '';
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
var date;
if (typeof options.expires == 'number') {
date = new Date();
date.setTime(date.getTime() + options.expires * 24 * 60 * 60 * 1000);
} else {
date = options.expires;
}
expires = '; expires=' + date.toUTCString();
}
var path = options.path ? '; path=' + options.path : '';
var domain = options.domain ? '; domain=' + options.domain : '';
var secure = options.secure ? '; secure' : '';
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
} else {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
// var cookie = $.trim(cookies[i]);
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) == name + '=') {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
}
// 安卓机型自动播放音乐
export function BGMAutoPlayMgr(url) {
this.audioContext = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
this.sourceNode = null;
this.buffer = null;
this.isPlayingBGM = false;
this.toggleBGM = function () {
if (typeof this.sourceNode == 'object') {
if (this.isPlayingBGM) {
this.sourceNode.stop();
this.isPlayingBGM = false;
} else this._playSourceNode();
}
}
this._playSourceNode = function () {
const audioContext = this.audioContext;
audioContext.resume();
const _sourceNode = audioContext.createBufferSource();
_sourceNode.buffer = this.buffer;
_sourceNode.loop = true;
_sourceNode.connect(audioContext.destination);
_sourceNode.start(0);
this.sourceNode = _sourceNode;
this.isPlayingBGM = true;
}
let loadAndAutoPlay = (audioUrl) => {
const audioContext = this.audioContext;
const xhr = new XMLHttpRequest();
xhr.open('GET', audioUrl, true);
xhr.responseType = 'arraybuffer';
xhr.onreadystatechange = () => {
if (xhr.status < 400 && xhr.status >= 200 && xhr.readyState === 4) {
audioContext.decodeAudioData(xhr.response, buffer => {
this.buffer = buffer;
WeixinJSBridge.invoke("getNetworkType", {}, () => this._playSourceNode());
});
}
}
xhr.send();
}
loadAndAutoPlay(url);
loadAndAutoPlay = null;
}
// 金管家获取openid及openToken
export function getJGJId() {
return new Promise(resolve => {
// 获取openid
PALifeOpen.getOpenId(
{
appId: '1aeedce2a31340e591a5d64080d6105b' // 商户编号,区分⽣产和测试环境商户编号
},
rsp => {
// 调⽤接⼝成功后的回调函数
console.log('success', rsp.data);
store.state.openId = rsp.data.openId
store.state.openToken = rsp.data.openToken
if (rsp.ret == 0) {
store.state.openId = rsp.data.openId
store.state.openToken = rsp.data.openToken
const data = {
id: store.state.openId,
token: store.state.openToken
};
resolve(data);
// console.log(`获取到金管家openid时间${Math.abs(s_t - new Date().getTime())}`);
}
if (rsp.ret == -1) {
console.log(JSON.stringify(rsp));
}
},
e => {
// 调⽤接⼝异常的回调函数
console.log('failed', e);
}
)
})
}
// 金管家内部埋点
export function addPoint(page, spage, des = {}) {
const activityId = process.env.VUE_APP_ACTIVITYID;
PALifeOpen.invoke(
"device",
"addRecord",
{
eventId: `499${page}-${activityId}`, //必填,根据需求
labelId: `499${page}${spage}-${activityId}`, //必填,根据需求
// 扩展参数
parameters: {
ext: JSON.stringify(des)
}
},
// 调用接口成功后的回调函数 // alert(JSON.stringify(rsp))
rsp => console.debug("success ", rsp),
// 调用接口异常的回调函数
e => console.debug("failed ", e),
{
timeout: 86400000
}
);
return this;
}
// 百度统计埋点
export function addPointByBd(des) {
_hmt && _hmt.push(["_trackEvent", `${des}`, `${des} success`]);
return this;
}
// 防抖函数
const btnEnable = ref(true)
export function debounceTap(target, callbacks, timeScale = 1) {
if (!btnEnable.value) return false
btnEnable.value = false;
let createAni = () => {
let timeline = new gsap.timeline({
onStart: () => { },
onComplete: () => {
callbacks && callbacks();
btnEnable.value = true;
timeline.kill();
}
});
timeline
.to(target, { duration: timeScale * 0.2, scale: 0.8, })
.to(target, { duration: timeScale * 0.5, scale: 1, })
}
createAni();
}
// 节流函数
export function throttle(fn, wait) {
let inThrottle = false
return (...args) => {
// @ts-ignore
const context = this
if (!inThrottle) {
inThrottle = true
fn.apply(context, args)
setTimeout(() => {
inThrottle = false
}, wait)
}
}
}
// vite环境引用图片
export function imgUrl(url) {
return new URL(`../assets/images/${url}`, import.meta.url).href
}
// 计算两个日期之间的天数(开始日期,结束日期)
export function getDaysBetween(date1, date2) {
let day1 = new Date(date1.join('-'))
let day2 = new Date(date2.join('-'))
let oneDay = 24 * 60 * 60 * 1000;
let diffDays = Math.round(Math.abs((day2 - day1) / oneDay));
return diffDays;
}
// 计算星座
export function getAstro(month, day) {
var s = "魔羯水瓶双鱼牡羊金牛双子巨蟹狮子处女天秤天蝎射手魔羯";
var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22];
return s.substr(month * 2 - (day < arr[month - 1] ? 2 : 0), 2);
}
// 引入BGM
export function createBGM() {
var bgmElement = document.createElement('div');
// document.querySelector('app').appendChild(bgmElement)
// <div class="music_icon" @click="musicPlay">
// <audio style="display: none; height: 0" id="bg-music" autoplay="autoplay" preload="auto" :src="audioUrl"
// loop="loop"></audio>
// </div>
}
// export h5plugin;

View File

@ -1,336 +0,0 @@
// 常用的方法
import gsap from 'gsap'
const h5plugin = {
//是否在微信环境
isWX() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;
} else {
return false;
}
},
// 判断是否移动端
isMobile() {
let userAgentInfo = navigator.userAgent;
let Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
let getArr = Agents.filter(i => userAgentInfo.includes(i));
return getArr.length ? true : false;
},
// 判断微博环境
isWeibo() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/WeiBo/i) == "weibo") {
console.log("微博环境");
return true;
} else {
console.log("非微博环境");
return false;
}
},
// 判断Safari环境
isSafari() {
var ua = window.navigator.userAgent.toLowerCase();
if ((/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent))) {
console.log("Safari环境");
return true;
} else {
console.log("非Safari环境");
return false;
}
},
//是否为安卓
isAndriod() {
var naviga = navigator.userAgent;
if (naviga.indexOf('Android') > -1 || naviga.indexOf('Adr') > -1) {
console.log("Andriod环境");
return true;
} else {
console.log("非Andriod环境");
return false;
}
},
//路径获取关键字
getQueryString(name) {
//截取页面传递字符串
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
},
// 判断全面屏和非全面屏true为全面屏
judgeBigScreen() {
let result = false;
const rate = window.screen.height / window.screen.width;
let limit = window.screen.height == window.screen.availHeight ? 1.8 : 1.65; // 临界判断值
// window.screen.height为屏幕高度
// window.screen.availHeight 为浏览器 可用高度
if (rate > limit) {
// console.log("全面屏");
result = true;
return result;
}
// console.log("非面屏");
return result;
},
// 获取url html名称
getUrlHtml() {
//获取url地址
var ts_href = window.location.href;
var ts_mainText = "";
//获取地址最后一个“/”的下标
var ts_indexof = ts_href.lastIndexOf("/");
//获取地址“/”之后的的内容
var ts_indexText = ts_href.substring(ts_indexof + 1);
//获取地址“.html”的下标
var ts_htmlBeforeText = ts_indexText.indexOf(".html");
//获取 “/”到".html"之间的内容
ts_mainText = ts_indexText.substring(0, ts_htmlBeforeText);
console.log("当前入口:", ts_mainText);
return ts_mainText;
},
// 获取cookie中的值
getSetCookie(name, value, options) {
if (typeof value != 'undefined') {
options = options || {};
if (value === null) {
value = '';
options = this._extend({}, options, true);
options.expires = -1;
}
var expires = '';
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
var date;
if (typeof options.expires == 'number') {
date = new Date();
date.setTime(date.getTime() + options.expires * 24 * 60 * 60 * 1000);
} else {
date = options.expires;
}
expires = '; expires=' + date.toUTCString();
}
var path = options.path ? '; path=' + options.path : '';
var domain = options.domain ? '; domain=' + options.domain : '';
var secure = options.secure ? '; secure' : '';
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
} else {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
// var cookie = $.trim(cookies[i]);
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) == name + '=') {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
},
// 安卓机型自动播放音乐
BGMAutoPlayMgr(url) {
this.audioContext = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
this.sourceNode = null;
this.buffer = null;
this.isPlayingBGM = false;
this.toggleBGM = function () {
if (typeof this.sourceNode == 'object') {
if (this.isPlayingBGM) {
this.sourceNode.stop();
this.isPlayingBGM = false;
} else this._playSourceNode();
}
}
this._playSourceNode = function () {
const audioContext = this.audioContext;
audioContext.resume();
const _sourceNode = audioContext.createBufferSource();
_sourceNode.buffer = this.buffer;
_sourceNode.loop = true;
_sourceNode.connect(audioContext.destination);
_sourceNode.start(0);
this.sourceNode = _sourceNode;
this.isPlayingBGM = true;
}
let loadAndAutoPlay = (audioUrl) => {
const audioContext = this.audioContext;
const xhr = new XMLHttpRequest();
xhr.open('GET', audioUrl, true);
xhr.responseType = 'arraybuffer';
xhr.onreadystatechange = () => {
if (xhr.status < 400 && xhr.status >= 200 && xhr.readyState === 4) {
audioContext.decodeAudioData(xhr.response, buffer => {
this.buffer = buffer;
WeixinJSBridge.invoke("getNetworkType", {}, () => this._playSourceNode());
});
}
}
xhr.send();
}
loadAndAutoPlay(url);
loadAndAutoPlay = null;
},
// 金管家获取openid及openToken
getJGJId() {
return new Promise(resolve => {
// 获取openid
PALifeOpen.getOpenId(
{
appId: '1aeedce2a31340e591a5d64080d6105b' // 商户编号,区分⽣产和测试环境商户编号
},
rsp => {
// 调⽤接⼝成功后的回调函数
console.log('success', rsp.data);
store.state.openId = rsp.data.openId
store.state.openToken = rsp.data.openToken
if (rsp.ret == 0) {
store.state.openId = rsp.data.openId
store.state.openToken = rsp.data.openToken
const data = {
id: store.state.openId,
token: store.state.openToken
};
resolve(data);
// console.log(`获取到金管家openid时间${Math.abs(s_t - new Date().getTime())}`);
}
if (rsp.ret == -1) {
console.log(JSON.stringify(rsp));
}
},
e => {
// 调⽤接⼝异常的回调函数
console.log('failed', e);
}
)
})
},
// 金管家内部埋点
addPoint(page, spage, des = {}) {
const activityId = process.env.VUE_APP_ACTIVITYID;
PALifeOpen.invoke(
"device",
"addRecord",
{
eventId: `499${page}-${activityId}`, //必填,根据需求
labelId: `499${page}${spage}-${activityId}`, //必填,根据需求
// 扩展参数
parameters: {
ext: JSON.stringify(des)
}
},
// 调用接口成功后的回调函数 // alert(JSON.stringify(rsp))
rsp => console.debug("success ", rsp),
// 调用接口异常的回调函数
e => console.debug("failed ", e),
{
timeout: 86400000
}
);
return this;
},
// 百度统计埋点
addPointByBd(des) {
_hmt && _hmt.push(["_trackEvent", `${des}`, `${des} success`]);
return this;
},
// 防抖函数
debounceTap(fn, wait) {
let timer
return (...args) => {
// @ts-ignore
const context = this
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
timer = null
fn.apply(context, args)
}, wait)
}
},
// 节流函数
throttle(fn, wait) {
let inThrottle = false
return (...args) => {
// @ts-ignore
const context = this
if (!inThrottle) {
inThrottle = true
fn.apply(context, args)
setTimeout(() => {
inThrottle = false
}, wait)
}
}
},
// vite环境引用图片
imgUrl(url) {
return new URL(`../assets/images/${url}`, import.meta.url).href
},
// 计算两个日期之间的天数(开始日期,结束日期)
getDaysBetween(date1, date2) {
let day1 = new Date(date1.join('-'))
let day2 = new Date(date2.join('-'))
let oneDay = 24 * 60 * 60 * 1000;
let diffDays = Math.round(Math.abs((day2 - day1) / oneDay));
return diffDays;
},
// 计算星座
getAstro(month, day) {
var s = "魔羯水瓶双鱼牡羊金牛双子巨蟹狮子处女天秤天蝎射手魔羯";
var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22];
return s.substr(month * 2 - (day < arr[month - 1] ? 2 : 0), 2);
},
// 引入BGM
createBGM() {
var bgmElement = document.createElement('div');
// document.querySelector('app').appendChild(bgmElement)
// <div class="music_icon" @click="musicPlay">
// <audio style="display: none; height: 0" id="bg-music" autoplay="autoplay" preload="auto" :src="audioUrl"
// loop="loop"></audio>
// </div>
}
}
export default h5plugin;

View File

@ -2,6 +2,11 @@
$red: red; $red: red;
$green: green; $green: green;
* {
padding: 0;
margin: 0;
}
// DIV宽高 // DIV宽高
@mixin box($width, $height) { @mixin box($width, $height) {
width: $width; width: $width;
@ -49,4 +54,4 @@ $green: green;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }

View File

@ -1,4 +1,4 @@
import { defineConfig } from 'vite' import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import { resolve } from 'path' import { resolve } from 'path'
import AutoImport from 'unplugin-auto-import/vite' import AutoImport from 'unplugin-auto-import/vite'
@ -10,91 +10,101 @@ import { createHtmlPlugin } from 'vite-plugin-html'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig(({ command, mode }) => {
plugins: [ console.log('mode:', mode);
vue(),
// 多页面配置插件 const env = loadEnv(mode, process.cwd(), '')
createHtmlPlugin({ return {
minify: true, define: {
pages: [ // enable hydration mismatch details in production build
{ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: mode == 'production' ? 'false' : 'true',
filename: 'index',
entry: '/src/page/Home/main.js',
template: 'index.html',
injectOptions: {
data: {
title: '首页',
},
}
},
{
filename: 'share',
entry: '/src/page/Share/main.js',
template: 'share.html',
injectOptions: {
data: {
title: '分享页',
},
}
}
]
}),
// 按需自动引入vant组件
Components({
resolvers: [VantResolver()],
}),
AutoImport({
imports: ['vue', 'vue-router',]
}),
// 开启gzip压缩
viteCompression({
verbose: true, // 默认即可
disable: false, //开启压缩(不禁用),默认即可
deleteOriginFile: false, //删除源文件
threshold: 10240, //压缩前最小文件大小
algorithm: 'gzip', //压缩算法
ext: '.gz', //文件类型
})
],
server: { // ← ← ← ← ← ←
host: '0.0.0.0' // ← 新增内容 ←
},
// 别名配置
resolve: {
alias: {
'@': resolve(__dirname, './src'),
}, },
extensions: ['.js', '.vue', '.json'] // 引入对应的文件时可以忽略其后缀
}, plugins: [
// css处理器配置 vue(),
css: { // 多页面配置插件
postcss: { createHtmlPlugin({
plugins: [ minify: true,
postcsspxtoviewport8plugin({ pages: [
unitToConvert: 'px', {
viewportWidth: file => { filename: 'index',
let num = 750; entry: '/src/page/Home/main.js',
//van是375 template: 'index.html',
if (file.indexOf('van') > 0) { injectOptions: {
num = 375; data: {
title: '首页',
},
} }
return num;
}, },
unitPrecision: 5, // 单位转换后保留的精度 {
propList: ['*'], // 能转化为vw的属性列表 filename: 'share',
viewportUnit: 'vw', // 希望使用的视口单位 entry: '/src/page/Share/main.js',
fontViewportUnit: 'vw', // 字体使用的视口单位 template: 'share.html',
selectorBlackList: ['ignore-'], // 需要忽略的CSS选择器不会转为视口单位使用原有的px等单位。 injectOptions: {
minPixelValue: 1, // 设置最小的转换数值如果为1的话只有大于1的值会被转换 data: {
mediaQuery: true, // 媒体查询里的单位是否需要转换单位 title: '分享页',
replace: true, // 是否直接更换属性值,而不添加备用属性 },
exclude: [], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件 }
include: [], // 如果设置了include那将只有匹配到的文件才会被转换 }
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape) ]
landscapeUnit: 'vw', // 横屏时使用的单位 }),
landscapeWidth: 1628, // 横屏时使用的视口宽度 // 按需自动引入vant组件
}), Components({
], resolvers: [VantResolver()],
}),
AutoImport({
imports: ['vue', 'vue-router',]
}),
// 开启gzip压缩
viteCompression({
verbose: true, // 默认即可
disable: false, //开启压缩(不禁用),默认即可
deleteOriginFile: false, //删除源文件
threshold: 10240, //压缩前最小文件大小
algorithm: 'gzip', //压缩算法
ext: '.gz', //文件类型
})
],
server: { // ← ← ← ← ← ←
host: '0.0.0.0' // ← 新增内容 ←
},
// 别名配置
resolve: {
alias: {
'@': resolve(__dirname, './src'),
},
extensions: ['.js', '.vue', '.json'] // 引入对应的文件时可以忽略其后缀
},
// css处理器配置
css: {
postcss: {
plugins: [
postcsspxtoviewport8plugin({
unitToConvert: 'px',
viewportWidth: file => {
let num = 750;
//van是375
if (file.indexOf('van') > 0) {
num = 375;
}
return num;
},
unitPrecision: 5, // 单位转换后保留的精度
propList: ['*'], // 能转化为vw的属性列表
viewportUnit: 'vw', // 希望使用的视口单位
fontViewportUnit: 'vw', // 字体使用的视口单位
selectorBlackList: ['home'], // 需要忽略的CSS选择器不会转为视口单位使用原有的px等单位。
minPixelValue: 1, // 设置最小的转换数值如果为1的话只有大于1的值会被转换
mediaQuery: true, // 媒体查询里的单位是否需要转换单位
replace: true, // 是否直接更换属性值,而不添加备用属性
exclude: [], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
include: [], // 如果设置了include那将只有匹配到的文件才会被转换
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
landscapeUnit: 'vw', // 横屏时使用的单位
landscapeWidth: 750, // 横屏时使用的视口宽度
}),
],
},
preprocessorOptions: { preprocessorOptions: {
scss: { scss: {
javascriptEnabled: true, javascriptEnabled: true,
@ -102,5 +112,39 @@ export default defineConfig({
}, },
}, },
}, },
// 公共基础路径构建生产环境时自动载入cdn路径
base: mode == 'production' ? env.VITE_CDN + env.VITE_FOLDER + '/' : './',
// 打包配置
build: {
assetsPublicPath: './',
assetsDir: 'static',
minify: 'terser',
chunkSizeWarningLimit: 1500,
terserOptions: {
compress: {
//生产环境时移除console.log()
drop_console: false,
drop_debugger: true,
},
},
rollupOptions: {
input: {},
output: {
// node_modules下引用的插件采用分包策略名称不改变应对浏览器缓存策略
"manualChunks": (id) => {
if (id.includes("node_modules")) {
return "vendor"
}
},
// 为输出文件加Hash值
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
}
}
}
} }
}) })