먼저 npm 또는 원사를 사용하여 vue 프로젝트를 만듭니다
// 使用npm创建一个基于vite构建的vue项目 npm create vite@latest // 使用yarn创建一个基于vite构建的vue项目 yarn create vite@latest
생성된 컴포지션에서 선택합니다.
vue vue-ts
생성 후 프로젝트를 컴파일러로 드래그하여 엽니다
vite.config에서 프로젝트를 구성합니다. .ts 파일 서비스 데이터는 다음과 같이 구성됩니다.
// 此处配置项目服务参数 server: { host: "0.0.0.0", // 项目运行地址,此处代表localhost port: 8888, // 项目运行端口 open: true, //编译之后是否自动打开页面 hmr: true, // 是否开启热加载 },
그런 다음 서버 아래에 src 별칭 @을 구성하면 구성은 다음과 같습니다.
// 配置src的别名@ resolve: { alias: { "@": resolve(__dirname, "./src"), }, },
또한 ts 구성 파일 tsconfig.json에 다음 구성을 추가해야 합니다. :
"baseUrl": "./", // 配置路径解析的起点 "paths": { // 配置src别名 "@/*": ["src/*"] // 当我们输入@/时会被映射成src/ }
npm install vue-router@latest yarn add vue-router@latest
src 아래에 새 라우터 폴더를 생성하고 index.ts를 생성한 후 다음과 같이 구성합니다
import { createRouter, createWebHistory, RouteRecordRaw} from 'vue-router'; import Layout from '@/components/HelloWorld.vue' // 定义路由,此处为Array数组,数据类型为RouteRecordRaw const routes: Array<RouteRecordRaw> = [ { path: '/home', name: 'home', component: Layout } ] // 创建路由 const router = createRouter({ history: createWebHistory(), routes // 将定义的路由传入 }) // 将创建的router路由暴露,使其在其他地方可以被引用 export default router
'@/router/index'에서 main.ts 첫 번째 라우터에 가져오기를 전달합니다. 경로를 소개한 다음 다음과 같이 use 함수를 사용하여 경로를 등록합니다.
import { createApp } from 'vue' import './style.css' import App from './App.vue' // 此处引入定义的路由 import router from '@/router/index' // createApp(App).mount('#app') // 此处将链式创建拆解,从中注册路由 const app = createApp(App); // 注册路由 app.use(router) app.mount('#app')4 라우터 라우팅 사용이후. 등록이 완료되면
<template>
<!-- <div>
<a href="https://vitejs.dev" rel="external nofollow" target="_blank">
<img src="/vite.svg" class="logo" alt="Vite logo" />
</a>
<a href="https://vuejs.org/" rel="external nofollow" target="_blank">
<img src="@/assets/vue.svg" class="logo vue" alt="Vue logo" />
</a>
</div> -->
<!-- 在App的入口程序使用路由,会将我们注册的路由全部引入到App入口,通过路由的路径确定跳转的页面 -->
<router-view></router-view>
</template>
# 选择一个你喜欢的包管理器 // 安装element-plus npm install element-plus --save yarn add element-plus pnpm install element-plus // 安装element-plus的图标库组件 npm install @element-plus/icons-vue yarn add @element-plus/icons-vue pnpm install @element-plus/icons-vue
import { createApp } from "vue"; import "./style.css"; import App from "./App.vue"; // 次数引入定义的路由 import router from "@/router/index"; // 引入element-plus import ElementPlus from "element-plus"; import "element-plus/dist/index.css"; // 引入element-plus的图标库 import * as ElementPlusIconsVue from "@element-plus/icons-vue"; // createApp(App).mount('#app') // 此处将链式创建拆解,从中注册路由 const app = createApp(App); // 注册路由、element-plus等 app.use(router).use(ElementPlus); // 将所有配置挂载到index.html的id为app的容器上 app.mount("#app"); // 此处参考官网,意为将图标库中的每个图标都注册成组件 for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component); }4. pinia 사용 다음으로 저장소 폴더를 만들고 새 index.ts 파일을 만듭니다. 구성
yarn add pinia # 或者使用 npm npm install pinia
// 从pinia中引入创建实例的函数 import { createPinia } from 'pinia' // 使用createPinia函数创建一个pinia实例并注册 app.use(createPinia())5. Layout레이아웃을 구성하기 전에 html, body 등의 일부 태그에 대한 스타일 설정도 다음과 같이 초기화해야 합니다 프로젝트의 index.html 파일 아래에 스타일 설정을 추가합니다.
// 从pinia中引入defineStore函数来定义store import { defineStore } from "pinia"; // 定义一个store并取名为useStore // defineStore第一个参数是应用程序中store的唯一标识,也就是在定义其他store时该标识不能相同 // 此处可以类比为java中的实体类,useStore就是类名,state里的属性是成员属性,getters里的函数是getter方法,actions里的函数是setter方法 export const useStore = defineStore("useStore", { // 定义state // 推荐使用 完整类型推断的箭头函数 state: () => { return { // 所有这些属性都将自动推断其类型 count: 0, name: "Eduardo", isAdmin: true, }; }, // 定义getters,里面定义一些对state值的取值操作 // 指向箭头函数定义的时候所处的对象,而不是其所使用的时候所处的对象,默认指向父级的this // 普通函数中的this指向它的调用者,如果没有调用者则默认指向window getters: { doubleCount: (state) => state.count * 2, doubleCountOne(state) { return state.count * 2; }, doublePlusOne(): number { return this.count * 2 + 1; }, }, // 定义actions,里面定义一些对state的赋值操作 actions: { setCounter(count:number){ this.count = count } } }); // 1、只有一个参数的时候,参数可以不加小括号,没有参数或2个及以上参数的,必须加上小括号 // 2、返回语句只有一条的时候可以不写{}和return,会自动加上return的,返回多条语句时必须加上{}和return // 3、箭头函数在返回对象的时候必须在对象外面加上小括号 // 在vue中定义函数时,我们尽量都指明函数返回值类型以及参数的数据类型
<template> <!-- 测试element-plus --> <el-button type="primary">Primary</el-button> <!-- 测试element-plus图标 --> <div > <Edit /> <Share /> <Delete /> <Search /> </div> <h3>方式一、直接通过store.count++</h3> <!-- 测试pinia --> <h4>直接从store取值并测试pinia:{{ count }}</h4> <el-button type="primary" @click="addCount">增加</el-button> <h4>使用storeToRefs函数解析store后测试pinia:{{ count1 }}</h4> <el-button type="primary" @click="addCount1">增加</el-button> <h3>方式二、通过调用store中的函数</h3> <h4>通过store中的函数并测试pinia:{{ count1 }}</h4> <el-button type="primary" @click="addCount2">增加</el-button> </template> <script setup lang="ts"> import { useStore } from "@/store/index"; import { storeToRefs } from "pinia"; // 解析store中的数据,如成员属性、方法 // 创建了一个useStore实例对象 const store = useStore(); // 增加成员属性count的值,方式一、直接通过store.count++ // 拿到成员属性count,但这样取值会失去响应性,也就是不能实时同步,当我们点击增加按钮后,虽然操作已经完成,count也增加了,但展示有延迟 // 这个取值过程可能涉及解析数据,从而导致函数执行完后数据没有变化 const count = store.count; const addCount = () => { store.count++; }; // 通过pinia中的storeToRefs函数将store中的数据都进行解析 const count1 = storeToRefs(store).count; const addCount1 = () => { store.count++; }; // 方式二、通过调用store中的函数 const addCount2 = () => { store.setCounter(++store.count) }; </script> <style scoped> .read-the-docs { color: #888; } </style>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" rel="external nofollow" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite + Vue + TS</title> </head> <body> <!-- 此处为程序的最终入口,会引入App.vue 并将相应的配置挂载到id为app <div id="app"></div> 上 --> <div id="app"></div> <script type="module" src="/src/main.ts"></script> </body> </html> <!-- 这里对html、body、挂载容器div做样式的初始化设置,去除原有的设置 --> <style lang="less"> html,body,#app { padding: 0px; margin: 0px; height: 100%; box-sizing: border-box; } #app { width: 100%; max-width: 100%; } </style>
<template> <el-container class="container"> <!-- layout布局左侧菜单区 --> <el-aside width="200px" class="aside"> <!-- 菜单项,通过组件的形式引入 --> <Menu></Menu> </el-aside> <!-- layout布局内容区 --> <el-container> <!-- 内容区头部 --> <el-header class="header"> <!-- 头部组件,抽离成组件形式 --> <Header></Header> </el-header> <!-- 内容区的主体,用于数据展示 --> <el-main class="content">Main</el-main> </el-container> </el-container> </template> <script setup lang="ts"> // vue3中组件引入后不需要使用conponents注册,可以直接使用 import Header from '@/layout/header/Header.vue' import Menu from '@/layout/menu/Menu.vue' </script> <style scoped lang="less"> .container { height: 100%; .aside { background-color: antiquewhite; } .header { background-color: aquamarine; } .content { background-color: pink } } </style>6. 메뉴바 로고먼저 준비한 로고 이미지를 src 폴더 아래의 에셋에 넣어주세요 , 레이아웃 메뉴의 로고 폴더 아래에 새 MenuLogo.vue 파일을 생성하고 다음과 같이 구성합니다.
<template> <el-menu default-active="2" class="el-menu-vertical-demo" :unique-opened='uniqueOpenedFlag' > <!-- 在为el-menu设置unique-opened属性时必须要确保el-sub-menu、el-menu-item中index的唯一性,如果index不唯一则不生效 --> <!-- 本组件作为父组件向子组件传递数据menuList,子组件需要定义menuList属性以确保可以接受该数据 --> <menu-item :menuList="menuList"></menu-item> </el-menu> </template> <script setup lang="ts"> import { ref, reactive } from "vue"; import MenuItem from "@/layout/menu/item/MenuItem.vue"; // 自定义的假的树形菜单数据 // reactive函数用来处理响应式数据,处理的数据一般是复杂类型数据,如对象类型 // ref函数也可以处理响应式数据,不过数据一般是基本数据类型 const isCollapse = ref(false) const uniqueOpenedFlag = ref(true) const menuList = reactive([ { path: "/system", name: "system", component: "Layout", meta: { title: "系统管理", icon: "Setting", roles: ["sys:manage"], }, children: [ { path: "/worker", name: "worker", component: "Layout", meta: { title: "员工管理", icon: "Setting", roles: ["sys:manage"], }, }, { path: "/happy", name: "happy", component: "Layout", meta: { title: "菜单管理", icon: "Setting", roles: ["sys:manage"], }, }, ], }, { path: "/mail", name: "mail", component: "Layout", meta: { title: "商场管理", icon: "Setting", roles: ["sys:manage"], }, children: [ { path: "/worker11", name: "worker11", component: "Layout", meta: { title: "员工管理22", icon: "Setting", roles: ["sys:manage"], }, }, { path: "/happy22", name: "happy22", component: "Layout", meta: { title: "菜单管理22", icon: "Setting", roles: ["sys:manage"], }, }, ], }, ]); </script> <style lang="less" scoped></style>마지막으로 메뉴 로고 구성 요소를 메뉴 표시줄 구성 요소에 도입하고
<template> <template v-for="item in menuList" :key="item.path"> <!-- 判断该菜单项是否有子菜单 --> <el-sub-menu v-if="item.children && item.children.length > 0" :index="item.path" > <template #title> <el-icon> <!-- 通过动态组件展示图标,因为图标数据一般是通过后端查数据库拿到的 --> <component :is="item.meta.icon"></component> </el-icon> <span>{{ item.meta.title }}</span> </template> <!-- 递归调用,将子菜单传递给组件处理 --> <menu-item :menuList="item.children"></menu-item> </el-sub-menu> <el-menu-item v-else :index="item.path"> <el-icon> <!-- 通过动态组件展示图标 --> <component :is="item.meta.icon"></component> </el-icon> <span>{{ item.meta.title }}</span> </el-menu-item> </template> </template> <script setup lang="ts"> import { Document, Menu as IconMenu, Location, Setting, } from "@element-plus/icons-vue"; // 子组件接受父组件传递的数据 // 本组件为子组件,接受父组件传过来的数据,此处定义menuList属性,接受父组件传递的menuList数据 defineProps(["menuList"]); </script> <style lang="less" scoped></style>를 사용하면 효과는 다음과 같습니다. :
src에 있는 라우터의 index.ts 파일 아래에 다음 라우팅 구성을 추가하고 views 폴더에 해당 파일을 생성합니다
<template> <div class="logo"> <img :src="Logo" / alt="vue3을 사용하여 백엔드 시스템을 구축하는 방법" > <span class="logo-title">{{ title }}</span> </div> </template> <script setup lang="ts"> import { ref } from "vue"; import Logo from "@/assets/logo.png"; const title = ref("博客管理系统"); </script> <style lang="less" scoped> .logo { display: flex; // 弹性布局 width: 100%; height: 60px; line-height: 60px; background-color: rgb(234, 255, 127); text-align: center; cursor: pointer; // 鼠标悬浮在元素上时,鼠标从箭头变成小手 align-items: center; img { width: 36px; height: 36px; margin-left: 20px; // 元素的外边距 margin-right: 12px; } .logo-title { font-weight: 800; // 800为加粗 color: black; font-size: 20px; line-height: 60px; // 元素上下居中 font-family: FangSong; // 字体类型 } } </style>라우팅 구성 추가 후 생성 현재 경로와 해당 페이지가 생성 및 연결되어 있지만 경로가 참조되지 않아 라우팅 페이지의 데이터가 올바른 위치에 표시될 수 없습니다. 따라서 레이아웃의 주요 영역인 데이터 표시 영역은 특정 경로에 액세스할 때 해당 경로 페이지가 이 영역에 표시될 수 있도록 보장해야 합니다.
메뉴 항목 구성 요소에서는 경로의 경로 값을 메뉴 항목의 인덱스 속성에 바인딩하는 것이 목적입니다. element-plus에서 제공하는 내비게이션 메뉴 활성화 시(메뉴 항목을 클릭하면 해당 메뉴 항목이 활성화됨) 해당 인덱스가 라우팅 점프 경로로 사용되므로 이 기능을 사용하려면, 또한 이 기능을 활성화하려면 메뉴 표시줄 구성 요소에 el을 추가해야 하며, 현재 활성화된 메뉴를 나타내려면 default-active 속성을 추가해야 합니다. 사용 사례는 다음과 같습니다
// 在script标签中引入 import MenuLogo from "@/layout/menu/logo/MenuLogo.vue"; // el-menu标签上方引入使用 <menu-logo></menu-logo>
위 내용은 vue3을 사용하여 백엔드 시스템을 구축하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!