create:创建基础项目

This commit is contained in:
2024-12-13 16:04:11 +08:00
commit dbb3c7aa2e
27 changed files with 8410 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist
# Node dependencies
node_modules
# Logs
logs
*.log
# Misc
.DS_Store
.fleet
.idea
# Local env files
.env
.env.*
!.env.example
+75
View File
@@ -0,0 +1,75 @@
# Nuxt Minimal Starter
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
## Setup
Make sure to install dependencies:
```bash
# npm
npm install
# pnpm
pnpm install
# yarn
yarn install
# bun
bun install
```
## Development Server
Start the development server on `http://localhost:3000`:
```bash
# npm
npm run dev
# pnpm
pnpm dev
# yarn
yarn dev
# bun
bun run dev
```
## Production
Build the application for production:
```bash
# npm
npm run build
# pnpm
pnpm build
# yarn
yarn build
# bun
bun run build
```
Locally preview production build:
```bash
# npm
npm run preview
# pnpm
pnpm preview
# yarn
yarn preview
# bun
bun run preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
+6
View File
@@ -0,0 +1,6 @@
<template>
<div>
<NuxtRouteAnnouncer />
<NuxtWelcome />
</div>
</template>
+15
View File
@@ -0,0 +1,15 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2024-11-01',
devtools: { enabled: true },
srcDir: 'src/',
modules: [
'@nuxtjs/tailwindcss',
'@nuxt/image',
'@tdesign-vue-next/nuxt'
],
image:{
dir: 'assets/images',
},
css: ['~/assets/css/main.css'],
})
+24
View File
@@ -0,0 +1,24 @@
{
"name": "nuxt-app",
"private": true,
"type": "module",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@nuxt/image": "^1.8.1",
"nuxt": "^3.14.1592",
"vue": "latest",
"vue-router": "latest"
},
"packageManager": "pnpm@9.15.0+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c",
"devDependencies": {
"@nuxtjs/tailwindcss": "^6.12.2",
"@tdesign-vue-next/nuxt": "^0.1.5",
"tdesign-vue-next": "^1.10.5"
}
}
+7564
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

+1
View File
@@ -0,0 +1 @@
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "../.nuxt/tsconfig.server.json"
}
+5
View File
@@ -0,0 +1,5 @@
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
+4
View File
@@ -0,0 +1,4 @@
:root{
--primary-color: #0052d9;
--primary-color-1: #007aff;
}
+3
View File
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

+14
View File
@@ -0,0 +1,14 @@
<template>
<div class="h-10 leading-10" v-for="item in line">
this is line {{ item }}
</div>
</template>
<script lang="ts" setup>
defineProps({
line: {
type: Number,
default: 20,
},
})
</script>
+167
View File
@@ -0,0 +1,167 @@
<template>
<qi-container>
<div class="grid grid-cols-5 gap-8 py-10">
<div v-for="(section, index) in footerSections" :key="index" class="space-y-4">
<h3 class="font-medium text-gray-700">{{ section.title }}</h3>
<ul class="space-y-2">
<li v-for="(item, itemIndex) in section.items" :key="itemIndex">
<a :href="item.link" class="text-gray-500 hover:text-blue-600 text-sm">
{{ item.text }}
</a>
</li>
</ul>
</div>
<div class="space-y-4">
<h3 class="font-medium text-gray-700">关注或联系我们</h3>
<div class="flex space-x-4">
<div class="text-center">
<!-- <img src="/qrcode-weixin.png" alt="微信二维码" class="w-32 h-32 mb-2" /> -->
<span class="text-sm text-gray-500">微信公众号</span>
</div>
<div class="text-center">
<!-- <img src="/qrcode-mini.png" alt="小程序码" class="w-32 h-32 mb-2" /> -->
<span class="text-sm text-gray-500">小程序</span>
</div>
</div>
<div class="text-sm text-gray-500">
<p>咨询热线95716 4009 100 100 1</p>
<button class="mt-2 px-6 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
联系我们
</button>
</div>
</div>
</div>
<div class="border-t border-gray-200 py-6">
<div class="flex items-center text-sm text-gray-500">
<img src="~/assets/nav/logo.png" alt="Logo" class="h-8">
<a v-for="(item, index) in qiLink" :href="item.link" class="text-gray-500 hover:text-blue-600 text-sm ml-4">
{{ item.text }}
</a>
</div>
<div class="flex items-center justify-between text-sm text-gray-500">
<div class="text-start flex flex-col">
<p class="mt-1">Copyright {{ new Date().getFullYear() }} Tencent Cloud. All Rights Reserved. 腾讯云 版权所有</p>
<p class="mt-1">深圳市腾讯计算机系统有限公司ICP备案/许可证号粤B2-20090059
粤公网安备44030502008569号
</p>
<p class="mt-4">腾讯云计算北京有限责任公司京ICP证150476号 | 京ICP备11018762号| 域名注册服务机构许可:京D3-20230006| 增值电信业务经营许可证B1.B2-20130326 |
京B2-20170284</p>
<p class="mt-1">代理域名注册服务机构烟台帝思普网络科技有限公司 | 新网数码 | 广州云讯信息科技有限公司</p>
</div>
<div>
<select class="bg-transparent border-none" v-model="selectedLanguage">
<option value="zh">中国站</option>
<option value="en">International</option>
<option value="jp">日本語</option>
</select>
</div>
</div>
</div>
</qi-container>
</template>
<script setup lang="ts">
import { ref } from 'vue'
interface FooterItem {
text: string;
link: string;
}
interface FooterSection {
title: string;
items: FooterItem[];
}
const selectedLanguage = ref('zh')
const qiLink = [
{
text: '产品文档',
link: '/'
},
{
text: 'API 中心',
link: '/'
},
{
text: 'SDK 中心',
link: '/'
},
{
text: '入门中心',
link: '/'
},
{
text: '开发者社区',
link: '/'
},
{
text: '培训认证',
link: '/'
},
]
const footerSections: FooterSection[] = [
{
title: '热门推荐',
items: [
{ text: '云服务器', link: '/' },
{ text: '轻量应用服务器', link: '/' },
{ text: '对象存储', link: '/' },
{ text: '云数据库 MySQL', link: '/' },
{ text: '域名注册', link: '/' },
{ text: '人脸识别', link: '/' },
{ text: '实时音视频', link: '/' },
{ text: '即时通信 IM', link: '/' }
]
},
{
title: '资源与社区',
items: [
{ text: '产品文档', link: '/' },
{ text: 'API 中心', link: '/' },
{ text: 'SDK 中心', link: '/' },
{ text: '入门中心', link: '/' },
{ text: '开发者社区', link: '/' },
{ text: '培训认证', link: '/' },
{ text: '腾讯云学堂', link: '/' }
]
},
{
title: '支持服务',
items: [
{ text: '公告', link: '/' },
{ text: '控制台', link: '/' },
{ text: '续费', link: '/' },
{ text: '安全中心', link: '/' },
{ text: '举报平台', link: '/' },
{ text: '健康专板', link: '/' },
{ text: '联系我们', link: '/' },
{ text: 'ICP 备案', link: '/' }
]
},
{
title: '腾讯云计算',
items: [
{ text: '最新动态', link: '/' },
{ text: '免费试用', link: '/' },
{ text: '合作伙伴', link: '/' },
{ text: '客户案例', link: '/' },
{ text: '合规认证', link: '/' },
{ text: '关于我们', link: '/' },
{ text: 'Techo 开发者大会', link: '/' },
{ text: '2024腾讯全球数字生态大会', link: '/' }
]
}
];
</script>
<style scoped>
select {
appearance: none;
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236B7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
background-position: right 0.5rem center;
background-repeat: no-repeat;
background-size: 1.5em 1.5em;
padding-right: 2.5rem;
}
</style>
+111
View File
@@ -0,0 +1,111 @@
<template>
<header class="w-full bg-white shadow box-border">
<div class="mx-full flex items-center justify-between pl-4 ">
<!-- 左侧 Logo 和菜单 -->
<div class="flex items-center space-x-6">
<nuxt-img src="/nav/logo.png" alt="Logo" class="h-8" />
<nav class="flex space-x-4">
<qi-link
v-for="item in navList"
:href="item.link"
@mouseenter="showDropdown(item)"
@mouseleave="hideDropdown"
:key="item.name"
>
{{ item.name }}
</qi-link>
</nav>
</div>
<!-- 中间 搜索框 -->
<!-- 右侧菜单 -->
<div class="flex items-center space-x-4">
<div class="flex-1">
<t-input placeholder="Search Input" clearable>
<template #suffixIcon>
<search-icon :style="{ cursor: 'pointer' }" />
</template>
</t-input>
</div>
<t-dropdown :options="siteOptions" placement="bottom-right">
<span class="cursor-pointer text-gray-700">中国站</span>
</t-dropdown>
<a href="#" class="text-gray-700 hover:text-blue-600">文档</a>
<a href="#" class="text-gray-700 hover:text-blue-600">备案</a>
<a href="#" class="text-gray-700 hover:text-blue-600">控制台</a>
<a href="#" class="text-gray-700 hover:text-blue-600">登录</a>
<a class="h-full bg-blue-600 cursor-pointer text-white px-4 py-3 text-center">免费注册</a>
<!-- <t-button theme="primary">免费注册</t-button> -->
</div>
</div>
<!-- 下拉弹窗内容 -->
<div
v-if="dropdownVisible"
class="absolute bg-white shadow rounded p-4 z-10 mt-2 w-full mx-auto"
@mouseenter="cancelHide"
@mouseleave="hideDropdown"
>
<div >
<h3 class="text-lg font-bold mb-2">{{currentDropdown.name}}</h3>
<p>这里是最新活动的相关内容</p>
</div>
<div v-if="currentDropdown === 'products'">
<h3 class="text-lg font-bold mb-2">产品</h3>
<p>这里是产品的相关内容</p>
</div>
</div>
</header>
</template>
<script setup lang="ts">
// import searchIcon from 'tdesign-icons-vue-next/Search'
import { SearchIcon } from 'tdesign-icons-vue-next';
const siteOptions = [
{ content: '中国站', value: 'cn' },
{ content: '国际站', value: 'global' },
]
const navList = ref([
{ name: '最新活动', link: '#' },
{ name: '产品', link: '#' },
{ name: '解决方案', link: '#' },
{ name: '定价', link: '#' },
{ name: '企业中心', link: '#' },
{ name: '开发者', link: '#' },
{ name: '客户支持', link: '#' },
{ name: '合作与生态', link: '/about2' },
{ name: '关于我们', link: '/about' },
])
const dropdownVisible = ref(false)
const currentDropdown = ref({})
let hideTimeout: ReturnType<typeof setTimeout> | null = null
function showDropdown(type: string) {
currentDropdown.value = type
dropdownVisible.value = true
if (hideTimeout) {
clearTimeout(hideTimeout)
hideTimeout = null
}
}
function hideDropdown() {
hideTimeout = setTimeout(() => {
dropdownVisible.value = false
currentDropdown.value = {}
}, 200)
}
function cancelHide() {
if (hideTimeout) {
clearTimeout(hideTimeout)
hideTimeout = null
}
}
</script>
<style>
/* 可以根据需要定制 TailwindCSS 配置 */
</style>
+5
View File
@@ -0,0 +1,5 @@
<template>
<div class="container m-auto p-4">
<slot></slot>
</div>
</template>
+29
View File
@@ -0,0 +1,29 @@
<template>
<div @click="$router.push(props.href)" class="qi-link">
<slot></slot>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
href: {
type: String,
required: true,
},
})
</script>
<style scoped>
.qi-link {
cursor: pointer;
transition: 0.5s;
padding: 0.5rem 0rem;
border: 3px solid transparent;
}
.qi-link:hover {
color: var(--td-brand-color-hover);
border-bottom: 3px solid var(--td-brand-color-7);
}
</style>
+6
View File
@@ -0,0 +1,6 @@
<template>
<div>
<p></p>
<slot />
</div>
</template>
+13
View File
@@ -0,0 +1,13 @@
<template>
<div class="flex flex-col h-screen">
<div class="leading-10 bg-slate-500 fixed w-full z-20 ">
<layout-header></layout-header>
</div>
<div class="flex-1 pt-10 bg-gray-100">
<slot />
</div>
<div class="h-auto text-center">
<layout-footer></layout-footer>
</div>
</div>
</template>
+82
View File
@@ -0,0 +1,82 @@
<template>
<div class="about-container">
<!-- Hero Section -->
<section class="hero-section">
<h1 class="text-3xl font-bold text-center mb-4">提供全球领先的云计算服务</h1>
<p class="text-gray-600 text-center mb-8">面向全世界各个国家和地区的分析机构企业用户和个人开发者提供全球领先的云计算大数据AI智能等技术产品与服务</p>
<div class="text-center">
<button class="bg-blue-500 text-white px-6 py-2 rounded-lg hover:bg-blue-600">了解更多</button>
</div>
</section>
<!-- Statistics Section -->
<section class="stats-section grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4 my-12">
<!-- <qi-container></qi-container> -->
<div class="stat-card">
<div class="text-2xl font-bold text-blue-600">100W+</div>
<div class="text-sm text-gray-600">全球服务器数量</div>
</div>
<div class="stat-card">
<div class="text-2xl font-bold text-blue-600">EB级别</div>
<div class="text-sm text-gray-600">数据存储规模</div>
</div>
<div class="stat-card">
<div class="text-2xl font-bold text-blue-600">3200+</div>
<div class="text-sm text-gray-600">全球加速节点数</div>
</div>
<div class="stat-card">
<div class="text-2xl font-bold text-blue-600">200T</div>
<div class="text-sm text-gray-600">带宽峰值</div>
</div>
<div class="stat-card">
<div class="text-2xl font-bold text-blue-600">400+</div>
<div class="text-sm text-gray-600">云产品服务</div>
</div>
</section>
<!-- Features Section -->
<section class="features-section my-12">
<h2 class="text-2xl font-bold text-center mb-8">五大优势</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6">
<div class="feature-card">
<h3 class="text-lg font-semibold mb-2">高效稳定</h3>
<p class="text-sm text-gray-600">深耕技术创新打造高性能解决方案</p>
</div>
<div class="feature-card">
<h3 class="text-lg font-semibold mb-2">安全可靠</h3>
<p class="text-sm text-gray-600">全方位的安全防护体系</p>
</div>
<div class="feature-card">
<h3 class="text-lg font-semibold mb-2">丰富场景</h3>
<p class="text-sm text-gray-600">覆盖多样化的业务应用场景</p>
</div>
<div class="feature-card">
<h3 class="text-lg font-semibold mb-2">开放生态</h3>
<p class="text-sm text-gray-600">打造共赢的合作生态系统</p>
</div>
<div class="feature-card">
<h3 class="text-lg font-semibold mb-2">服务保障</h3>
<p class="text-sm text-gray-600">7*24小时专业服务支持</p>
</div>
</div>
</section>
</div>
</template>
<style scoped>
.about-container {
@apply max-w-7xl mx-auto px-4 py-12;
}
.hero-section {
@apply bg-gray-50 rounded-xl p-8 mb-12;
}
.stat-card {
@apply bg-white p-6 rounded-lg shadow-sm text-center hover:shadow-md transition-shadow duration-300;
}
.feature-card {
@apply bg-white p-6 rounded-lg shadow-sm hover:shadow-md transition-shadow duration-300;
}
</style>
+133
View File
@@ -0,0 +1,133 @@
<template>
<div class="reasons-container">
<h1 class="title">选择腾讯云的五大理由</h1>
<div class="reasons-grid">
<div class="reason-card" v-for="(reason, index) in reasons" :key="index">
<div class="icon-wrapper">
<img :src="reason.icon" :alt="reason.title">
</div>
<h3>{{ reason.title }}</h3>
<p>{{ reason.description }}</p>
</div>
</div>
</div>
</template>
<script setup>
const reasons = [
{
title: '高效稳定',
description: '深厚的基础架构,自研的操作系统,多年技术积累和海量服务经验,为客户提供可靠、稳运维、智能化、弹性化的云服务。',
// icon: '/icons/stable.png'
},
{
title: '安全可靠',
description: '七大安全联合实验室团队,一体化病毒安全管理体系,助您建立系统性的安全防御机制。',
// icon: '/icons/security.png'
},
{
title: '丰富场景',
description: '从基础设施到行业应用领域,提供完善的产品体系,为各行业客户提供全球领先方案,助力业务腾飞。',
// icon: '/icons/rich.png'
},
{
title: '开放生态',
description: '完整的合作伙伴生态体系,与产业链上下游通力合作,提供优质的服务和丰富的产品选择。',
// icon: '/icons/open.png'
},
{
title: '服务保障',
description: '7*24小时贴心服务保障,多元化的服务支持,提供专业的技术咨询,让您的云上之旅更加安心。',
// icon: '/icons/service.png'
}
]
</script>
<style scoped>
.reasons-container {
max-width: 1400px;
margin: 0 auto;
padding: 40px 20px;
}
.title {
text-align: center;
font-size: 32px;
color: #333;
margin-bottom: 40px;
}
.reasons-grid {
display: flex;
justify-content: space-between;
gap: 20px;
}
.reason-card {
flex: 1;
background: #fff;
border-radius: 12px;
padding: 20px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
cursor: pointer;
min-width: 200px;
}
.reason-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.icon-wrapper {
width: 60px;
height: 60px;
margin: 0 auto 15px;
display: flex;
align-items: center;
justify-content: center;
}
.icon-wrapper img {
width: 100%;
height: 100%;
object-fit: contain;
}
.reason-card h3 {
font-size: 18px;
color: #333;
margin-bottom: 10px;
text-align: center;
}
.reason-card p {
font-size: 13px;
color: #666;
line-height: 1.5;
text-align: center;
}
@media (max-width: 1200px) {
.reasons-grid {
flex-wrap: wrap;
}
.reason-card {
flex: 1 1 calc(33.333% - 20px);
min-width: 250px;
}
}
@media (max-width: 768px) {
.reason-card {
flex: 1 1 calc(50% - 20px);
}
}
@media (max-width: 480px) {
.reason-card {
flex: 1 1 100%;
}
}
</style>
+114
View File
@@ -0,0 +1,114 @@
<script setup lang="ts">
import { z } from 'zod'
import type { FormSubmitEvent } from '#ui/types'
const options = [
{ label: 'Option 1', value: 'option-1' },
{ label: 'Option 2', value: 'option-2' },
{ label: 'Option 3', value: 'option-3' },
]
const state = reactive({
input: undefined,
inputMenu: undefined,
textarea: undefined,
select: undefined,
selectMenu: undefined,
checkbox: undefined,
toggle: undefined,
radio: undefined,
radioGroup: undefined,
switch: undefined,
range: undefined,
})
const schema = z.object({
input: z.string().min(10),
inputMenu: z.any().refine((option) => option?.value === 'option-2', {
message: 'Select Option 2',
}),
textarea: z.string().min(10),
select: z.string().refine((value) => value === 'option-2', {
message: 'Select Option 2',
}),
selectMenu: z.any().refine((option) => option?.value === 'option-2', {
message: 'Select Option 2',
}),
toggle: z.boolean().refine((value) => value === true, {
message: 'Toggle me',
}),
checkbox: z.boolean().refine((value) => value === true, {
message: 'Check me',
}),
radio: z.string().refine((value) => value === 'option-2', {
message: 'Select Option 2',
}),
radioGroup: z.string().refine((value) => value === 'option-2', {
message: 'Select Option 2',
}),
range: z.number().max(20, { message: 'Must be less than 20' }),
})
type Schema = z.infer<typeof schema>
const form = ref()
async function onSubmit(event: FormSubmitEvent<Schema>) {
// Do something with event.data
console.log(event.data)
}
</script>
<template>
<div class="container m-auto p-4">
<UForm ref="form" :schema="schema" :state="state" class="space-y-4" @submit="onSubmit">
<div class="grid grid-cols-2 gap-4">
<UFormGroup name="input" label="Input">
<UInput v-model="state.input" />
</UFormGroup>
<UFormGroup name="inputMenu" label="Input Menu">
<UInputMenu v-model="state.inputMenu" :options="options" />
</UFormGroup>
</div>
<UFormGroup name="textarea" label="Textarea">
<UTextarea v-model="state.textarea" />
</UFormGroup>
<UFormGroup name="select" label="Select">
<USelect v-model="state.select" placeholder="Select..." :options="options" />
</UFormGroup>
<UFormGroup name="selectMenu" label="Select Menu">
<USelectMenu v-model="state.selectMenu" placeholder="Select..." :options="options" />
</UFormGroup>
<UFormGroup name="toggle" label="Toggle">
<UToggle v-model="state.toggle" />
</UFormGroup>
<UFormGroup name="checkbox" label="Checkbox">
<UCheckbox v-model="state.checkbox" label="Check me" />
</UFormGroup>
<UFormGroup name="radioGroup" label="Radio Group">
<URadioGroup v-model="state.radioGroup" :options="options" />
</UFormGroup>
<UFormGroup name="radio" label="Radio">
<URadio v-for="option in options" :key="option.value" v-model="state.radio" v-bind="option">
{{ option.label }}
</URadio>
</UFormGroup>
<UFormGroup name="range" label="Range">
<URange v-model="state.range" />
</UFormGroup>
<UButton type="submit">Submit</UButton>
<UButton variant="outline" class="ml-2" @click="form.clear()">Clear</UButton>
</UForm>
</div>
</template>
+8
View File
@@ -0,0 +1,8 @@
<template>
<div>
<!-- <img class="w-full" src="~/assets/images/pretty-girl.png" /> -->
<div class="container m-auto bg-yellow-100 p-4">
<fg-content :line="40" />
</div>
</div>
</template>
+4
View File
@@ -0,0 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}