更新脚手架!
This commit is contained in:
parent
f1c3d10fd5
commit
c0871a9b1f
1
.env.development
Normal file
1
.env.development
Normal file
@ -0,0 +1 @@
|
||||
VITE_MODE = dev
|
||||
5
.env.production
Normal file
5
.env.production
Normal file
@ -0,0 +1,5 @@
|
||||
VITE_MODE = production
|
||||
VITE_HOST = https://hd.xglpa.com
|
||||
VITE_CDN = https://cdn.xglpa.com
|
||||
VITE_FOLDER = /vite-4
|
||||
VITE_API = /vite-api
|
||||
5
.env.test
Normal file
5
.env.test
Normal file
@ -0,0 +1,5 @@
|
||||
VITE_MODE = test
|
||||
VITE_HOST = https://test.szxgl.cn
|
||||
VITE_CDN = https://test.szxgl.cn
|
||||
VITE_FOLDER = /vite
|
||||
VITE_API = /vite-api
|
||||
12
index.html
12
index.html
@ -1,13 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + Vue</title>
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||
<title><%- title%></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
11
jsconfig.json
Normal file
11
jsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"allowJs": true,
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
24
package.json
24
package.json
@ -5,14 +5,32 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"test": "vite --mode test",
|
||||
"build:test": "vite build --mode test",
|
||||
"build:pro": "vite build --mode production",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.2.41"
|
||||
"axios": "^1.6.3",
|
||||
"gsap": "^3.12.4",
|
||||
"howler": "^2.2.4",
|
||||
"pinia": "^2.1.7",
|
||||
"qs": "^6.11.2",
|
||||
"vant": "^3.6.12",
|
||||
"vconsole": "^3.15.1",
|
||||
"vue": "^3.2.41",
|
||||
"weixin-js-sdk": "^1.6.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vant/auto-import-resolver": "^1.0.2",
|
||||
"@vitejs/plugin-vue": "^3.2.0",
|
||||
"vite": "^3.2.3"
|
||||
"postcss-px-to-viewport-8-plugin": "^1.2.3",
|
||||
"sass": "^1.68.0",
|
||||
"sass-loader": "^13.3.2",
|
||||
"unplugin-auto-import": "^0.17.3",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^3.2.3",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-html": "^3.2.1"
|
||||
}
|
||||
}
|
||||
15
share.html
Normal file
15
share.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||
<title><%- title%></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
31
src/App.vue
31
src/App.vue
@ -1,31 +0,0 @@
|
||||
<script setup>
|
||||
// This starter template is using Vue 3 <script setup> SFCs
|
||||
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a href="https://vitejs.dev" target="_blank">
|
||||
<img src="/vite.svg" class="logo" alt="Vite logo" />
|
||||
</a>
|
||||
<a href="https://vuejs.org/" target="_blank">
|
||||
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
|
||||
</a>
|
||||
</div>
|
||||
<HelloWorld msg="Vite + Vue" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.vue:hover {
|
||||
filter: drop-shadow(0 0 2em #42b883aa);
|
||||
}
|
||||
</style>
|
||||
33
src/api/Axios.js
Normal file
33
src/api/Axios.js
Normal file
@ -0,0 +1,33 @@
|
||||
import axios from 'axios'
|
||||
import QS from 'qs';
|
||||
|
||||
// 创建axios
|
||||
const service = axios.create({
|
||||
baseURL: import.meta.env.VITE_API,
|
||||
timeout: 50000,
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 添加请求拦截器
|
||||
service.interceptors.request.use((config) => {
|
||||
// 在发送请求之前做些什么
|
||||
config
|
||||
return config;
|
||||
}, function (error) {
|
||||
// 对请求错误做些什么
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// 添加响应拦截器
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
|
||||
return response.data;
|
||||
}, (error) => {
|
||||
|
||||
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
export default service;
|
||||
9
src/api/api.js
Normal file
9
src/api/api.js
Normal file
@ -0,0 +1,9 @@
|
||||
import http from './http'
|
||||
|
||||
export function addSurveyed(data, authorization) {
|
||||
return http.post("/api/user/addSurveyed",
|
||||
data,
|
||||
true,
|
||||
authorization
|
||||
);
|
||||
}
|
||||
73
src/api/http.js
Normal file
73
src/api/http.js
Normal file
@ -0,0 +1,73 @@
|
||||
import service from './Axios'
|
||||
import qs from "qs";
|
||||
|
||||
|
||||
// json格式请求头
|
||||
const headerJSON = {
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
};
|
||||
// FormData格式请求头
|
||||
const headerFormData = {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
};
|
||||
|
||||
|
||||
const http = {
|
||||
/**
|
||||
* methods: 请求
|
||||
* @param url 请求地址
|
||||
* @param params 请求参数
|
||||
* @param json 判断数据发送是否是json格式: true-为是 false-为否
|
||||
*/
|
||||
get(url, params, json, authorization) {
|
||||
if (authorization) {
|
||||
headerJSON['authorization'] = authorization
|
||||
}
|
||||
const config = {
|
||||
method: "get",
|
||||
url: url,
|
||||
headers: json ? headerJSON : headerFormData
|
||||
};
|
||||
if (params) config.params = params;
|
||||
return service(config);
|
||||
},
|
||||
post(url, params, json, authorization) {
|
||||
|
||||
if (authorization) {
|
||||
headerJSON['authorization'] = authorization
|
||||
}
|
||||
|
||||
const config = {
|
||||
method: "post",
|
||||
url: url,
|
||||
headers: json ? headerJSON : headerFormData
|
||||
};
|
||||
|
||||
if (params) config.data = json ? params : qs.stringify(params);
|
||||
|
||||
return service(config);
|
||||
},
|
||||
put(url, params, json) {
|
||||
const config = {
|
||||
method: "put",
|
||||
url: url,
|
||||
headers: headerFormData
|
||||
};
|
||||
if (params) config.params = params;
|
||||
return service(config);
|
||||
},
|
||||
delete(url, params, json) {
|
||||
const config = {
|
||||
method: "delete",
|
||||
url: url,
|
||||
headers: headerFormData
|
||||
};
|
||||
if (params) config.params = params;
|
||||
return service(config);
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
|
||||
//导出
|
||||
export default http;
|
||||
@ -1,16 +1,19 @@
|
||||
<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>{{ msg }}</h1>
|
||||
|
||||
<h1 class="msg">{{ msg }}</h1>
|
||||
<Button @click="show" type="primary">警告按钮</Button>
|
||||
<div class="card">
|
||||
<button type="button" @click="count++">count is {{ count }}</button>
|
||||
<p>
|
||||
@ -21,9 +24,8 @@ const count = ref(0)
|
||||
|
||||
<p>
|
||||
Check out
|
||||
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
||||
>create-vue</a
|
||||
>, the official Vue + Vite starter
|
||||
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank">create-vue</a>, the official Vue + Vite
|
||||
starter
|
||||
</p>
|
||||
<p>
|
||||
Install
|
||||
@ -37,4 +39,8 @@ const count = ref(0)
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.msg {
|
||||
font-size: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
31
src/data/data.js
Normal file
31
src/data/data.js
Normal file
@ -0,0 +1,31 @@
|
||||
export default {
|
||||
|
||||
//manifest 加载到纹理缓存使用的资源
|
||||
manifest: [
|
||||
{
|
||||
name: "test0",
|
||||
url: new URL(`@/assets/images/m_0.png`, import.meta.url).href,
|
||||
position: { x: 110, y: 210, w: 80, h: 80 },
|
||||
zIndex: 4,
|
||||
},
|
||||
{
|
||||
name: "test1",
|
||||
url: new URL(`@/assets/images/m_1.png`, import.meta.url).href,
|
||||
position: { x: 110, y: 200, w: 100, h: 100 },
|
||||
zIndex: 3,
|
||||
},
|
||||
{
|
||||
name: "test2",
|
||||
url: new URL(`@/assets/images/m_2.png`, import.meta.url).href,
|
||||
position: { x: 110, y: 300, w: 100, h: 100 },
|
||||
zIndex: 2,
|
||||
},
|
||||
{
|
||||
name: "test3",
|
||||
url: new URL(`@/assets/images/share.jpg`, import.meta.url).href,
|
||||
position: { x: 110, y: 400, w: 300, h: 300 },
|
||||
zIndex: 1,
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
20
src/data/imgList.js
Normal file
20
src/data/imgList.js
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
const load = [
|
||||
'load/1.png',
|
||||
]
|
||||
|
||||
// 处理为vite引入图片格式
|
||||
function imgCreate(url, img) {
|
||||
let i = new URL(`../assets/images/${url}`, import.meta.url).href
|
||||
img.push(i)
|
||||
}
|
||||
|
||||
|
||||
const loadImg = []
|
||||
const pageImg = []
|
||||
|
||||
load.forEach(element => {
|
||||
imgCreate(element, loadImg)
|
||||
});
|
||||
|
||||
export { loadImg, pageImg }
|
||||
@ -1,5 +0,0 @@
|
||||
import { createApp } from 'vue'
|
||||
import './style.css'
|
||||
import App from './App.vue'
|
||||
|
||||
createApp(App).mount('#app')
|
||||
14
src/page/Home/App.vue
Normal file
14
src/page/Home/App.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<HelloWorld></HelloWorld>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Loading from "@/components/HelloWorld";
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" ></style>
|
||||
36
src/page/Home/main.js
Normal file
36
src/page/Home/main.js
Normal file
@ -0,0 +1,36 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import { createPinia } from "pinia"
|
||||
import 'vant/lib/index.css';
|
||||
import h5plugin from '@/plugins/plugin';
|
||||
import { wxShare } from '@/plugins/wxshare';
|
||||
// import VConsole from 'vconsole';
|
||||
|
||||
|
||||
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
// 定义引入图片地址的全局方法
|
||||
app.config.globalProperties.imgUrl = (url) => {
|
||||
return new URL(`./assets/images/${url}`, import.meta.url).href
|
||||
}
|
||||
// 初始化我的方法
|
||||
app.config.globalProperties.myPlugin = h5plugin
|
||||
|
||||
// 微信分享配置
|
||||
wxShare({
|
||||
title: '分享标题',
|
||||
desc: '分享描述',
|
||||
link: '/index.html'
|
||||
})
|
||||
|
||||
// 测试环境开vconsole
|
||||
if (h5plugin.isMobile()) {
|
||||
// const vConsole = new VConsole();
|
||||
|
||||
}
|
||||
|
||||
app.use(createPinia())
|
||||
app.mount('#app')
|
||||
console.log('Mode:', import.meta.env.VITE_MODE);
|
||||
13
src/page/Share/App.vue
Normal file
13
src/page/Share/App.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div class="SharePage">share</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.SharePage {
|
||||
@include fixed();
|
||||
@include flexCen();
|
||||
}
|
||||
</style>
|
||||
24
src/page/Share/main.js
Normal file
24
src/page/Share/main.js
Normal file
@ -0,0 +1,24 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import { createPinia } from "pinia"
|
||||
import h5plugin from '@/plugins/plugin';
|
||||
import { wxShare } from '@/plugins/wxshare';
|
||||
const app = createApp(App)
|
||||
|
||||
// 定义引入图片地址的全局方法
|
||||
app.config.globalProperties.imgUrl = (url) => {
|
||||
return new URL(`./assets/images/${url}`, import.meta.url).href
|
||||
}
|
||||
// 初始化我的方法
|
||||
app.config.globalProperties.myPlugin = h5plugin
|
||||
|
||||
// 微信分享配置
|
||||
wxShare({
|
||||
title: '分享标题',
|
||||
desc: '分享描述',
|
||||
link: '/index.html',
|
||||
})
|
||||
|
||||
app.use(createPinia())
|
||||
app.mount('#app')
|
||||
console.log('Mode:', import.meta.env.VITE_MODE);
|
||||
31
src/plugins/Preloader.js
Normal file
31
src/plugins/Preloader.js
Normal file
@ -0,0 +1,31 @@
|
||||
// 图片资源预加载器
|
||||
const imgPreloader = url => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let image = new Image();
|
||||
image.src = url;
|
||||
image.onload = () => {
|
||||
resolve();
|
||||
};
|
||||
image.onerror = () => {
|
||||
reject();
|
||||
};
|
||||
});
|
||||
};
|
||||
const Preloader = ({ name, imgs, callback }) => {
|
||||
let promiseArr = [];
|
||||
let num = 0
|
||||
imgs.forEach(element => {
|
||||
promiseArr.push(imgPreloader(element).then((res => {
|
||||
num++
|
||||
let progress = parseInt((num / imgs.length) * 100)
|
||||
callback(progress)
|
||||
})));
|
||||
});
|
||||
|
||||
console.log(name, promiseArr.length, '张');
|
||||
return Promise.all(promiseArr);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default Preloader
|
||||
13
src/plugins/algorithm.js
Normal file
13
src/plugins/algorithm.js
Normal file
@ -0,0 +1,13 @@
|
||||
// 洗牌算法
|
||||
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;
|
||||
}
|
||||
|
||||
49
src/plugins/hooks.js
Normal file
49
src/plugins/hooks.js
Normal file
@ -0,0 +1,49 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 倒计时
|
||||
export function useCountDown() {
|
||||
const countNum = ref(0)
|
||||
const countInterval = ref(null)
|
||||
|
||||
const startCountDown = num => {
|
||||
countNum.value = Number(num)
|
||||
clearCountDown()
|
||||
countInterval.value = setInterval(() => {
|
||||
if (countNum.value === 0) {
|
||||
clearInterval(countInterval.value)
|
||||
countInterval.value = null
|
||||
return
|
||||
}
|
||||
countNum.value--
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const clearCountDown = () => {
|
||||
if (countInterval.value) {
|
||||
clearInterval(countInterval.value)
|
||||
}
|
||||
}
|
||||
|
||||
return { countNum, startCountDown, clearCountDown }
|
||||
}
|
||||
|
||||
|
||||
// 防抖
|
||||
export function useDebounce(cb, delay = 150) {
|
||||
const timer = ref(null)
|
||||
|
||||
const handler = () => {
|
||||
if (timer.value) {
|
||||
clearTimeout(timer.value)
|
||||
timer.value = setTimeout(() => {
|
||||
cb()
|
||||
}, delay)
|
||||
} else {
|
||||
timer.value = setTimeout(() => {
|
||||
cb()
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
|
||||
return { handler }
|
||||
}
|
||||
336
src/plugins/plugin.js
Normal file
336
src/plugins/plugin.js
Normal file
@ -0,0 +1,336 @@
|
||||
// 常用的方法
|
||||
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;
|
||||
69
src/plugins/wxshare.js
Normal file
69
src/plugins/wxshare.js
Normal file
@ -0,0 +1,69 @@
|
||||
import wx from 'weixin-js-sdk';
|
||||
import axios from "axios";
|
||||
import { Toast } from "vant";
|
||||
|
||||
const imgUrl = new URL(`../assets/images/share.jpg`, import.meta.url).href
|
||||
const linkUrl = import.meta.env.VITE_HOST + import.meta.env.VITE_FOLDER
|
||||
|
||||
export function wxShare(option) {
|
||||
let url = location.href.split('#')[0];
|
||||
// qiween: https://www.qiween.com/wxapi/api/jsconfig
|
||||
// 信蜂: https://wx.xfhd.net/wxapi/api/jsconfig?appid=wx41d80a1bb01f658d
|
||||
axios.get('https://wx.xfhd.net/wxapi/api/jsconfig?appid=wx41d80a1bb01f658d', {
|
||||
params: { url }
|
||||
})
|
||||
.then((res) => {
|
||||
console.log('分享配置:', {
|
||||
'title': option.title,
|
||||
'desc': option.desc,
|
||||
'link': linkUrl + option.link
|
||||
});
|
||||
|
||||
let data = res.data;
|
||||
wx.config({
|
||||
debug: false, // 开启调试模式
|
||||
appId: data.appId, // 必填,公众号的唯一标识
|
||||
timestamp: data.timestamp, // 必填,生成签名的时间戳
|
||||
nonceStr: data.nonceStr, // 必填,生成签名的随机串
|
||||
signature: data.signature, // 必填,签名,见附录1
|
||||
jsApiList: [
|
||||
'checkJsApi',
|
||||
'chooseImage',
|
||||
'closeWindow',
|
||||
'chooseWXPay',
|
||||
'scanQRCode',
|
||||
'showMenuItems',
|
||||
'onMenuShareAppMessage',
|
||||
'onMenuShareTimeline',
|
||||
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
|
||||
})
|
||||
wx.ready(function () {
|
||||
wx.hideMenuItems({
|
||||
menuList: ["menuItem:copyUrl", "menuItem:share:appMessage", "menuItem:share:timeline"] // 屏蔽复制链接
|
||||
});
|
||||
wx.onMenuShareTimeline({
|
||||
link: linkUrl + option.link, // 分享链接
|
||||
title: option.title, // 分享标题
|
||||
desc: option.desc, // 分享描述
|
||||
imgUrl: imgUrl, // 分享图标
|
||||
success() {// 用户成功分享后执行的回调函数
|
||||
Toast('分享成功')
|
||||
},
|
||||
});
|
||||
wx.onMenuShareAppMessage({
|
||||
link: linkUrl + option.link, // 分享链接
|
||||
title: option.title, // 分享标题
|
||||
desc: option.desc, // 分享描述
|
||||
imgUrl: imgUrl, // 分享图标
|
||||
success() {// 用户成功分享后执行的回调函数
|
||||
Toast('分享成功')
|
||||
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
}
|
||||
15
src/store/index.js
Normal file
15
src/store/index.js
Normal file
@ -0,0 +1,15 @@
|
||||
// pinia仓库
|
||||
import { defineStore } from "pinia"
|
||||
|
||||
|
||||
export const useMainStore = defineStore("counter", {
|
||||
state: () => {
|
||||
return {
|
||||
name: '超级管理员'
|
||||
}
|
||||
},
|
||||
// 相当于computed属性,对state进行二次加工
|
||||
getters: {},
|
||||
// 异步处理方法
|
||||
actions: {},
|
||||
})
|
||||
@ -1,90 +0,0 @@
|
||||
:root {
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
52
src/styles/global.scss
Normal file
52
src/styles/global.scss
Normal file
@ -0,0 +1,52 @@
|
||||
@charset "utf-8";
|
||||
$red: red;
|
||||
$green: green;
|
||||
|
||||
// DIV宽高
|
||||
@mixin box($width, $height) {
|
||||
width: $width;
|
||||
height: $height;
|
||||
}
|
||||
|
||||
// DIV宽高定位
|
||||
@mixin pos($width, $height, $left, $top) {
|
||||
width: $width;
|
||||
height: $height;
|
||||
position: absolute;
|
||||
left: $left;
|
||||
top: $top;
|
||||
}
|
||||
|
||||
// DIV背景
|
||||
@mixin bg_pos($src) {
|
||||
// new URL(`../assets/images/${url}`, import.meta.url).href
|
||||
background-image: url("../assets/images/" + $src);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
// flex居中定位
|
||||
@mixin flex() {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 全屏样式
|
||||
@mixin fixed() {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
// flex垂直水平居中
|
||||
@mixin flexCen() {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
101
vite.config.js
101
vite.config.js
@ -1,7 +1,106 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { resolve } from 'path'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite';
|
||||
import { VantResolver } from 'unplugin-vue-components/resolvers';
|
||||
import postcsspxtoviewport8plugin from 'postcss-px-to-viewport-8-plugin';
|
||||
import viteCompression from 'vite-plugin-compression';
|
||||
import { createHtmlPlugin } from 'vite-plugin-html'
|
||||
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()]
|
||||
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'),
|
||||
},
|
||||
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: ['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, // 横屏时使用的视口宽度
|
||||
}),
|
||||
],
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
javascriptEnabled: true,
|
||||
additionalData: '@import "@/styles/global.scss";',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user