This commit is contained in:
xingyy 2024-08-06 17:07:36 +08:00
parent f3ac427e41
commit 951b7c1407
21 changed files with 2225 additions and 155 deletions

View File

@ -9,15 +9,15 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"autoprefixer": "^10.4.20", "@unocss/reset": "^0.61.9",
"cnjm-postcss-px-to-viewport": "^1.0.1",
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"normalize.css": "^8.0.1",
"path": "^0.12.7", "path": "^0.12.7",
"postcss": "^8.4.40",
"postcss-preset-env": "^10.0.0", "postcss-preset-env": "^10.0.0",
"postcss-px-to-viewport": "^1.1.1", "postcss-px-to-viewport": "^1.1.1",
"postcss-pxtorem": "^6.1.0", "postcss-pxtorem": "^6.1.0",
"postcss-responsive-type": "^1.0.0", "postcss-responsive-type": "^1.0.0",
"vant": "^4.9.4",
"vue": "^3.4.31", "vue": "^3.4.31",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
}, },
@ -25,10 +25,17 @@
"@babel/core": "^7.23.9", "@babel/core": "^7.23.9",
"@babel/preset-env": "^7.23.9", "@babel/preset-env": "^7.23.9",
"@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-babel": "^6.0.4",
"@vant/auto-import-resolver": "^1.2.1",
"@vitejs/plugin-legacy": "^5.3.0", "@vitejs/plugin-legacy": "^5.3.0",
"@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue": "^5.0.5",
"autoprefixer": "^10.4.20",
"babel-plugin-transform-react-jsx": "^6.24.1", "babel-plugin-transform-react-jsx": "^6.24.1",
"postcss": "^8.4.40",
"sass": "^1.70.0", "sass": "^1.70.0",
"tailwindcss": "^3.4.7",
"unocss": "^0.61.9",
"unplugin-auto-import": "^0.18.2",
"unplugin-vue-components": "^0.27.3",
"vite": "^5.3.4" "vite": "^5.3.4"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,48 @@
import autoprefixer from 'autoprefixer'; import autoprefixer from 'autoprefixer';
import postcssResponsiveType from 'postcss-responsive-type'; import postcssResponsiveType from 'postcss-responsive-type';
import pxToViewport from 'postcss-px-to-viewport'; import pxToViewport from 'postcss-px-to-viewport';
import tailwindcss from 'tailwindcss';
// 使用新的PostCSS 8 API创建自定义的px-to-viewport插件
const customPxToViewportPlugin = (options) => {
return {
postcssPlugin: 'custom-px-to-viewport',
Once(root, { result }) {
const file = result.opts.from;
let viewportWidth = '';
if (file?.includes('vant')) {
viewportWidth = 375;
}
if (file.includes('src/views')) {
viewportWidth = 1920;
}
const pxToViewportInstance = pxToViewport({
...options,
viewportWidth: viewportWidth,
});
if (file) {
pxToViewportInstance(root, result);
}
}
};
};
// 定义postcss插件名称
customPxToViewportPlugin.postcss = true;
export default { export default {
plugins: [ plugins: [
tailwindcss(),
autoprefixer(), // 自动添加浏览器前缀 autoprefixer(), // 自动添加浏览器前缀
postcssResponsiveType(), // 自动调整文本大小 postcssResponsiveType(), // 自动调整文本大小
pxToViewport({ customPxToViewportPlugin({
viewportWidth: 1920, // 设计稿的视口宽度 unitPrecision: 5, // 保留的小数位数
unitPrecision: 3, // 保留的小数位数 selectorBlackList: [/^\.van/], // 以 .van 开头的类名不转换
viewportUnit: 'vw', // 转换单位
selectorBlackList: [], // 不进行转换的类名
minPixelValue: 1, // 小于或等于 1px 不转换 minPixelValue: 1, // 小于或等于 1px 不转换
mediaQuery: false, // 允许在媒体查询中转换 px mediaQuery: false, // 允许在媒体查询中转换 px
viewportUnit: "vw", // 转换后的单位
fontViewportUnit: "vw", // 字体单位
unitToConvert: "px" // 需要转换的单位
}), }),
], ],
}; };

BIN
src/assets/image/gdz27.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,4 @@
/* src/assets/styles/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

3
src/dict/index.js Normal file
View File

@ -0,0 +1,3 @@
export const sizes = [
{maxWidth:'375px'}, {maxWidth:'768px'}, {maxWidth:'1440px'}, {maxWidth:'1920px'}
]

View File

@ -1,7 +1,10 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import './style.css' import './style.css'
import App from './App.vue' import App from './App.vue'
import 'normalize.css'; import '@unocss/reset/normalize.css'
/*import 'virtual:uno.css'*/
import './assets/styles/index.css'; // 引入 Tailwind CSS
import router from "./router/index.js"; import router from "./router/index.js";
const app = createApp(App); const app = createApp(App);

