diff --git a/package.json b/package.json index 7f1f64c..989f178 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,15 @@ "dev": "vite", "test": "vite --mode test", "build:test": "vite build --mode test", - "build:pro": "vite build --mode production", + "build:prod": "vite build --mode production", "preview": "vite preview" }, "dependencies": { "axios": "^1.6.3", "gsap": "^3.12.4", "howler": "^2.2.4", + "lodash": "^4.17.21", + "lodash.debounce": "^4.0.8", "pinia": "^2.1.7", "qs": "^6.11.2", "vant": "^3.6.12", @@ -33,4 +35,4 @@ "vite-plugin-compression": "^0.5.1", "vite-plugin-html": "^3.2.1" } -} +} \ No newline at end of file diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue deleted file mode 100644 index 5927807..0000000 --- a/src/components/HelloWorld.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/src/components/Index.vue b/src/components/Index.vue new file mode 100644 index 0000000..a33a380 --- /dev/null +++ b/src/components/Index.vue @@ -0,0 +1,37 @@ + + + + + diff --git a/src/components/Loading.vue b/src/components/Loading.vue new file mode 100644 index 0000000..3033163 --- /dev/null +++ b/src/components/Loading.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/src/page/Home/App.vue b/src/page/Home/App.vue index 3f2d9b7..f160c14 100644 --- a/src/page/Home/App.vue +++ b/src/page/Home/App.vue @@ -1,14 +1,41 @@ - + diff --git a/src/page/Home/main.js b/src/page/Home/main.js index 14130f7..569fe21 100644 --- a/src/page/Home/main.js +++ b/src/page/Home/main.js @@ -2,11 +2,9 @@ import { createApp } from 'vue' import App from './App.vue' import { createPinia } from "pinia" import 'vant/lib/index.css'; -import h5plugin from '@/plugins/plugin'; +import { isMobile } from '@/plugins'; import { wxShare } from '@/plugins/wxshare'; -// import VConsole from 'vconsole'; - - +import VConsole from 'vconsole'; const app = createApp(App) @@ -15,8 +13,10 @@ const app = createApp(App) app.config.globalProperties.imgUrl = (url) => { return new URL(`./assets/images/${url}`, import.meta.url).href } + + // 初始化我的方法 -app.config.globalProperties.myPlugin = h5plugin +// app.config.globalProperties.myPlugin = h5plugin // 微信分享配置 wxShare({ @@ -26,7 +26,7 @@ wxShare({ }) // 测试环境开vconsole -if (h5plugin.isMobile()) { +if (isMobile()) { // const vConsole = new VConsole(); } diff --git a/src/page/Share/main.js b/src/page/Share/main.js index e3922a7..cbd0249 100644 --- a/src/page/Share/main.js +++ b/src/page/Share/main.js @@ -1,7 +1,7 @@ import { createApp } from 'vue' import App from './App.vue' import { createPinia } from "pinia" -import h5plugin from '@/plugins/plugin'; +// import h5plugin from '@/plugins'; import { wxShare } from '@/plugins/wxshare'; const app = createApp(App) @@ -10,7 +10,7 @@ app.config.globalProperties.imgUrl = (url) => { return new URL(`./assets/images/${url}`, import.meta.url).href } // 初始化我的方法 -app.config.globalProperties.myPlugin = h5plugin +// app.config.globalProperties.myPlugin = h5plugin // 微信分享配置 wxShare({ diff --git a/src/plugins/algorithm.js b/src/plugins/algorithm.js deleted file mode 100644 index c5dae6a..0000000 --- a/src/plugins/algorithm.js +++ /dev/null @@ -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; -} - diff --git a/src/plugins/index.js b/src/plugins/index.js new file mode 100644 index 0000000..1108a14 --- /dev/null +++ b/src/plugins/index.js @@ -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) + + //
+ // + //
+} + + + +// export h5plugin; \ No newline at end of file diff --git a/src/plugins/plugin.js b/src/plugins/plugin.js deleted file mode 100644 index 2c85c42..0000000 --- a/src/plugins/plugin.js +++ /dev/null @@ -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) - - //
- // - //
- } - -} - -export default h5plugin; \ No newline at end of file diff --git a/src/styles/global.scss b/src/styles/global.scss index 91dfa55..4ca31f5 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -2,6 +2,11 @@ $red: red; $green: green; +* { + padding: 0; + margin: 0; +} + // DIV宽高 @mixin box($width, $height) { width: $width; @@ -49,4 +54,4 @@ $green: green; flex-direction: column; align-items: center; justify-content: center; -} +} \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index 2ff9fac..875806e 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,4 +1,4 @@ -import { defineConfig } from 'vite' +import { defineConfig, loadEnv } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' import AutoImport from 'unplugin-auto-import/vite' @@ -10,91 +10,101 @@ import { createHtmlPlugin } from 'vite-plugin-html' // https://vitejs.dev/config/ -export default defineConfig({ - plugins: [ - vue(), - // 多页面配置插件 - createHtmlPlugin({ - minify: true, - pages: [ - { - 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'), +export default defineConfig(({ command, mode }) => { + console.log('mode:', mode); + + const env = loadEnv(mode, process.cwd(), '') + return { + define: { + // enable hydration mismatch details in production build + __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: mode == 'production' ? 'false' : 'true', }, - 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; + + plugins: [ + vue(), + // 多页面配置插件 + createHtmlPlugin({ + minify: true, + pages: [ + { + filename: 'index', + entry: '/src/page/Home/main.js', + template: 'index.html', + injectOptions: { + data: { + title: '首页', + }, } - return num; }, - unitPrecision: 5, // 单位转换后保留的精度 - propList: ['*'], // 能转化为vw的属性列表 - viewportUnit: 'vw', // 希望使用的视口单位 - fontViewportUnit: 'vw', // 字体使用的视口单位 - selectorBlackList: ['ignore-'], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。 - minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换 - mediaQuery: true, // 媒体查询里的单位是否需要转换单位 - replace: true, // 是否直接更换属性值,而不添加备用属性 - exclude: [], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件 - include: [], // 如果设置了include,那将只有匹配到的文件才会被转换 - landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape) - landscapeUnit: 'vw', // 横屏时使用的单位 - landscapeWidth: 1628, // 横屏时使用的视口宽度 - }), - ], + { + 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'] // 引入对应的文件时可以忽略其后缀 + }, + // 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: { scss: { 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]', + } + } + } } + })