文章目录
前言
按着自己习惯的环境版本号来.一共分为一下文件夹
一、public
index.html代码如下
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="icon" href="https://图片地址" type="image/x-icon" />
<title>DivergenceValueSimulator</title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
二、src
1.api
api.js
import http from './http'
// 密码登录
export const login = params => { return http.post('/login', params).then(res => res.data); };
http.js
import axios from 'axios';
import qs from 'qs';
import Vue from 'vue';
Vue.prototype.$axios = axios;
import { Toast } from "vant";
axios.defaults.baseURL = 'http://192.168.61.16:8009'
axios.defaults.timeout = 1000 * 30
axios.defaults.withCredentials = false; // true: 不允许跨域
function request(url, data = {}, method) {
return new Promise(function (resolve, reject) {
var headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': localStorage.getItem("token") || localStorage.getItem("guest_token") || "",
}
var conf = {
method: method,
url: url,
headers: headers,
data: data
}
method === 'POST' ? conf.data = data : conf.params = data
axios(conf).then((res) => {
if (res.status == 200) {
if (res.data.Code == '0') {
resolve(res)
} else {
if (res.data) {
// reject(res.data)
resolve(res)
}
}
}
}).catch((res) => {
reject(res.response)
if (res.response) {
if (res.response.status === 500) {
Toast("网络打了个盹,请刷新页面");
} else {
Toast(res.response.data.Message || "请重试");
if (res.response.status == 403) {
// Toast("请先登录");
localStorage.removeItem("token");
localStorage.removeItem("guest_token");
sessionStorage.removeItem("loginStatusBli");
sessionStorage.removeItem("loginStatusGame");
// setTimeout(function () {
// window.location.href = "http://192.168.61.21:8088/#/";
// }, 1000)
}
}
}
})
})
}
export default {
get(url, data = {}) {
return request(url, data, 'GET')
},
post(url, data = {}) {
return request(url, data, 'POST')
},
}
2.assets
放资源,图片,视频,字体
3.common
utils.js 自定义的一些方法,这里展示判断移动端的方法
export const isIpadFun = function() {
var ua = window.navigator.userAgent
var IsIPad = false
if (/ipad/i.test(ua)) {
IsIPad = true
}
// iPad from IOS13
var macApp = ua.match(/Macintosh/i) != null
if (macApp) {
// need to distinguish between Macbook and iPad
var canvas = document.createElement('canvas')
if (canvas != null) {
var context =
canvas.getContext('webgl') || canvas.getContext('experimental-webgl')
if (context) {
var info = context.getExtension('WEBGL_debug_renderer_info')
if (info) {
var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL)
if (renderer.indexOf('Apple') != -1) IsIPad = true
}
}
}
}
return IsIPad;
}
export const isMobileDevice = function() {
return navigator.userAgent.match(
/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
);
}
export default {
isIpadFun,
isMobileDevice,
}
vant.js 引入的前端UI框架,按需引入
import Vue from 'vue'
import { Popup, Form, Field, Toast, Loading, Button } from 'vant';
Vue.use(Popup);
Vue.use(Form);
Vue.use(Field);
Vue.use(Loading);
Vue.use(Toast);
Vue.use(Button);
4.components
自定义的公共组件文件夹
5.router
index.js
import Vue from 'vue'
import Router from 'vue-router'
import index from "../views/index.vue";
import home from "../views/home/home.vue";
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.NODE_ENV==='production' ? '/OperationEndless2063' : '/',
routes: [
{
path: '/',
name: 'index',
component: index,
},
{
path: '/home',
name: 'home',
component: home,
children: [
// {
// path: '/game',
// name: 'game',
// component: game,
// },
// {
// path: '/access',
// name: 'access',
// component: access,
// },
// {
// path: '/atlas',
// name: 'atlas',
// component: atlas,
// },
]
},
]
})
6.store
index.js vuex状态管理器
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
targetScroll: sessionStorage.getItem('targetScroll') || 0,
},
mutations: {
setTargetScroll(state, arr) {
sessionStorage.setItem('targetScroll', arr)
state.targetScroll = arr
},
}
})
export default store;
7. style
main.css 公共样式文件,在main.js中引入
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
8.views
放页面的文件夹
9.App.vue
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
}
},
created() {
},
mounted() {},
methods: {},
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
width: 100%;
height: 100%;
overflow-y: hidden;
overflow-x: hidden;
}
</style>
10.main.js
import vuescroll from 'vuescroll';
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import moment from 'moment';
import lodash from "lodash";
import "./style/main.css";
import "./common/vant";
moment.locale('zh-cn')
Vue.prototype.$moment = moment;
Vue.use(vuescroll, {
ops: {
vuescroll: {
mode: "native",
detectResize: true, //内容是否根据页面调整
},
bar: {
showDelay: 500,
onlyShowBarOnScroll: false, //是否只有滚动的时候才显示滚动条
keepShow: true,
background: '#eeeeee',
opacity: 0,
hoverStyle: false,
specifyBorderRadius: false,
minSize: false,
size: '6px',
disable: false,
overflowX: 'hidden',
},
scrollPanel: {
speed: 800, //多长时间内完成一次滚动。 数值越小滚动的速度越快。
easing: 'easeInQuad', //默认动画
}
},
name: 'vueScroll' // 在这里自定义组件名字,默认是vueScroll
});
// import proNav from "./components/proNav.vue";
// Vue.component("proNav", proNav)
Vue.component('vueScroll', vuescroll);
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
三 babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
['import', {
libraryName: 'vant',
libraryDirectory: 'es',
// style: true
style: (name) => `${name}/style/less`,
}, 'vant']
]
}
四 package-lock.json
可以为空,会自定下载
五 package.json
{
"name": "part3",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"start": "webpack serve --open"
},
"keywords": [],
"author": "juaner",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.18.2",
"@vue/cli-plugin-babel": "^5.0.8",
"babel-loader": "^8.2.5",
"babel-plugin-import": "^1.13.5",
"clean-webpack-plugin": "^4.0.0",
"core-js": "^3.22.8",
"css-loader": "^6.7.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"html-withimg-loader": "^0.1.16",
"image-webpack-loader": "^8.1.0",
"less": "^4.1.3",
"less-loader": "^11.0.0",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"postcss": "^8.4.14",
"postcss-loader": "^7.0.0",
"postcss-preset-env": "^7.7.1",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.9",
"ts-loader": "^9.3.1",
"uglifyjs-webpack-plugin": "^2.2.0",
"url-loader": "^4.1.1",
"vant": "^2.13.0",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.73.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.9.2",
"wowjs": "^1.1.3"
},
"dependencies": {
"@studio-freight/lenis": "^1.0.27",
"animate.css": "^4.1.1",
"ar-style": "^0.1.3",
"axios": "^0.27.2",
"gsap": "^3.12.2",
"html2canvas": "^1.0.0-rc.4",
"js-md5": "^0.7.3",
"live2d-widget": "^3.1.4",
"moment": "^2.29.4",
"streamsaver": "^2.0.6",
"swiper": "^3.4.2",
"vue": "^2.6.14",
"vue-clipboard2": "^0.3.1",
"vue-kinesis": "^1.3.3",
"vue-mobile-audio": "^0.1.3",
"vue-router": "^3.5.4",
"vue-template-loader": "^1.1.0",
"vue-touch": "^2.0.0-beta.4",
"vuescroll": "^4.17.0",
"vuex": "^3.1.1"
}
}
六 webpack.config.js
// webpack的配置文件
// 引入一个包
const path = require('path');
// 引入html插件
const HTMLWebpackPlugin = require('html-webpack-plugin');
// 引入clean插件(不是默认的,需要写在{}里面),作用就是清除dist文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
// babel 把新语法转换成旧语法,让代码兼容性更好\
const TerserPlugin = require('terser-webpack-plugin'); // 压缩js
// webpack中的所有配置信息都应该写到module.exports中
module.exports = {
// publicPath: process.env.NODE_ENV==='production' ? '/aaa/' : './',
// 开发环境 development(production:生产环境)
mode: "development",
// 指定入口文件
entry: "./src/main.js",
devtool: false,
// devtool: 'eval-cheap-module-source-map', // 开发环境
// 指定打包文件所在的目录
output: {
// 指定打包文件的目录
path: path.resolve(__dirname, "dist"),
// 打包后的文件
filename: "bundle.[contenthash:10].js",
// 每次打包后是否清除dist
clean: true,
// 配置打包环境
environment: {
// 告诉webpack不适用箭头函数
arrowFunction: false
}
},
devServer: {
open: true,
host: "192.168.61.21",
port: "8084"
},
// 指定webpack打包时要使用的模块
module: {
// 指定要加载的规则
rules: [
// 配置vue
{
test: /\.vue$/,
use: ['vue-loader'],
},
{
test: /\.js$/,
include: path.resolve("src"),
use: ['babel-loader'],
},
// 设置less文件的处理
{
test: /\.less|.css$/,
use: [
"style-loader",
"css-loader",
// 引入postcss(让css兼容性更好)
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
browsers: "last 2 versions"
}
]
]
}
}
},
"less-loader"
]
},
// 背景图片处理规则
{
test: /\.(jpg|png|gif|bmp|jpeg)$/,
use: {
loader: "url-loader",
options: {
// publicPath: '/',
name: 'image/[name].[ext]',
esModule: false,
limit: 0 * 1024, // 将小于4kb的图片用based64处理
// publicPath: '/',
}
},
type: 'javascript/auto' //转换 json 为 js
},
// 视频音频
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'file-loader',
options: {
name:'audios/[name].[ext]',
// publicPath: '/',
esModule: false,
}
},
// html图片
{
test: /\.(htm|html)$/,
loader: 'html-withimg-loader'
},
// 通过资源模块来处理字体
// {
// test: /\.(eot|svg|ttf|otf|woff|woff2)$/i,
// type: 'asset/resource',
// generator: {
// filename: "fonts/[name]_[hash:9][ext]" // 单独指定 名字
// }
// },
// 压缩图片(要搭配url-loader一起使用)
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 60
},
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false,
},
//ios不支持
// webp: {
// quality: 100
// }
}
}
]
},
optimization: {
usedExports: true, // 配合实现 Tree Shaking,,默认 true 开启
concatenateModules: true, // 公共代码整合,生产环境下被启用
minimize: true, // 在生成环境是否开启js代码压缩和Tree Shaking,默认 true 开启
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // 去除console
},
},
extractComments: false, // 默认:true,当 minimize为true 打包时会生成注释文件,参数为 false 不生成注释文件
}),
],
},
// 配置webpack插件
plugins: [
new HTMLWebpackPlugin({
// favicon: path.resolve(__dirname, './public/favicon.ico'),
template: path.resolve(__dirname, "./public/index.html")
}),
new CleanWebpackPlugin(),
new VueLoaderPlugin(),
],
// 用来设置引用模块的,哪些文件可以用来做为引用模块
resolve: {
// 以ts,js结尾的文件可以用来引用
extensions: ['.ts', '.js']
},
}