第八章:实战项目案例
第八章实战项目案例8.1 项目一Todo 应用Vue 3 Pinia项目初始化npmcreate vitelatest todo-app ----templatevuecdtodo-appnpminstallpinianpminstall-Dvitejs/plugin-vue项目结构todo-app/ ├── src/ │ ├── components/ │ │ ├── TodoList.vue │ │ ├── TodoItem.vue │ │ └── TodoForm.vue │ ├── stores/ │ │ └── todo.js │ ├── App.vue │ └── main.js └── vite.config.jsStore 实现// src/stores/todo.jsimport{defineStore}frompiniaimport{ref,computed}fromvueexportconstuseTodoStoredefineStore(todo,(){consttodosref([{id:1,text:学习 Vite,completed:false},{id:2,text:学习 Pinia,completed:false}])constaddTodo(text){todos.value.push({id:Date.now(),text,completed:false})}consttoggleTodo(id){consttodotodos.value.find(tt.idid)if(todo)todo.completed!todo.completed}constdeleteTodo(id){todos.valuetodos.value.filter(tt.id!id)}constcompletedCountcomputed(()todos.value.filter(tt.completed).length)constpendingCountcomputed(()todos.value.length-completedCount.value)return{todos,addTodo,toggleTodo,deleteTodo,completedCount,pendingCount}})组件实现!-- src/components/TodoList.vue -- template div classtodo-list div classstats span总计: {{ todos.length }}/span span已完成: {{ completedCount }}/span span未完成: {{ pendingCount }}/span /div div v-fortodo in todos :keytodo.id classtodo-item input typecheckbox :checkedtodo.completed changetoggleTodo(todo.id) / span :class{ completed: todo.completed }{{ todo.text }}/span button clickdeleteTodo(todo.id)删除/button /div /div /template script setup import { useTodoStore } from ../stores/todo import { storeToRefs } from pinia const todoStore useTodoStore() const { todos, completedCount, pendingCount } storeToRefs(todoStore) const { toggleTodo, deleteTodo } todoStore /script style scoped .todo-list { max-width: 500px; margin: 0 auto; } .stats { display: flex; gap: 20px; margin-bottom: 20px; padding: 10px; background: #f5f5f5; border-radius: 8px; } .todo-item { display: flex; align-items: center; gap: 10px; padding: 10px; border-bottom: 1px solid #eee; } .completed { text-decoration: line-through; color: #999; } button { margin-left: auto; padding: 4px 12px; background: #ff4444; color: white; border: none; border-radius: 4px; cursor: pointer; } /style8.2 项目二博客系统React React Router项目初始化npmcreate vitelatest blog ----templatereactcdblognpminstallreact-router-domnpminstall-Dvitejs/plugin-react路由配置// src/router.jsximport{createBrowserRouter}fromreact-router-domimportLayoutfrom./LayoutimportHomefrom./pages/HomeimportPostfrom./pages/PostimportAboutfrom./pages/AboutexportconstroutercreateBrowserRouter([{path:/,element:Layout/,children:[{index:true,element:Home/},{path:post/:id,element:Post/},{path:about,element:About/}]}])使用 Vite 的 import.meta.glob// src/pages/Home.jsximport{useState,useEffect}fromreact// 动态导入所有 Markdown 文件constmodulesimport.meta.glob(../posts/*.md,{as:raw,eager:true})functionHome(){const[posts,setPosts]useState([])useEffect((){constpostsDataObject.entries(modules).map(([path,content])({id:path.split(/).pop().replace(.md,),title:extractTitle(content),excerpt:content.slice(0,200)...}))setPosts(postsData)},[])functionextractTitle(content){constmatchcontent.match(/^# (.)$/m)returnmatch?match[1]:无标题}return(divh1我的博客/h1{posts.map(post(article key{post.id}h2{post.title}/h2p{post.excerpt}/pa href{/post/${post.id}}/a/article))}/div)}exportdefaultHome8.3 项目三组件库开发项目结构my-ui/ ├── src/ │ ├── components/ │ │ ├── Button/ │ │ │ ├── index.js │ │ │ ├── Button.vue │ │ │ └── style.css │ │ └── Input/ │ │ ├── index.js │ │ └── Input.vue │ └── index.js ├── vite.config.js └── package.jsonVite 配置库模式// vite.config.jsimport{defineConfig}fromviteimportvuefromvitejs/plugin-vueimportpathfrompathexportdefaultdefineConfig({plugins:[vue()],build:{lib:{entry:path.resolve(__dirname,src/index.js),name:MyUI,formats:[es,umd],fileName:(format)my-ui.${format}.js},rollupOptions:{external:[vue],output:{globals:{vue:Vue},assetFileNames:(assetInfo){if(assetInfo.namestyle.css)returnmy-ui.cssreturnassetInfo.name}}}},css:{preprocessorOptions:{scss:{additionalData:import ./src/styles/variables.scss;}}}})组件实现!-- src/components/Button/Button.vue -- template button :class[btn, btn-${type}] :disableddisabled click$emit(click) slot / /button /template script setup defineProps({ type: { type: String, default: primary, validator: (v) [primary, success, danger].includes(v) }, disabled: Boolean }) defineEmits([click]) /script style scoped .btn { padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; } .btn-primary { background: #42b983; color: white; } .btn-success { background: #67c23a; color: white; } .btn-danger { background: #f56c6c; color: white; } .btn:disabled { opacity: 0.6; cursor: not-allowed; } /style8.4 项目四PWA 应用配置 PWAnpminstall-Dvite-plugin-pwa// vite.config.jsimport{VitePWA}fromvite-plugin-pwaexportdefaultdefineConfig({plugins:[VitePWA({registerType:autoUpdate,includeAssets:[favicon.ico,apple-touch-icon.png],manifest:{name:My PWA App,short_name:PWA,description:A Vite PWA App,theme_color:#ffffff,icons:[{src:pwa-192x192.png,sizes:192x192,type:image/png},{src:pwa-512x512.png,sizes:512x512,type:image/png}]},workbox:{globPatterns:[**/*.{js,css,html,ico,png,svg,woff2}],runtimeCaching:[{urlPattern:/^https:\/\/fonts\.googleapis\.com\/.*/i,handler:CacheFirst,options:{cacheName:google-fonts-cache,expiration:{maxEntries:10,maxAgeSeconds:60*60*24*365}}}]}})]})更新通知// src/main.jsif(serviceWorkerinnavigator){navigator.serviceWorker.addEventListener(controllerchange,(){window.location.reload()})}8.5 项目五Chrome 扩展项目结构chrome-extension/ ├── public/ │ ├── manifest.json │ └── icon.png ├── src/ │ ├── popup/ │ │ ├── popup.html │ │ └── popup.js │ ├── background/ │ │ └── background.js │ └── content/ │ └── content.js └── vite.config.jsVite 配置// vite.config.jsimport{defineConfig}fromviteimport{resolve}frompathexportdefaultdefineConfig({build:{outDir:dist,rollupOptions:{input:{popup:resolve(__dirname,src/popup/popup.html),background:resolve(__dirname,src/background/background.js),content:resolve(__dirname,src/content/content.js)},output:{entryFileNames:[name].js,assetFileNames:[name].[ext]}}}})Manifest{manifest_version:3,name:My Extension,version:1.0.0,action:{default_popup:popup.html},background:{service_worker:background.js},content_scripts:[{matches:[all_urls],js:[content.js]}],permissions:[storage,activeTab]}本章小结通过五个实战项目覆盖了✅ Vue 3 Pinia 状态管理✅ React Router 路由系统✅ 组件库开发与发布✅ PWA 离线应用✅ Chrome 扩展开发每个项目都是真实可运行的可以作为学习和参考的基础。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2488812.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!