View File

@ -10,6 +10,11 @@ const routes = [
name: 'login', name: 'login',
component: () => import('@/views/login/index.vue') component: () => import('@/views/login/index.vue')
}, },
{
path: '/signup',
name: 'signup',
component: () => import('@/views/signup/index.vue')
},
]; ];

View File

@ -0,0 +1,48 @@
import { ref, onMounted, onBeforeUnmount } from 'vue';
export function useAdaptation(sizes, handleChange) {
const mediaQueryLists = sizes.map(size => window.matchMedia(`(max-width: ${size.maxWidth})`));
const currentDevice = ref(getCurrentDevice());
function getCurrentDevice() {
for (let i = 0; i < mediaQueryLists.length; i++) {
if (mediaQueryLists[i].matches) {
return sizes[i].maxWidth;
}
}
return sizes[sizes.length - 1].maxWidth; // Default to the largest size if none match
}
const changeHandler = (newValue) => {
if (typeof handleChange === 'function') {
handleChange(newValue);
}
};
const mediaQueryChangeHandler = () => {
const newDevice = getCurrentDevice();
if (currentDevice.value !== newDevice) {
currentDevice.value = newDevice;
changeHandler(newDevice);
}
};
let cleanupHandlers = [];
onMounted(() => {
mediaQueryLists.forEach(query => {
query.addEventListener('change', mediaQueryChangeHandler);
cleanupHandlers.push(() => query.removeEventListener('change', mediaQueryChangeHandler));
});
// Ensure the initial value is correct and trigger the changeHandler with the initial value
const initialDevice = getCurrentDevice();
currentDevice.value = initialDevice;
changeHandler(initialDevice);
});
onBeforeUnmount(() => {
cleanupHandlers.forEach(cleanup => cleanup());
});
return { maxWidth: currentDevice };
}

View File

@ -1,131 +1,24 @@
<script setup> <script setup>
import {useAdaptation} from "@/utils/self-adaption.js";
import {sizes} from "@/dict/index.js";
import size375 from '@/views/login/size375/index.vue'
import {computed} from "vue";
const {maxWidth}= useAdaptation(sizes,(maxWidth)=>{
})
const viewComponent = computed(()=>{
switch (maxWidth.value){
case '375px':
return size375
default:
return size375
}
})
</script> </script>
<template> <template>
<div class="container"> <component :is="viewComponent"></component>
<div class="content1"></div>
<div class="content2">
<div class="wrap1">
<div class="wrap1_1">手机号</div>
<div class="wrap1_2">
<input class="wrap1_2_1" placeholder="请输入手机号" type="text">
</div>
</div>
<div class="wrap2">
<div class="wrap2_1">验证码</div>
<div class="wrap2_2">
<input class="wrap2_2_1" placeholder="请输入验证码" type="text">
</div>
<div class="wrap2_3">
获取验证码
</div>
</div>
<div class="wrap3">登录/注册</div>
</div>
</div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.container{
width: 1920px;
height: 100vh;
background-repeat: no-repeat;
background-size: cover;
background-image:url("@/assets/image/zu3237.png");
display: flex;
align-items: center;
flex-direction: column;
.content1{
margin-top: 835px;
background-size: contain;
width: 1074px;
height: 178px;
font-size: 72px;
background-image: url("@/assets/image/zu3310@2x.png");
}
.content2{
margin-top: 123px;
background-size: contain;
width: 1654px;
height: 1285px;
background-image: url("@/assets/image/zu3270@2x.png");
display: flex;
flex-direction: column;
align-items: center;
padding-top: 241px;
.wrap3{
background-size: contain;
background-repeat: no-repeat;
font-size: 82px;
color: #fff;
margin-top: 261px;
display: flex;
justify-content: center;
align-items: center;
width: 866px;
height: 200px;
background-image: url("@/assets/image/fbbb@4x.png");
}
.wrap1{
display: flex;
align-items: center;
.wrap1_2{
.wrap1_2_1{
padding-left: 61px;
width: 1174px;
height: 174px;
background-color: #DCE5E9;
border: none;
&::placeholder{
font-size: 72px;
color: #2B69A1;
}
}
}
.wrap1_1{
margin-right: 41px;
font-weight: bold;
color: #2B69A1;
font-size: 72px;
}
}
.wrap2{
margin-top: 118px;
display: flex;
align-items: center;
.wrap2_3{
margin-left: 51px;
color: #FFFFFF;
font-size: 72px;
display: flex;
justify-content: center;
align-items: center;
width: 460px;
height: 174px;
background-color: #2B69A1;
}
.wrap2_2{
.wrap2_2_1{
padding-left: 61px;
width: 660px;
height: 174px;
background-color: #DCE5E9;
border: none;
&::placeholder{
font-size: 72px;
color: #2B69A1;
}
}
}
.wrap2_1{
margin-right: 41px;
font-weight: bold;
color: #2B69A1;
font-size: 72px;
}
}
}
}
</style> </style>

