【项目-Ruoyi】Day2--前端知识串讲


Day2–前端知识串讲

写在前面

Vue3

简介

常见指令

  • **指令:**指的是HTML标签上带有v- 前缀的特殊属性

    不同指令具有不同含义,可以实现不同的功能

Vue的常见指令

生命周期

  • Vue的生命周期

    指的是vue对象从创建到销毁的过程

  • Vue的生命周期包含8个阶段

    每触发一个生命周期事件,会自动执行一个生命周期方法

    这些生命周期方法也被称为钩子方法

Vue的生命周期

  • 重点关注:mounted其他的了解

  • mounted:挂载完成,Vue初始化成功,HTML页面渲染成功。一般用于页面初始化自动的ajax请求后台数据

Vue脚手架

  • Vue脚手架(Vue CLI)是Vue.js官方提供的一个命令行工具,它可以帮助开发者快速搭建Vue.js项目的初始结构

项目创建

1
npm create vue@3.4.0

创建一个工程化的Vue项目

项目创建初始化选择

  • 创建步骤详细说明↓↓↓

  • Project name:------------------》项目名称,默认值:vue-project,可输入想要的项目名称

  • Add TypeScript? ----------------》是否加入TypeScript组件?默认值:No

  • Add JSX Support? --------------》是否加入JSX支持?默认值:No

  • Add Vue Router...--------------》是否为单页应用程序开发添加Vue Router路由管理组件?默认值:No

  • Add Pinia ...----------------------》是否添加Pinia组件来进行状态管理?默认值:No

  • Add Vitest ...---------------------》是否添加Vitest来进行单元测试?默认值:No

  • Add an End-to-End ...-----------》是否添加端到端测试?默认值No

  • Add ESLint for code quality? —》是否添加ESLint来进行代码质量检查?默认值:No

  • 项目创建完成后,进入vue-demo1项目目录,执行命令安装当前项目的依赖

1
npm install

项目结构

Vue项目结构

Vue项目开发流程

Vue项目开发流程

  • 其中*.vueVue项目中的组件文件,在Vue项目中也称为单文件组件SFC,Single-File Components)
  • Vue 的单文件组件会将一个组件的逻辑 (JS),模板 (HTML) 和样式 (CSS) 封装在同一个文件里(*.vue

Vue的单文件组件

API风格

Vue2

  • 在 Vue 2 中,组件的逻辑主要通过一个选项式(Options API)的方式组织
  • 这意味着组件的属性、方法、生命周期钩子等都被定义在一个对象的不同属性中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script>
export default{
data() {
return {
count: 0 // 模型变量
}
},
methods: {
increment: function(){
this.count++
}
},
mounted() {
console.log('Vue选项式 mounted.....');
}
}
</script>

<template>
<div>
<input type="button" @click="increment" value="Api Demo1 Count : "> {{ count }}
</div>
</template>

<style>

</style>

Vue3

  • Vue 3引入了组合式 API(Composition API),这是一种新的编写组件逻辑的方式,它允许开发者更灵活地组织代码
  • 组合式 API 通过 setup 函数为核心,提供了 refreactivecomputedwatch 等响应式 API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script setup>
import { ref, onMounted } from 'vue';
const count = ref(0); //声明响应式变量

function increment(){ //声明函数
count.value++;
}

onMounted(() => { //声明钩子函数
console.log('Vue组合式 Mounted....');
})
</script>

<template>
<div>
<input type="button" @click="increment" value="Api Demo1 Count : ">{{ count }}
</div>
</template>

<style scoped>

</style>

选项式API的弊端

  • Options类型API,数据、方法、计算属性等,是分散在:datamethodscomputed
  • 若想新增或者修改一个需求,就需要分别修改:datamethodscomputed,不便于维护和复用

选项式API1

选项式API2

组合式API的优势

  • 用函数的方式,更加优雅的组织代码,让相关功能的代码更加有序的组织在一起

组合式API

几个常用API

  • reactive:能将对象类型变为【响应式】,对简单类型无效(例如 string,number,boolean)
  • ref:接收简单类型或者对象类型的数据传入并返回一个响应式的对象
1
2
3
4
5
6
7
8
9
10
11
12
13
reactive与ref二者对比:

1. 都是用来生成响应式数据


2. 不同点
a. reactive不能处理简单类型的数据
b. ref参数类型支持更好,但是必须通过.value做访问修改
c. ref函数内部的实现依赖于reactive函数


3. 在实际工作中的推荐
a. 推荐使用ref函数,减少记忆负担

VueRouter

介绍

  • 官网:https://router.vuejs.org/zh/

  • Vue RouterVue的官方路由

    Vue提供富有表现力、可配置的、方便的路由

  • Vue中的路由路径组件 的对应关系

  • 打开一个网站,点击左侧菜单,地址栏的地址发生变化

  • 地址栏地址一旦发生变化,在主区域显示对应的页面组件

VueRouter的组成部分

VueRouter的组成部分

  • VueRouter:路由器类,根据路由请求在路由视图中动态渲染选中的组件
  • <router-link>:请求链接组件,浏览器会解析成<a>
  • <router-view>:动态视图组件,用来渲染展示与路由路径对应的组件

核心配置

  • src/router/index.js 中定义路由表信息,在其中主要是定义请求路径与组件之间的对应关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 router
  • 在浏览器中访问/ —>则会跳转到views/HomeView.vue组件中,这是一个文件目录位置
  • 在浏览器中访问 /about —>则会跳转到views/AboutView.vue组件中,这是一个文件目录位置
  • 其中真正的页面渲染,需要使用到router提供的<RouterView></RouterView>标签

访问的流程图

Pinia

介绍

  • PiniaVue 的专属状态管理库,它允许你跨组件或页面共享状态。 也就意味着可以使用 Pinia 来存储数据,而这些数据是可以**跨组件/页面来访问**的

Pinia官网

  • Store是保存状态和业务逻辑的实体、承载着全局状态

    像一个永远存在的组件,每个组件都可以读取数据、存入数据

Store1

Store2

使用Pinia

  • 在需要获取Pinia数据的视图组件中引入即可
1
2
3
4
import {useCounterStore} from '@/stores/counter.js';

useCounterStore().increment();
console.log(useCounterStore().doubleCount);

Element Plus

介绍

  • Element:是饿了么公司前端开发团队提供的一套基于 Vue3 的网站组件库,用于快速构建网页
  • Element提供了很多组件(组成网页的部件)供我们使用。例如 超链接、按钮、图片、表格等等
  • 官方网站:https://element-plus.org/zh-CN/#/zh-CN

Element Plus

  • 作为一个后台开发者,只需要学会如何从 ElementPlus 的官网拷贝组件到我们自己的页面中,并且做一些修改即可

快速入门

准备工作

  1. 安装ElementPlus的组件库(在当前工程的目录下)
1
npm install element-plus@2.4.3 --save
  1. main.js 中引入ElementPlus组件库 (参照官方文档)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'
import './assets/main.css'

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(ElementPlus)

app.mount('#app')

制作组件

  1. 访问ElementPlus的官方文档,查看对应的组件源代码

ElementPlus官方文档

  1. srcviews 目录下,创建Element.vue组件文件,复制组件代码,调整成自己想要的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script setup>

</script>

<template>
<el-row class="mb-4">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</el-row>
</template>

<style scoped>

</style>
  1. 配置组件路由,在src/router/index.js文件中添加对Element.vue组件的路由映射
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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')
},
{
path: '/element',
name: 'element',
component: () => import('../views/Element.vue')
}
]
})

