做网站 中企动力海燕网站建设公司
做网站 中企动力,海燕网站建设公司,网站子目录安装dedecms导致网页布局混乱的解决方法,做网站第一步要学什么1. 从零开始#xff1a;用 Vite 快速搭建你的第一个 Vue 3 项目
很多新手朋友一上来就被各种配置吓到了#xff0c;觉得搭建环境是个大工程。其实现在早就不是那个需要手动配半天 webpack 的时代了。我刚开始学的时候也走过弯路#xff0c;但现在我首推 Vite#xff0c;因为…1. 从零开始用 Vite 快速搭建你的第一个 Vue 3 项目很多新手朋友一上来就被各种配置吓到了觉得搭建环境是个大工程。其实现在早就不是那个需要手动配半天 webpack 的时代了。我刚开始学的时候也走过弯路但现在我首推 Vite因为它真的太快了快到让你感觉不到“构建”这个过程的存在。它不像传统的打包工具那样启动时要先把你整个项目的模块都分析一遍而是利用了现代浏览器原生支持 ES 模块的特性按需提供源码。简单说就是你改一行代码浏览器几乎立刻就更新了几乎没有等待时间。那第一步我们得确保你电脑上装了 Node.js。去官网下载最新的 LTS长期支持版本就行安装过程一路下一步。装好后打开你的终端Windows 用户用 PowerShell 或 CMDMac 用户用终端输入node -v和npm -v能看到版本号就说明成功了。接下来我们不用 Vue CLI直接用 Vite 官方提供的模板。在终端里找个你喜欢的文件夹执行下面这行命令npm create vuelatest这个命令会启动一个交互式的项目创建向导。它会问你几个问题比如项目名、是否要 TypeScript、JSX 支持、路由、状态管理等等。对于初学者我的建议是项目名随便起一个比如my-vue-blogTypeScript可以先选 No等熟悉了基础再加JSX选 NoVue Router选 Yes这个我们后面做多页面要用Pinia选 Yes这是新一代的状态管理工具比 Vuex 简单好用ESLint和Prettier建议都选 Yes它们能帮你保持代码整洁规范。一路回车下来项目就创建好了。接着按照终端的提示进入项目目录安装依赖然后启动开发服务器cd my-vue-blog npm install npm run dev执行完npm run dev通常一两秒钟终端就会告诉你一个本地地址比如http://localhost:5173。你把它复制到浏览器打开一个最基础的 Vue 应用页面就出来了。整个过程可能不到一分钟是不是比想象中简单多了这个项目已经自带了 Vue Router 和 Pinia 的基本配置文件结构也非常清晰。src目录下components放组件views或pages放页面router和stores里分别是路由和状态管理的配置。这种开箱即用的体验能让你跳过繁琐的配置直接开始写业务逻辑对于保持学习热情至关重要。2. 理解核心组件、响应式与 Composition API项目跑起来了我们得聊聊 Vue 的灵魂。Vue 的核心思想是“组件化”和“响应式”。你可以把一个复杂的网页想象成一个乐高模型而每个组件就是一块乐高积木。比如一个博客网站导航栏是一个组件文章列表是一个组件侧边栏又是一个组件。组件可以复用可以组合这让开发和维护变得非常清晰。在 Vue 3 里我们写一个组件通常用一个.vue文件里面包含三部分template模板、script脚本和style样式。响应式是 Vue 的魔法。你定义一个数据当这个数据变化时用到它的视图会自动更新。在 Vue 2 里我们用的是data()函数和Options API。但在 Vue 3我强烈推荐你直接从Composition API学起。它用起来更灵活逻辑组织也更清晰。它的核心是ref和reactive这两个函数。ref用来定义基本类型如字符串、数字的响应式数据而reactive用来定义对象或数组。在模板里ref定义的值需要用.value来访问但在模板中 Vue 会自动帮你“解包”所以直接写名字就行。让我们写一个最简单的计数器组件来感受一下。在src/components下新建一个Counter.vue文件template div classcounter h3{{ title }}/h3 p当前的计数是{{ count }}/p button clickincrement点我加1/button button clickdecrement点我减1/button p双倍计数{{ doubleCount }}/p /div /template script setup import { ref, computed } from vue // 定义响应式数据 const count ref(0) const title ref(我的第一个计数器) // 定义计算属性 const doubleCount computed(() count.value * 2) // 定义方法 function increment() { count.value } function decrement() { count.value-- } /script style scoped .counter { border: 1px solid #eee; padding: 20px; border-radius: 8px; margin: 10px; } /style注意看script setup这个语法这是 Composition API 的语法糖它让代码变得更简洁。所有顶层的绑定变量、函数都能直接在模板里使用。computed用来创建依赖其他响应式数据的计算属性只有当依赖变化时它才会重新计算效率很高。style scoped里的scoped表示这里的样式只作用于当前组件不会影响其他组件避免了样式冲突。把这个组件引入到App.vue里你就能在页面上看到一个可以交互的计数器了。通过这个例子你应该能体会到数据和视图是联动的你只需要操作数据视图的事交给 Vue。3. 构建骨架用 Vue Router 设计博客的路由系统一个博客不能只有一个页面。我们需要首页展示文章列表点击文章要能进入详情页可能还有关于我、归档等页面。这就需要路由来管理了。Vue Router 就是专门干这个的。在我们用 Vite 创建项目时如果选了 Yes它已经帮我们安装并配置好了基础路由。打开src/router/index.js或index.ts文件你会看到类似下面的结构import { createRouter, createWebHistory } from vue-router import HomeView from ../views/HomeView.vue const router createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: /, name: home, component: HomeView }, { path: /about, name: about, // 路由级代码分割懒加载组件 component: () import(../views/AboutView.vue) } ] }) export default routercreateWebHistory创建的是历史模式它的路由路径像http://localhost/about更美观但需要服务器做一些配置。如果怕麻烦可以用createWebHashHistory它会在 URL 里带个#像http://localhost/#/about但部署简单。routes数组里定义了我们的路由表。每个路由对象至少需要path路径和component组件。name属性是可选的但在编程式导航时很有用。对于我们的博客我们来规划几个路由/首页显示文章列表。/article/:id文章详情页id是动态参数代表文章的唯一标识。/archive归档页面按时间分类文章。/about关于我页面。我们来添加文章详情页的路由并演示动态路由和懒加载。首先在src/views下创建ArticleDetail.vue。然后在路由文件中添加{ path: /article/:id, name: article, component: () import(../views/ArticleDetail.vue), // 一个可选的 props 配置可以将路由参数作为组件的 props 传入让组件更纯净 props: true }在首页的列表组件里我们可以这样跳转到详情页template div v-forarticle in articleList :keyarticle.id h3{{ article.title }}/h3 p{{ article.summary }}/p !-- 使用 router-link 进行声明式导航 -- router-link :to/article/${article.id}阅读全文/router-link !-- 或者在方法里使用编程式导航 -- button clickgoToDetail(article.id)编程式跳转/button /div /template script setup import { useRouter } from vue-router const router useRouter() function goToDetail(id) { // 使用 name 跳转更稳定即使 path 改了也没关系 router.push({ name: article, params: { id: id } }) } /script在ArticleDetail.vue组件里我们可以通过route对象获取到传递过来的id参数然后根据这个id去请求对应的文章数据script setup import { useRoute } from vue-router import { ref, onMounted } from vue import { fetchArticleById } from /api/article // 假设有个 API 模块 const route useRoute() const article ref(null) const loading ref(true) onMounted(async () { const articleId route.params.id try { article.value await fetchArticleById(articleId) } catch (error) { console.error(获取文章失败, error) } finally { loading.value false } }) /script路由守卫也是一个非常重要的概念。比如我们想在用户进入某个页面之前检查他是否登录就可以用“全局前置守卫”// 在 router/index.js 中 router.beforeEach((to, from) { // 假设我们有一个元信息 meta.requiresAuth 来标记哪些页面需要登录 if (to.meta.requiresAuth !isAuthenticated()) { // 如果未登录则重定向到登录页 return { name: login } } })通过这样的设计我们博客的页面骨架就清晰了不同页面之间的跳转和参数传递也变得非常顺畅。4. 状态管理使用 Pinia 管理博客的全局数据随着应用变大组件之间需要共享的数据会越来越多。比如用户登录信息、博客的主题模式深色/浅色、全站的提示消息等。如果只用组件间的props和emit来传递会变得非常复杂和混乱。这时候就需要一个“状态管理库”来帮忙。Vue 官方以前推荐 Vuex但现在有了更现代、更简单的选择——Pinia。它和 Vuex 的核心思想类似但 API 设计更贴合 Composition API用起来也更直观。Pinia 的核心概念是Store仓库。一个 Store 就是一个包含状态和业务逻辑的实体。我们的博客可以创建几个 Store比如useUserStore管理用户登录状态、用户信息。useThemeStore管理 UI 主题亮色/暗色。useNotificationStore管理全局的通知消息。我们用创建项目时自带的 Pinia 来创建一个主题 Store。在src/stores目录下新建一个theme.js或theme.tsimport { defineStore } from pinia import { ref, computed } from vue export const useThemeStore defineStore(theme, () { // 状态 const themeMode ref(light) // light 或 dark // 计算属性 const isDarkMode computed(() themeMode.value dark) // 动作Action function toggleTheme() { themeMode.value themeMode.value light ? dark : light // 可以在这里把主题保存到 localStorage实现持久化 localStorage.setItem(app-theme, themeMode.value) // 也可以在这里动态修改 HTML 根元素的 class用于 CSS 变量切换 document.documentElement.setAttribute(data-theme, themeMode.value) } function initializeTheme() { const savedTheme localStorage.getItem(app-theme) if (savedTheme) { themeMode.value savedTheme } document.documentElement.setAttribute(data-theme, themeMode.value) } return { themeMode, isDarkMode, toggleTheme, initializeTheme } })这个 Store 使用了defineStore并传入一个函数这是 Composition API 风格的写法里面定义了响应式状态themeMode、计算属性isDarkMode和修改状态的方法toggleTheme、initializeTheme。现在在任何组件里我们都可以使用这个 Store 了template div :class{ dark-theme: theme.isDarkMode } button clicktheme.toggleTheme 切换主题 (当前: {{ theme.themeMode }}) /button p这是正文内容.../p /div /template script setup import { useThemeStore } from /stores/theme const theme useThemeStore() // 在应用初始化时调用比如在 App.vue 的 onMounted 里 // theme.initializeTheme() /script style .dark-theme { background-color: #333; color: #fff; } /style你看在组件里使用 Store 非常简单就像调用一个函数一样。而且状态是响应式的当你在一个组件里调用toggleTheme改变了themeMode所有用到这个 Store 的组件都会自动更新。Pinia 还支持模块化你可以把不同的业务状态分到不同的 Store 文件里结构非常清晰。相比于 Vuex 的state、mutations、actions、getters分块定义Pinia 这种“一体化”的写法逻辑更集中也更符合直觉。5. 实战演练搭建一个博客首页与文章列表理论说了这么多我们动手来搭一个博客首页。这个页面需要展示文章列表并且有加载、错误处理等状态。我们会用到之前学的组件、路由、状态管理还会涉及到一些实战中的小技巧。首先我们来设计文章的数据结构。通常一篇文章会包含标题、摘要、封面图、发布时间、分类、标签等。我们可以先定义一个简单的结构。在src/api/mockData.js里模拟一些数据// 模拟文章数据 export const mockArticles [ { id: 1, title: Vue 3 Composition API 入门指南, summary: 详细介绍了 Vue 3 全新的 Composition API 的使用方法和设计理念帮助你更好地组织组件逻辑。, coverImage: https://picsum.photos/seed/picsum/300/200, publishTime: 2023-10-26, category: 前端框架, tags: [Vue3, Composition API, 教程] }, { id: 2, title: Pinia vs Vuex下一代状态管理该选谁, summary: 对比分析了 Pinia 和 Vuex 的优缺点并给出了在新时代 Vue 项目中的选型建议。, coverImage: https://picsum.photos/seed/picsum2/300/200, publishTime: 2023-10-25, category: 状态管理, tags: [Pinia, Vuex, 状态管理] }, // ... 更多模拟数据 ]然后我们创建一个ArticleList.vue组件放在src/components下。这个组件负责获取数据并渲染列表template div classarticle-list div v-ifloading classloading加载中.../div div v-else-iferror classerror{{ error }}/div div v-else div v-forarticle in articles :keyarticle.id classarticle-card img :srcarticle.coverImage :altarticle.title classcover / div classcontent h3 classtitle router-link :to{ name: article, params: { id: article.id } } {{ article.title }} /router-link /h3 p classsummary{{ article.summary }}/p div classmeta span classtime{{ formatDate(article.publishTime) }}/span span classcategory{{ article.category }}/span span v-fortag in article.tags :keytag classtag{{ tag }}/span /div /div /div /div /div /template script setup import { ref, onMounted } from vue import { mockArticles } from /api/mockData // 暂时用模拟数据 const articles ref([]) const loading ref(true) const error ref(null) // 模拟一个异步请求 function fetchArticles() { return new Promise((resolve) { setTimeout(() { resolve(mockArticles) }, 800) // 模拟网络延迟 }) } onMounted(async () { try { articles.value await fetchArticles() } catch (err) { error.value 获取文章列表失败请稍后重试。 console.error(err) } finally { loading.value false } }) // 一个简单的日期格式化函数 function formatDate(dateString) { const options { year: numeric, month: long, day: numeric } return new Date(dateString).toLocaleDateString(zh-CN, options) } /script style scoped .article-list { max-width: 800px; margin: 0 auto; } .article-card { display: flex; margin-bottom: 30px; border-bottom: 1px solid #eee; padding-bottom: 20px; } .cover { width: 200px; height: 140px; object-fit: cover; border-radius: 8px; margin-right: 20px; } .content { flex: 1; } .title a { color: inherit; text-decoration: none; } .title a:hover { color: #42b983; /* Vue 主题色 */ } .meta { margin-top: 10px; font-size: 0.9em; color: #666; } .meta * { margin-right: 10px; } .tag { display: inline-block; background: #f0f0f0; padding: 2px 8px; border-radius: 12px; font-size: 0.8em; } .loading, .error { text-align: center; padding: 40px; font-size: 1.2em; } /style这个组件里我们处理了三种状态加载中、加载失败和加载成功。使用了v-if、v-else-if、v-else来条件渲染不同的 UI。列表渲染用了v-for并且记得给每个循环项一个唯一的:key这能帮助 Vue 高效地更新 DOM。点击文章标题会通过router-link跳转到对应的文章详情页。接下来我们把ArticleList组件放到首页视图HomeView.vue中。同时我们可以把顶部的导航栏也做成一个可复用的组件AppHeader.vue里面可以放上博客标题、导航菜单以及之前我们做的主题切换按钮。这样一个博客首页的雏形就出来了。在实际项目中数据请求会放在更专门的 Service 层或使用axios这样的 HTTP 库状态管理也可能把文章列表数据放到 Pinia Store 里供多个组件共享但基本的思路和流程就是这样一步步构建起来的。6. 进阶技巧Composition API 复用与 TypeScript 初探当你写了几个组件后可能会发现一些逻辑比如获取数据、监听窗口大小、格式化时间在多个组件里重复出现。这时候Composition API 的另一个巨大优势就体现出来了逻辑复用。我们可以把这些可复用的逻辑提取成“组合式函数”Composables。这比 Vue 2 时代的 Mixin 要清晰和强大得多因为组合式函数是基于函数的你可以清楚地看到数据的来源没有命名冲突的烦恼。举个例子我们几乎每个页面都需要处理加载和错误状态。我们可以创建一个useFetch组合式函数。在src/composables目录下没有就新建一个创建useFetch.jsimport { ref } from vue export function useFetch(url) { const data ref(null) const error ref(null) const loading ref(false) async function doFetch() { loading.value true error.value null data.value null try { const response await fetch(url) if (!response.ok) { throw new Error(HTTP error! status: ${response.status}) } data.value await response.json() } catch (e) { error.value e.message || 请求失败 } finally { loading.value false } } // 可以立即执行一次也可以由组件手动调用 // onMounted(doFetch) return { data, error, loading, doFetch } }然后在我们的ArticleList.vue组件里就可以这样使用script setup import { useFetch } from /composables/useFetch import { onMounted } from vue const { data: articles, error, loading, doFetch } useFetch(/api/articles) onMounted(() { doFetch() }) /script看是不是清爽多了所有与请求相关的状态和逻辑都被封装到了一个函数里组件只需要关心如何使用这些状态。你可以创建各种各样的组合式函数比如useLocalStorage、useMousePosition、useDebounce等等极大地提高了代码的复用性和可维护性。另一个让项目变得更健壮的工具是TypeScript。Vue 3 对 TypeScript 的支持是原生的非常好。即使你之前没学过 TypeScript也可以从简单的类型标注开始。它能帮你提前发现很多潜在的错误比如拼写错误、传参类型不对等。给我们的ArticleList组件加上类型首先确保你的项目支持 TypeScript创建时选了 Yes或者后来安装了typescript和vue/tsconfig。然后我们可以为文章定义一个接口Interface// src/types/article.ts export interface IArticle { id: number title: string summary: string coverImage: string publishTime: string category: string tags: string[] }接着修改我们的组件为.vue文件并在script标签上加上langtsscript setup langts import { ref, onMounted } from vue import type { IArticle } from /types/article import { mockArticles } from /api/mockData const articles refIArticle[]([]) // 这里指定了数组内部是 IArticle 类型 const loading ref(true) const error refstring | null(null) // 指定 error 可以是 string 或 null // 现在 fetchArticles 的返回值类型就被推断为 PromiseIArticle[] async function fetchArticles(): PromiseIArticle[] { // ... 模拟请求 return mockArticles as IArticle[] } onMounted(async () { try { articles.value await fetchArticles() } catch (err) { error.value err instanceof Error ? err.message : 未知错误 } finally { loading.value false } }) /script加了类型之后如果你不小心把articles.value赋值为一个字符串或者调用一个article对象上不存在的方法IDE比如 VSCode会立刻给你红色波浪线提示。这就像有个经验丰富的伙伴在帮你做代码审查能有效减少运行时错误。从长远来看在稍具规模的项目中引入 TypeScript绝对是利大于弊的。