Vue生态中包含了大量优秀的组件库,经过快速的学习,我们就能把这些现成的组件应用到自己的项目中了
UI组件库需要基于JS框架来实现,也就是说我们现在学习的是Vue3,也需要选择适配的组件库,在Vue生态中,最为流行的PC端组件库要数饿了么团队开发的element系列,Vue2版本对应Element-Ui,Vue3版本对应Element-Plus,我们当前要学习的便是Element-Plus,只要掌握了一个组件库的使用,其他组件库的使用基本上大同小异,大家无需担心。常见的UI组件库介绍如下:
上面这4个UI组件库对应了两大主流JS框架(Vue React)的PC端和移动端,我们当前的课程重点学习Element-Plus。
通过命令将Element-Plus安装到项目中:
- npm install element-plus --save
-
- vue2
- npm i element-ui
确认正确安装完毕:
虽然已经安装了依赖,但是要在项目中使用还需要引入,组件库一般都提供了全局引入和按需引入2种方法,全局引入更加方便,一次引入后可以在项目的任何位置使用,但是全局引入会让项目的体积变大,对于性能而言不是那么友好。
- /main.js
- import { createApp } from 'vue'
- import ElementPlus from 'element-plus'
- import 'element-plus/dist/index.css' //记得引入样式文件
- import App from './App.vue'
-
- const app = createApp(App)
-
- app.use(ElementPlus) //通过use方法来注册插件
- app.mount('#app')
引入完成之后,便可以在项目中使用Element-Plus提供的任意组件了。
如果你只是希望使用Element-Plus的一小部分组件,按需引入往往是更好的方式,没有使用到的组件最终并不会被打包。但需要安装一个插件unplugin-element-plus来自动导入样式。
- //App.vue
- <template>
- <el-button>I am ElButton</el-button>
- </template>
- <script>
- import { ElButton } from 'element-plus'
- export default {
- components: { ElButton },
- }
- </script>
- // vite.config.js
- import { defineConfig } from 'vite'
- import ElementPlusPlugin from 'unplugin-element-plus/vite'
-
- export default defineConfig({
- // ...
- plugins: [ElementPlusPlugin()],
- })
插件的作用是可以自动引入组件对应的样式:
- import { ElButton } from 'element-plus'
- // ↓ ↓ ↓ ↓ ↓ ↓
- import { ElButton } from 'element-plus'
- import 'element-plus/es/components/button/style/css'
准备完毕后,我们尝试在项目中引入一些组件!进入官网后点选到组件页面,我们可以看到非常多的常用组件:
以最常见的button按钮为例,我们一起体验下组件库提供的按钮的强大之处:
在官方文档中我们确认使用组件前可以直接看到最终的显示效果:
按钮组件中提供了各种形状和颜色的按钮,如果匹配到了你的业务需求,可以找到对应的代码移植到你的项目中(比如我要选中那个success的圆角按钮)
- /App.vue
- <template>
- <el-button type="success" round>Success</el-button>
- </template>
启动项目后在浏览器中便能看到对应的按钮组件了,是不是非常方便?
现在我们再来进一步学习一些常见的组件
搭建页面的整体结构往往是布局的第一步,Element-Plus提供了快速布局的相关组件,我们选用其中的一个添加到我们的项目中:
我们对3个区域都做一些修改:
Header区域给上一个背景色,修改一下文本描述,在组件库中修改元素样式需要通过浏览器调试工具找到对应元素的类名,比如头部
- <template>
- <div class="common-layout">
- <el-container>
- <el-header>Element-Plus常用组件</el-header>
- <el-container>
- <el-aside width="200px">Aside</el-aside>
- <el-main>main</el-main>
- </el-container>
- </el-container>
- </div>
- </template>
-
- <script setup></script>
-
- <style scoped>
- .el-header{
- background-color: skyblue;
- text-align: center;
- line-height: 60px;
- }
- </style>
Aside区域引入一个菜单列表,用于展示不同的组件,显然这里的菜单列表也会是一个单独的组件,马上就会来介绍。
Main区域用于展示不同的组件,这里显然需要页面的切换,那可以将之前学习的路由引入,菜单组件完成后我们就立刻加入路由!
找到菜单组件,侧栏是符合我们需求的样式,提供了2种颜色风格,任选一种即可,找到对应的代码引入到我们的项目中。我们这里不需要二级菜单,所以在引入对应代码的时候可以去掉二级菜单部分。
- /Aside.vue
- <template>
- <el-row class="tac">
- <el-col :span="24">
- <h5 class="mb-4">常见组件</h5>
- <el-menu
- default-active="1"
- class="el-menu-vertical-demo"
- >
- <el-menu-item index="1">
- <el-icon><icon-menu /></el-icon>
- <span>Navigator One</span>
- </el-menu-item>
- <el-menu-item index="2" disabled>
- <el-icon><document /></el-icon>
- <span>Navigator Two</span>
- </el-menu-item>
- <el-menu-item index="3">
- <el-icon><setting /></el-icon>
- <span>Navigator Three</span>
- </el-menu-item>
- </el-menu>
- </el-col>
- </el-row>
- </template>
-
- <script setup>
- import {
- Document,
- Menu as IconMenu,
- Setting,
- } from '@element-plus/icons-vue'
-
- </script>
Menu组件上有一些特定的API,查阅文档最下方的说明,这需要多多使用才能熟练,我们现在项目的页面应该是这样的:
main区域用来展示不同的具体组件,菜单区域修改一下文本,这里涉及到页面跳转,所以需要将路由引入到项目中。
需要注意的是,menu组件有一个router属性需要手动开启。
在项目中配置好路由和对应组件后,我们的项目页面已经实现了路由跳转功能:
我们可以把刚才已经学习过的Button,Menu组件都放到我们项目中对应的位置。
我们刚才已经搭建好了Form的路由,现在找到Element-Plus中Form组件,然后将它引入到我们的项目中,Form组件是一个比较复杂的组件,里面又包含了大量其他的基本组件,同样在文档下方提供了API的具体用法,我们现在做一个基本了解,后面通过逐步的实际使用来加深理解记忆。
修改组件库内部组件样式,必须使用样式穿透语法
- ::v-deep .el-input__inner { /* 样式穿透 */
- background-color: pink;
- }
Element-Plus中还提供了大量的常用组件,基于这些提供的组件我们还需要根据实际业务需求进行二次封装,要熟练使用它们需要经过大量的实际项目练习
之前的Pinia购物车太丑了!我们使用Element-Plus给它美化一下吧!在项目中快速安装和引入Element-Plus。
同样的,我们也引入路由,让商品列表和购物车作为2个单独的页面显示。
- router/index
- import { createRouter, createWebHistory } from 'vue-router'
- import ProductionList from '../components/ProductionList.vue'
- import ShoppingCart from '../components/ShoppingCart.vue'
- const router = createRouter({
- history: createWebHistory(),
- routes: [
- {
- path: '',
- },
- {
- path: '/list',
- name: 'list',
- component: ProductionList,
- },
- {
- path: '/cart',
- name: 'cart',
- component: ShoppingCart,
- },
- ],
- })
- export default router
在首页中,可以引入2个Button组件设置2个路由页面的跳转,那么引入Element-Plus中的button组件吧!
- <template>
- <h1>Pinia-购物车</h1>
- <div class="btn">
- <router-link to="/list" style="margin-right: 10px"
- ><el-button type="primary" round>商品列表</el-button></router-link
- >
- <router-link to="/cart"
- ><el-button type="primary" round>购物车</el-button></router-link
- >
- </div>
- <router-view></router-view>
- </template>
-
- <script setup></script>
-
- <style scoped>
- h1 {
- text-align: center;
- }
- a {
- text-decoration: none;
- }
- .btn{
- text-align: center;
- }
- </style>
现在我们的页面通过点击按钮实现正确的跳转了。
现在进入商品列表页来做一些美化,列表展示我们一般会联想到表格,去到Element-Plus表格组件中找到一个你喜欢的风格,然后引入它,就选择这个吧,当然你需要对每列的内容做一些调整,第三列中我们需要加入按钮,记得给按钮绑定对应的事件(具体事件参考文档说明 这里我们使用cell-click事件)。
- <template>
- <el-table :data="store1.lists" stripe style="width: 100%">
- <el-table-column prop="title" label="商品名称" width="500" align="center" />
- <el-table-column prop="price" label="商品价格" width="500" align="center" />
- <el-table-column width="500" align="center">
- <template #default="scope">
- <el-button @click.prevent="store2.addProduct(scope.row)">加入购物车</el-button>
- </template>
- </el-table-column>
- </el-table>
- </template>
-
- <script setup>
- import { useProductStore } from '../store/product.js'
- import { useShopCartStore } from '../store/shopCart'
- const store1 = useProductStore()
- store1.getProductLists()
- const store2 = useShopCartStore()
- </script>
-
- <style></style>
修改完毕后,商品列表页面好看了许多,按钮功能也能正常实现!
但体验还是不够好,点选加入购物车的时候,最好能给一些提示,例如“添加成功”这样的消息提示,Element-Plus同样提供了这样的组件,这里我们选用Message 消息提示组件。
- <template>
- <el-table :data="store1.lists" stripe style="width: 100%">
- <el-table-column prop="title" label="商品名称" width="500" align="center" />
- <el-table-column prop="price" label="商品价格" width="500" align="center" />
- <el-table-column width="500" align="center">
- <template #default="scope">
- <el-button @click.prevent="add(scope)">加入购物车</el-button>
- </template>
- </el-table-column>
- </el-table>
- </template>
-
- <script setup>
- import { ElMessage } from 'element-plus'
- import { useProductStore } from '../store/product.js'
- import { useShopCartStore } from '../store/shopCart'
- const store1 = useProductStore()
- store1.getProductLists()
- const store2 = useShopCartStore()
- const add = (scope) => {
- ElMessage({
- message: '成功添加至购物车',
- type: 'success',
- onClose: () => {
- store2.addProduct(scope.row) //提示消息关闭后 添加商品到购物车
- },
- })
- }
- </script>
好了,现在我们的商品列表页是不是看起来美观了许多?
购物车中仍然是列表展示,所以可以继续使用表格组件。
然后优化一下 底部总价和结算按钮的布局,点击结算按钮时,给一个确认框的提示,这里可以用到Element-Plus中Message Box消息弹出框和刚才用过的Message 消息提示组件。
vue
- <template>
- <div class="cart">
- <p v-show="!store.lists.length">
- <i>请添加一些商品到购物车</i>
- </p>
- <el-table
- :data="store.lists"
- stripe
- style="width: 100%"
- v-show="store.lists.length > 0"
- >
- <el-table-column
- prop="title"
- label="商品名称"
- width="500"
- align="center"
- />
- <el-table-column
- prop="price"
- label="商品价格"
- width="500"
- align="center"
- />
- <el-table-column
- prop="number"
- label="商品数量"
- width="500"
- align="center"
- />
- </el-table>
- <div class="bot">
- <p>商品总价:{{ store.sum }}</p>
- <p>
- <el-button @click="getResult" :disabled="!store.lists.length"
- >结算</el-button
- >
- </p>
- </div>
- </div>
- </template>
-
- <script setup>
- import { ElMessageBox, ElMessage } from 'element-plus'
- import { useShopCartStore } from '../store/shopCart'
- const store = useShopCartStore()
- const getResult = () => {
- ElMessageBox.confirm('确认要结算购物车吗?', {
- confirmButtonText: '确认',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- ElMessage({
- type: 'success',
- message: '正在结算中',
- onClose: async () => {
- await store.getResult()
- if (store.result === '成功') {
- ElMessage({
- type: 'success',
- message: '结算成功',
- })
- } else {
- ElMessage({
- type: 'error',
- message: '结算失败',
- })
- }
- },
- })
- })
- .catch(() => {
- ElMessage({
- type: 'info',
- message: '退出结算',
- })
- })
- }
- </script>
-
- <style scoped>
- .bot {
- display: flex;
- justify-content: space-between;
- padding: 0 15%;
- }
- </style>
经过进一步优化,购物车组件的交互和展示效果也完成了,结算按钮增加了消息提示更加符合用户习惯。
经过我们的优化,现在的购物车案例已经看起来非常不错了,各种样式和交互效果都给加上了,这就是组件库给我们带来的便捷之处。
Menu组件上有一些特定的API,查阅文档最下方的说明;
main区域用来展示不同的具体组件,菜单区域修改一下文本,这里涉及到页面跳转,所以需要将路由引入到项目中。需要注意的是,menu组件有一个router属性需要手动开启。
Element-Plus中还提供了大量的常用组件,基于这些提供的组件我们还需要根据实际业务需求进行二次封装,封装要求参考官方文档;
找到组件的类名:再浏览器中审查元素,查找类名
在 vue 文件中,为了防止组件间样式相互影响,我们给 style 标签添加了样式隔离 scoped 属性,但有时后我们需要对组件库内部组件的样式进行二次修改,因此必须使用样式穿透语法来实现;
:: v-deep .组件的样式类名

(1)vue2 中给一个组件绑定事件,组件会同意默认绑定的都是自定义事件,需要给事件添加修饰符 native,才会当作原生事件;

(2)vue3 中给组件绑定事件:vue3 对应组件会检视这个事件的名称,如果名称是一个原生事件,那么会将其作为一个原生事件处理,否则视为自定义事件


(1)通过添加事件:然后编程式导航
(2)用
- <router-link to="/list" style="margin-right: 10px">
- <el-button type="primary" round>商品列表</el-button>
- </router-link>