export default router
  1. 在根组件 app.vue 中设置路由地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<header>
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />

<div class="wrapper">
<HelloWorld msg="You did it!" />

<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
<RouterLink to="/element">Element</RouterLink>
</nav>
</div>
</header>

<RouterView />
</template>
  1. 启动项目,访问 http://localhost:5173

启动Vue3项目

常见组件

表格组件

  • 用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作

表格组件

  • 在ElementPlus的组件库中找到表格组件

在ElementPlus的组件库中找到表格组件

  • Element.vue 组件中继续制作表格

    组件包括了3个部分

    如果官方有除了<template>部分之外的<style><script>都需要复制

代码cv

  • 插入表格组件整体代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<script setup>
const tableData = [
{date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'},
{date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'},
{date: '2016-05-04', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'},
{date: '2016-05-01', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'}
]
</script>

<template>

<!-- Button按钮 -->
<el-row class="mb-4">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</el-row>

<br>

<!-- Table表格 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
</template>

<style scoped>

</style>
1
2
3
4
5
Table表格组件,属性说明:
- data: 主要定义table组件的数据模型
- prop: 定义列的数据应该绑定data中定义的具体的数据模型
- label: 定义列的标题
- width: 定义列的宽度

分页条组件

  • Pagination: 分页组件,主要提供分页工具条相关功能

分页条组件效果图

  • 默认情况下,ElementPlus的组件是英文的,如果希望使用中文语言,可以在 main.js 中做如下配置
1
2
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
app.use(ElementPlus, {locale: zhCn})
  • 整个Element.vue的内容(分页条组件)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<script setup>
import { ref } from 'vue'

const tableData = [
{date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'},
{date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'},
{date: '2016-05-04', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'},
{date: '2016-05-01', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'}
]

const currentPage4 = ref(4)
const pageSize4 = ref(100)

const handleSizeChange = (val) => {
console.log(`${val} items per page`)
}
const handleCurrentChange = (val) => {
console.log(`current page: ${val}`)
}
</script>

<template>

<!-- Button按钮 -->
<el-row class="mb-4">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</el-row>

<br>

<!-- Table表格 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>

<br>

<el-pagination
v-model:current-page="currentPage4"
v-model:page-size="pageSize4"
:page-sizes="[100, 200, 300, 400]"
layout="total, sizes, prev, pager, next, jumper"
:total="400"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</template>

<style scoped>

</style>
  • Pagination分页组件的属性:
    • background: 添加背景颜色
    • layout: 分页工具条的布局,其具体值包含sizes, prev, pager, next, jumper, total 这些值
    • total: 数据的总数量

Pagination分页组件属性对应效果图

  • 还有两个重要事件需要学习:
    • size-changepageSize改变时会触发
    • current-changecurrentPage改变时会触发

对话框组件

  • 在保留当前页面状态的情况下,告知用户并承载相关操作

对话框组件效果图

Dialect组件页

  • 复制如下代码到组件文件 Element.vue<template></template> 模块中
1
2
3
4
5
6
7
8
9
10
11
<el-button @click="dialogTableVisible = true">
打开对话框
</el-button>

<el-dialog v-model="dialogTableVisible" title="Shipping address">
<el-table :data="tableData">
<el-table-column property="date" label="Date" width="150" />
<el-table-column property="name" label="Name" width="200" />
<el-table-column property="address" label="Address" />
</el-table>
</el-dialog>
  • 然后复制如下代码到组件文件 Element.vue<script></script> 模块中
1
const dialogTableVisible = ref(false)
1
Dialog对话框组件使用的关键点,就是控制其显示与隐藏。 通过 v-model 给定的boolean值,来控制Dialog的显示与隐藏。

表单组件

  • Form表单

    由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据

表单组件

  • 复制代码到组件文件 Element.vue<template></template> 模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- Form 表单 -->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="Approved by">
<el-input v-model="formInline.user" placeholder="Approved by" clearable />
</el-form-item>

<el-form-item label="Activity zone">
<el-select v-model="formInline.region" placeholder="Activity zone" clearable>
<el-option label="Zone one" value="shanghai" />
<el-option label="Zone two" value="beijing" />
</el-select>
</el-form-item>

<el-form-item label="Activity time">
<el-date-picker v-model="formInline.date" type="date" placeholder="Pick a date" clearable/>
</el-form-item>

<el-form-item>
<el-button type="primary" @click="onSubmit">Query</el-button>
</el-form-item>
</el-form>
  • 复制如下代码到组件文件 Element.vue<script></script> 模块
1
2
3
4
5
6
7
8
9
10
// Form表单
const formInline = ref({
user: '',
region: '',
date: '',
})

const onSubmit = () => {
console.log('submit!')
}

最后完成的组件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<script setup>
import { ref } from 'vue'

const tableData = [
{date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'},
{date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'},
{date: '2016-05-04', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'},
{date: '2016-05-01', name: 'Tom', address: 'No. 189, Grove St, Los Angeles'}
]

const currentPage4 = ref(4)
const pageSize4 = ref(100)

const handleSizeChange = (val) => {
console.log(`${val} items per page`)
}
const handleCurrentChange = (val) => {
console.log(`current page: ${val}`)
}

// Dialog对话框
const dialogTableVisible = ref(false)

// Form表单
const formInline = ref({
user: '',
region: '',
date: '',
})

const onSubmit = () => {
console.log('submit!')
}
</script>

<template>

<!-- Button按钮 -->
<el-row class="mb-4">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</el-row>

<br>

<!-- Table表格 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>

<br>

<el-pagination
v-model:current-page="currentPage4"
v-model:page-size="pageSize4"
:page-sizes="[100, 200, 300, 400]"
layout="total, sizes, prev, pager, next, jumper"
:total="400"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>

<br>

<el-button @click="dialogTableVisible = true">
打开对话框
</el-button>

<el-dialog v-model="dialogTableVisible" title="Shipping address">
<el-table :data="tableData">
<el-table-column property="date" label="Date" width="150" />
<el-table-column property="name" label="Name" width="200" />
<el-table-column property="address" label="Address" />
</el-table>
</el-dialog>

<br><br>

<!-- Form 表单 -->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="Approved by">
<el-input v-model="formInline.user" placeholder="Approved by" clearable />
</el-form-item>

<el-form-item label="Activity zone">
<el-select v-model="formInline.region" placeholder="Activity zone" clearable>
<el-option label="Zone one" value="shanghai" />
<el-option label="Zone two" value="beijing" />
</el-select>
</el-form-item>

<el-form-item label="Activity time">
<el-date-picker v-model="formInline.date" type="date" placeholder="Pick a date" clearable/>
</el-form-item>

<el-form-item>
<el-button type="primary" @click="onSubmit">Query</el-button>
</el-form-item>
</el-form>

</template>

<style scoped>

</style>
  • Copyrights © 2024-2025 brocademaple
  • 访问人数: | 浏览次数:

      请我喝杯咖啡吧~

      支付宝
      微信