View File

@ -0,0 +1,184 @@
<script setup>
import { useAdaptation } from "@/utils/self-adaption.js";
const { maxWidth } = useAdaptation([
{ maxWidth: '375px' },
{ maxWidth: '768px' }
])
</script>
<template>
<div class="container">
<div class="content1"></div>
<div class="content2">
<div class="wrap1">
<div class="wrap1_1">手机号</div>
<div class="wrap1_2">
<input class="wrap1_2_1" placeholder="请输入手机号" type="text">
</div>
</div>
<div class="wrap2">
<div class="wrap2_1">验证码</div>
<div class="wrap2_2">
<input class="wrap2_2_1" placeholder="请输入验证码" type="text">
</div>
<div class="wrap2_3">
获取验证码
</div>
</div>
<div class="wrap3">登录/注册</div>
</div>
<div class="content3">
<img src="@/assets/image/gdz27.png" alt="">
</div>
<div class="content4">
<img src="@/assets/image/zu733@2x.png" alt="">
</div>
</div>
</template>
<style scoped lang="scss">
.container {
box-sizing: border-box;
position: relative;
width: 1920px;
height: 100vh;
background-repeat: no-repeat;
background-size: cover;
background-image: url("@/assets/image/zu3237.png");
display: flex;
align-items: center;
flex-direction: column;
.content4 {
position: absolute;
bottom: 200px;
img {
width: 1270px;
height: 145px;
}
}
.content3 {
position: absolute;
top: 0;
left: 0;
background-size: cover;
img {
width: 671px;
height: 728px;
}
}
.content1 {
margin-top: 835px;
background-size: cover;
width: 1074px;
height: 178px;
background-repeat: no-repeat;
background-image: url("@/assets/image/zu3310@2x.png");
}
.content2 {
margin-top: 123px;
background-size: cover;
width: 1654px;
height: 1285px;
background-repeat: no-repeat;
background-image: url("@/assets/image/zu3270@2x.png");
display: flex;
flex-direction: column;
align-items: center;
padding-top: 241px;
.wrap3 {
background-size: cover;
background-repeat: no-repeat;
font-size: 82px;
color: #fff;
margin-top: 261px;
display: flex;
justify-content: center;
align-items: center;
width: 866px;
height: 200px;
background-image: url("@/assets/image/fbbb@4x.png");
}
.wrap1 {
display: flex;
align-items: center;
.wrap1_2 {
.wrap1_2_1 {
padding-left: 61px;
width: 1174px;
height: 174px;
background-color: #DCE5E9;
border: none;
&:focus{
outline: none;
}
&::placeholder {
font-size: 72px;
color: #2B69A1;
}
}
}
.wrap1_1 {
margin-right: 41px;
font-weight: bold;
color: #2B69A1;
font-size: 72px;
}
}
.wrap2 {
margin-top: 118px;
display: flex;
align-items: center;
.wrap2_3 {
margin-left: 51px;
color: #FFFFFF;
font-size: 72px;
display: flex;
justify-content: center;
align-items: center;
width: 460px;
height: 174px;
background-color: #2B69A1;
}
.wrap2_2 {
.wrap2_2_1 {
padding-left: 61px;
width: 660px;
height: 174px;
background-color: #DCE5E9;
border: none;
&:focus{
outline: none;
}
&::placeholder {
font-size: 72px;
color: #2B69A1;
}
}
}
.wrap2_1 {
margin-right: 41px;
font-weight: bold;
color: #2B69A1;
font-size: 72px;
}
}
}
}
</style>

View File

@ -0,0 +1,24 @@
<script setup>
import {useAdaptation} from "@/utils/self-adaption.js";
import {sizes} from "@/dict/index.js";
import size375 from '@/views/signup/size375/index.vue'
import {computed} from "vue";
const {maxWidth}= useAdaptation(sizes,(maxWidth)=>{
})
const viewComponent = computed(()=>{
switch (maxWidth.value){
case '375px':
return size375
default:
return size375
}
})
</script>
<template>
<component :is="viewComponent"></component>
</template>
<style scoped lang="scss">
</style>

