从零构建带AI流式对话的Vue2全栈应用-CSDN博客本文是对这个链接阶段二的讲解
一、阶段二解决什么问题
阶段一只是学习 Vue 的基础语法。阶段二开始制作真正的后台管理页面。
要完成的结构是:
后台页面 ├─ 左侧菜单 │ ├─ 仪表盘 │ └─ 用户管理 ├─ 顶部导航栏 └─ 中间页面 ├─ DashboardView.vue └─ UserManagementView.vue在这个阶段主要接触:
Element UI Vue 组件 父子组件通信 Vue Router 嵌套路由 计算属性 computed 事件 methods 响应式布局二、main.js为什么要引入 Element UI
文件:
src/main.js核心代码:
import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import App from './App.vue' import router from './router' import store from './store' Vue.config.productionTip = false Vue.use(ElementUI) new Vue({ router, store, render: h => h(App) }).$mount('#app')逐段解释。
1. 导入 Vue
import Vue from 'vue'意思是:
从已经安装的
vue软件包中取出 Vue。
后面的页面、组件、路由、Vuex 都要依赖 Vue 才能运行。
2. 导入 Element UI
import ElementUI from 'element-ui'Element UI 是一个已经写好的界面组件库。
没有 Element UI 时,按钮需要自己写:
<button>提交</button>并且需要自己设计样式。
使用 Element UI 后,可以写:
<el-button type="primary"> 提交 </el-button>它会自动带有蓝色按钮样式、悬停效果和点击效果。
3. 导入 Element UI 样式
import 'element-ui/lib/theme-chalk/index.css'Element UI 分成两部分:
JavaScript:按钮、表格等组件的功能 CSS:按钮、表格等组件的外观只导入ElementUI,没有导入 CSS,组件可能能运行,但是没有正常样式。
4. 全局注册 Element UI
Vue.use(ElementUI)它表示:
把 Element UI 中的组件安装到整个 Vue 项目中。
之后任何.vue文件都能直接使用:
<el-button /> <el-table /> <el-card /> <el-menu /> <el-dialog />不需要每个文件单独导入。
5. 创建 Vue 根实例
new Vue({ router, store, render: h => h(App) }).$mount('#app')可以把它理解为:
创建整个 Vue 应用 ├─ 加载路由 router ├─ 加载全局数据 store ├─ 显示 App.vue └─ 把应用放到网页中的 #app 元素其中:
render: h => h(App)表示把App.vue作为整个项目最外层的组件。
三、App.vue为什么只有router-view
文件:
src/App.vue核心代码:
<template> <div id="app"> <router-view /> </div> </template>router-view可以理解成一个“页面占位框”。
浏览器访问:
/#/dashboard这里显示仪表盘。
访问:
/#/users这里显示用户管理页面。
所以:
<router-view />本身没有固定内容,它显示哪个组件,由路由决定。
四、侧边栏组件SidebarMenu.vue
文件:
src/components/SidebarMenu.vue核心结构:
<template> <el-menu :default-active="$route.path" :collapse="collapse" router > <el-menu-item index="/dashboard"> <i class="el-icon-s-home"></i> <span slot="title">仪表盘</span> </el-menu-item> <el-menu-item index="/users"> <i class="el-icon-user"></i> <span slot="title">用户管理</span> </el-menu-item> </el-menu> </template>1.el-menu是什么
<el-menu>是整个菜单容器。
里面可以放多个:
<el-menu-item>每一个el-menu-item是一个菜单选项。
2.router属性
<el-menu router>开启菜单的路由模式。
例如:
<el-menu-item index="/dashboard">点击后,相当于:
this.$router.push('/dashboard')浏览器地址会变成:
http://localhost:8081/#/dashboard3.default-active
:default-active="$route.path"前面的冒号:
:是:
v-bind:的缩写。
完整写法是:
v-bind:default-active="$route.path"$route.path是当前页面路径。
访问仪表盘时
$route.path === '/dashboard'所以仪表盘菜单会高亮。
访问用户管理时:
$route.path === '/users'所以用户管理会高亮。
4.collapse是父组件传来的数据
:collapse="collapse"在脚本中接收:
props: { collapse: { type: Boolean, default: false } }props是父组件向子组件传递数据的方式。
父组件中:
<SidebarMenu :collapse="isCollapse" />父组件把isCollapse传给子组件。
子组件使用名字collapse接收。
数据流是:
AdminLayout.vue isCollapse ↓ props SidebarMenu.vue collapse5. 为什么不能在子组件直接修改 props
在 Vue 中,props应该由父组件控制。
错误思路:
this.collapse = true子组件直接修改父组件传来的值,Vue 会给出警告。
正确思路:
父组件保存状态 子组件只负责显示这是“单向数据流”。
五、后台布局AdminLayout.vue
AdminLayout.vue是阶段二最重要的文件。
它负责组织:
左侧菜单 顶部导航栏 页面内容 手机端抽屉核心结构:
<el-container> <el-aside> 左侧菜单 </el-aside> <el-container> <el-header> 顶部导航栏 </el-header> <el-main> <router-view /> </el-main> </el-container> </el-container>1. Element UI 布局容器
<el-container>表示布局容器。
<el-aside>表示侧边栏。
<el-header>表示顶部。
<el-main>表示主体。
结构关系:
el-container ├─ el-aside └─ el-container ├─ el-header └─ el-main2.data()中保存会变化的数据
data() { return { isCollapse: false, mobileDrawerVisible: false } }data()返回的数据是响应式数据。
也就是说,当数据变化时,页面会自动更新。
isCollapse
isCollapse: false表示侧边栏是否折叠。
false:展开 true:折叠按钮点击后:
this.isCollapse = !this.isCollapse假设原来是:
false取反后变成:
true再次点击又变成:
falsemobileDrawerVisible
mobileDrawerVisible: false控制手机端抽屉是否出现。
false:抽屉关闭 true:抽屉打开模板中:
<el-drawer :visible.sync="mobileDrawerVisible" >.sync表示抽屉打开或关闭时,Element UI 可以同步修改这个数据。
3.computed计算属性
computed: { asideWidth() { return this.isCollapse ? '64px' : '220px' } }computed用于根据现有数据计算新结果。
这里根据isCollapse计算侧边栏宽度。
三元表达式:
条件 ? 条件成立结果 : 条件不成立结果所以:
this.isCollapse ? '64px' : '220px'等价于:
if (this.isCollapse) { return '64px' } else { return '220px' }4. 为什么使用 computed,而不直接写在模板中
也可以写成:
<el-aside :width="isCollapse ? '64px' : '220px'" >但是模板会越来越复杂。
使用计算属性:
<el-aside :width="asideWidth">更清楚。
计算逻辑集中放在脚本中,页面结构放在模板中。
5. 当前页面标题
currentPageTitle() { return this.$route.meta.title || '未命名页面' }路由中写:
meta: { title: '仪表盘' }当前访问仪表盘时:
this.$route.meta.title得到:
仪表盘然后显示在顶部面包屑中:
{{ currentPageTitle }}{{ }}是 Vue 的文本插值语法。
6.methods方法
methods: { toggleCollapse() { this.isCollapse = !this.isCollapse } }方法通常由点击、输入等事件触发。
模板中:
<el-button @click="toggleCollapse">@click是:
v-on:click的缩写。
完整写法:
<el-button v-on:click="toggleCollapse">表示按钮点击后执行toggleCollapse()。
六、嵌套路由为什么重要
路由结构:
{ path: '/', component: AdminLayout, redirect: '/dashboard', children: [ { path: 'dashboard', component: DashboardView }, { path: 'users', component: UserManagementView } ] }这里的关键是:
children表示子路由。
访问:
/dashboardVue 先加载:
AdminLayout.vue然后把:
DashboardView.vue显示到AdminLayout.vue的:
<router-view />里面。
所以页面切换时:
左侧菜单不消失 顶部栏不消失 只有中间内容变化这就是后台系统常用的嵌套路由。
七、仪表盘中的栅格布局
代码:
<el-row :gutter="20"> <el-col :xs="24" :sm="12" :lg="8" > <el-card> 内容 </el-card> </el-col> </el-row>Element UI 把一行分成 24 份。
24:占整行 12:占半行 8:占三分之一行所以:
:xs="24"手机端占整行。
:sm="12"较小屏幕占一半,一行两个。
:lg="8"大屏幕占三分之一,一行三个。
这就是响应式布局。
八、阶段二数据流总结
浏览器访问 /dashboard ↓ Vue Router 找到路由 ↓ 加载 AdminLayout.vue ↓ AdminLayout 内加载 SidebarMenu.vue ↓ DashboardView.vue 显示在内部 router-view阶段二完成后,你应该理解:
组件是什么 父子组件如何传值 路由如何切换页面 布局组件如何组合 响应式数据变化为什么能更新页面