View File

@ -0,0 +1,368 @@
<script setup>
import { useAdaptation } from "@/utils/self-adaption.js";
import {ref} from "vue";
const { maxWidth } = useAdaptation([
{ maxWidth: '375px' },
{ maxWidth: '768px' }
])
const showPicker=ref(false)
const columns=ref([
{text:'男',value:0},
{text:'女',value:1}
])
function onConfirm(){
}
</script>
<template>
<div class="box-border relative w-[1920px] h-screen bg-no-repeat bg-cover bg-[url('@/assets/image/zu3237.png')] flex items-center flex-col container">
<div class="content1"></div>
<div class="content2">
<div class="wrap1">
<div class="wrap1_1">*姓名</div>
<div class="wrap1_2">
<input class="wrap1_2_1" placeholder="请输入宝贝姓名" type="text">
</div>
</div>
<div class="wrap1">
<div class="wrap1_1">*年龄</div>
<div class="wrap1_2">
<input class="wrap1_2_1" placeholder="请输入年龄" type="text">
</div>
</div>
<div class="wrap2">
<div class="wrap2_1">*性别</div>
<div class="wrap2_2" @click="showPicker=true" >
<input readonly class="wrap2_2_1" placeholder="请选择性别" type="text">
<img src="@/assets/image/hsmr@2x.png" class="wrap2_2_2" alt="">
</div>
</div>
<div class="package1">
<div class="package1_1">
<div class="package1_1_1">*作品1</div>
<div class="package1_1_2">
<van-uploader>
<div class="package1_1_2_1">
<img class="package1_1_2_1_1" src="@/assets/image/zu3264@2x.png" alt="">
<div class="package1_1_2_1_2">上传作品</div>
</div>
</van-uploader>
<div class="x_c1">
作品名称
</div>
<input class="x_c2" placeholder="请输入作品名称" type="text">
<div class="x_c3">
<div class="x_c3_1">
<div class="x_c3_1_1">长度</div>
<div class="x_c3_1_2">
<input class="x_c3_1_2_1" type="text" placeholder="请输入">
<div class="x_c3_1_2_2">cm</div>
</div>
</div>
<div class="x_c3_1">
<div class="x_c3_1_1">宽度</div>
<div class="x_c3_1_2">
<input class="x_c3_1_2_1" type="text" placeholder="请输入">
<div class="x_c3_1_2_2">cm</div>
</div>
</div>
</div>
</div>
</div>
<div class="package1_2">
</div>
</div>
<div class="package2">
确定
</div>
</div>
<div class="content3">
<img src="@/assets/image/gdz27.png" alt="">
</div>
<div class="content4">
<img src="@/assets/image/zu733@2x.png" alt="">
</div>
<van-popup v-model:show="showPicker" round position="bottom">
<van-picker
:columns="columns"
@cancel="showPicker = false"
@confirm="onConfirm"
/>
</van-popup>
</div>
</template>
<style scoped lang="scss">
.container {
.content4 {
position: absolute;
bottom: 200px;
img {
width: 1270px;
height: 145px;
}
}
.content3 {
position: absolute;
top: 0;
left: 0;
background-size: cover;
img {
width: 671px;
height: 728px;
}
}
.content1 {
margin-top: 143px;
background-size: cover;
width: 1074px;
height: 178px;
background-repeat: no-repeat;
background-image: url("@/assets/image/zu3311@2x.png");
}
.content2 {
padding-left: 82px;
padding-right: 82px;
margin-top: 123px;
background-size: cover;
width: 1654px;
height: 2729px;
background-repeat: no-repeat;
background-image: url("@/assets/image/zu3186@2x.png");
display: flex;
flex-direction: column;
align-items: center;
padding-top: 164px;
.package2{
margin-top: 133px;
background-size: contain;
background-repeat: no-repeat;
width: 866px;
height: 200px;
background-image: url("@/assets/image/zu3189@2x1.png");
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 82px;
}
.package1{
padding-top: 46px;
padding-left: 31px;
width: 100%;
background-color: #F5F5F5;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.package1_2 {
margin-bottom: 46px;
margin-top: 51px;
width: 184px; /* 按照图片的实际尺寸调整 */
height: 184px; /* 按照图片的实际尺寸调整 */
background-color: #336699; /* 蓝色背景颜色 */
border-radius: 50%; /* 圆形 */
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* 可选的阴影效果 */
}
.package1_2::before,
.package1_2::after {
content: '';
position: absolute;
background-color: white; /* 加号的颜色 */
}
.package1_2::before {
width: 88px; /* 加号横线的宽度 */
height: 6px; /* 加号横线的高度 */
}
.package1_2::after {
width: 6px; /* 加号竖线的宽度 */
height: 88px; /* 加号竖线的高度 */
}
.package1_1{
width: 100%;
display: flex;
.package1_1_2{
.x_c2{
margin-top: 20px;
width: 1174px;
padding-left: 61px;
height: 174px;
background-color: #DCE5E9;
border: none;
&:focus{
outline: none;
}
&::placeholder {
font-size: 72px;
color: #2B69A1;
}
}
.x_c3{
margin-top: 41px;
display: flex;
justify-content: space-between;
.x_c3_1{
display: flex;
flex-direction: column;
.x_c3_1_2{
display: flex;
align-items: center;
.x_c3_1_2_2{
color: #2B69A1;
font-size: 72px;
}
.x_c3_1_2_1{
margin-right: 51px;
padding-left: 61px;
width: 379px;
height: 174px;
background-color: #DCE5E9;
border: none;
&:focus{
outline: none;
}
&::placeholder {
font-size: 72px;
color: #2B69A1;
}
}
}
.x_c3_1_1{
color: #2B69A1;
font-size: 61px;
}
}
}
.x_c1{
margin-top: 41px;
color: #2B69A1;
font-size: 61px;
}
.package1_1_2_1{
background-color: #D6E0E9;
border-radius: 20px;
width: 410px;
height: 410px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.package1_1_2_1_1{
width: 88px;
height: 88px;
}
.package1_1_2_1_2{
margin-top: 36px;
color: #2B69A1;
font-size: 72px;
}
}
}
.package1_1_1{
width: 256px;
color: #2B69A1;
font-weight: bold;
}
}
}
.wrap1 {
padding-left: 31px;
margin-top: 80px;
display: flex;
align-items: center;
width: 100%;
.wrap1_2 {
.wrap1_2_1 {
padding-left: 61px;
width: 1174px;
height: 174px;
background-color: #DCE5E9;
border: none;
&:focus{
outline: none;
}
&::placeholder {
font-size: 72px;
color: #2B69A1;
}
}
}
.wrap1_1 {
width: 256px;
font-weight: bold;
color: #2B69A1;
font-size: 72px;
}
}
.wrap2 {
padding-left: 31px;
width: 100%;
margin-top: 87px;
display: flex;
align-items: center;
.wrap2_3 {
margin-left: 51px;
color: #FFFFFF;
font-size: 72px;
display: flex;
justify-content: center;
align-items: center;
width: 460px;
height: 174px;
background-color: #2B69A1;
}
.wrap2_2 {
position: relative;
.wrap2_2_2{
top: 50%;
transform: translateY(-50%);
right: 72px;
position: absolute;
width: 50px;
height: 28px;
}
.wrap2_2_1 {
width: 1174px;
padding-left: 61px;
height: 174px;
background-color: #DCE5E9;
border: none;
&:focus{
outline: none;
}
&::placeholder {
font-size: 72px;
color: #2B69A1;
}
}
}
.wrap2_1 {
width: 256px;
font-weight: bold;
color: #2B69A1;
font-size: 72px;
}
}
}
}
</style>

19
uno.config.js Normal file
View File

@ -0,0 +1,19 @@
/*
// uno.config.ts
import { defineConfig, presetUno,presetWind , presetAttributify, presetIcons } from 'unocss'
export default defineConfig({
presets: [
presetWind(), // 使用默认的 UnoCSS 预设
presetAttributify(), // 支持属性模式
presetIcons()
],
/!* rules: [
[/^p-(\d+)$/, (match) => ({padding: `${match[1]}px`})
],
[/^m-(\d+)$/, (match) => ({padding: `${match[1]}px`})
]
]*!/
})
*/

View File

@ -1,15 +1,28 @@
import { defineConfig } from 'vite' import {defineConfig} 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 Components from 'unplugin-vue-components/vite';
import {VantResolver} from '@vant/auto-import-resolver';
import UnoCSS from 'unocss/vite'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [vue()], plugins: [
resolve: { vue(),
alias: [ /* UnoCSS(),*/
{ AutoImport({
find: "@", resolvers: [VantResolver()],
replacement: resolve(__dirname, 'src') }),
} Components({
] resolvers: [VantResolver()],
}, }),
],
resolve: {
alias: [
{
find: "@",
replacement: resolve(__dirname, 'src')
}
]
},
}) })