一、element-plus
1.用组件属性实现跳转路由

javascript
<el-menu
active-text-color="#ffd04b"
background-color="#232323"
:default-active="$route.path" //高亮
text-color="#fff"
router>
<el-menu-item index="/article/channel">
<el-icon>
<Management />
</el-icon>
<span>文章分类</span>
</el-menu-item>
2. el-card 组件

javascript
<template>
<el-card class="page-container">
<template #header>
<div class="header">
<span>文章分类</span>
<div class="extra">
<el-button type="primary">添加分类</el-button>
</div>
</div>
</template>
...
</el-card>
</template>
<style lang="scss" scoped>
.page-container {
min-height: 100%;
box-sizing: border-box;
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
}
</style>
考虑到多个页面复用,封装成组件
-
props 定制标题
-
默认插槽 default 定制内容主体
-
具名插槽 extra 定制头部右侧额外的按钮
-
<slot>
javascript
<script setup>
defineProps({
title: {
required: true,
type: String
}
})
</script>
<template>
<el-card class="page-container">
<template #header>
<div class="header">
<span>{{ title }}</span>
<div class="extra">
<slot name="extra"></slot>
</div>
</div>
</template>
<slot></slot>
</el-card>
</template>
页面内使用
javascript
<template>
<page-container title="文章分类">
<template #extra>
<el-button type="primary"> 添加分类 </el-button>
</template>
主体部分
</page-container>
</template>
3.el-表格(重要)
第一步先调通借口返回数据

第二步封装组件


详情看官网
javascript
<el-table :data="channelList" style="width: 100%">
<el-table-column label="序号" width="100" type="index"> </el-table-column>
<el-table-column label="分类名称" prop="cate_name"></el-table-column>
<el-table-column label="分类别名" prop="cate_alias"></el-table-column>
<el-table-column label="操作" width="100">
<template #default="{ row }">
<el-button
:icon="Edit"
circle
plain
type="primary"
@click="onEditChannel(row)"
></el-button>
<el-button
:icon="Delete"
circle
plain
type="danger"
@click="onDelChannel(row)"
></el-button>
</template>
</el-table-column>
<template #empty>
<el-empty description="没有数据" />
</template>
</el-table>
const onEditChannel = (row) => {
console.log(row)
}
const onDelChannel = (row) => {
console.log(row)
}

4.封装弹层
javascript
<script setup>
import { ref } from 'vue'
const dialogVisible = ref(false)
const open = async (row) => {
dialogVisible.value = true
console.log(row)
}
defineExpose({
open
})
</script>
<template>
<el-dialog v-model="dialogVisible" title="添加弹层" width="30%">
<div>我是内容部分</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary"> 确认 </el-button>
</span>
</template>
</el-dialog>
</template>


二、封装公共组件,下拉菜单
1.新建 article/components/ChannelSelect.vue
javascript
<template>
<el-select>
<el-option label="新闻" value="新闻"></el-option>
<el-option label="体育" value="体育"></el-option>
</el-select>
</template>
2.页面中导入渲染
javascript
import ChannelSelect from './components/ChannelSelect.vue'
<el-form-item label="文章分类:">
<channel-select></channel-select>
</el-form-item>
3.调用接口,动态渲染下拉分类,设计成 v-model 的使用方式
javascript
<script setup>
import { artGetChannelsService } from '@/api/article'
import { ref } from 'vue'
defineProps({//子组件接收
modelValue: {
type: [Number, String]
}
})
const emit = defineEmits(['update:modelValue'])//提交父组件方法
const channelList = ref([])//定义数组动态渲染
const getChannelList = async () => {
const res = await artGetChannelsService()
channelList.value = res.data.data
}
getChannelList()
</script>
<template>
<el-select//拆解方法
:modelValue="modelValue"
@update:modelValue="emit('update:modelValue', $event)"
>
<el-option//动态渲染
v-for="channel in channelList"
:key="channel.id"
:label="channel.cate_name"
:value="channel.id"
></el-option>
</el-select>
</template>
注意:这里一定要使用大驼峰命名,不然会报错
4.父组件定义参数绑定
javascript
const params = ref({//父组件定义数据
pagenum: 1,
pagesize: 5,
cate_id: '',
state: ''
})
<channel-select v-model="params.cate_id"></channel-select>//拆分开就是子组件的updata方法
vue2和Vue3v-model
区别
在Vue 2和Vue 3中,v-model
的使用和行为大体上是相似的,都是用来创建表单输入和应用状态之间的双向数据绑定。不过,随着Vue 3的推出,有一些细微的差别和改进:
Vue 2 中的 v-model
- 基于对象属性 :Vue 2 使用
v-model
实现双向绑定时,实际上是在使用value
属性和input
事件的一个语法糖。 - 组件实现 :自定义组件需要定义
value
属性和input
事件来配合v-model
的工作。 model
选项 :在Vue 2的自定义组件中,可以使用model
选项来指定一个自定义的事件,而不是默认的input
事件。
Vue 3 中的 v-model
- 基于
createModel
函数 :Vue 3 引入了一个新的createModel
函数,它允许更灵活的双向绑定实现。 - 组件实现改进 :自定义组件可以使用
modelValue
属性和update:modelValue
事件来代替Vue 2中的value
和input
。 - 模板中的变化 :在Vue 3的模板中,应该使用
update:modelValue
来监听更新事件,如上一个警告信息所述,这要求使用全小写并用连字符分隔的事件名。 - 性能优化 :Vue 3中的
v-model
可以利用Vue 3的性能优化,例如通过避免不必要的渲染来提高效率。
共同点
- 在两种版本中,
v-model
都是用于创建用户输入和应用状态之间的同步。 - 它们都允许开发者在模板中以一种简洁的方式处理表单输入和应用状态的绑定。
迁移注意事项
如果你正在从Vue 2迁移到Vue 3,需要注意以下几点:
- 确保在Vue 3中将
v-model
的更新事件监听器更改为使用全小写的连字符命名法,如update:modelValue
。 - 自定义组件可能需要更新以使用新的
modelValue
属性和update:modelValue
事件。 - 利用Vue 3的组合式API(如
ref
,reactive
)来更好地管理响应式状态。
总的来说,v-model
在Vue 2和Vue 3中的核心概念保持不变,但Vue 3对其进行了一些现代化的改进和优化。

三、el-表格(进阶)
1.封装格式化日期工具函数
1.新建 utils/format.js
封装格式化日期函数
javascript
import { dayjs } from 'element-plus'
export const formatTime = (time) => dayjs(time).format('YYYY年MM月DD日')
2.导入使用 import { formatTime } from '@/utils/format'
注意这里要用插槽,
javascript
<el-table-column label="发表时间" prop="pub_date">
<template #default="{ row }">
{{ formatTime(row.pub_date) }}
</template>
</el-table-column>
2.分页渲染 [element-plus 分页]
1.分页组件


javascript
<el-pagination
v-model:current-page="params.pagenum"
v-model:page-size="params.pagesize"
:page-sizes="[2, 3, 4, 5, 10]"
layout="jumper, total, sizes, prev, pager, next"
background
:total="total"
@size-change="onSizeChange"
@current-change="onCurrentChange"
style="margin-top: 20px; justify-content: flex-end"
/>
javascript
const onSizeChange = (size) => {
params.value.pagenum = 1
params.value.pagesize = size
getArticleList()
}
const onCurrentChange = (page) => {
params.value.pagenum = page
getArticleList()
}
2.提供分页修改逻辑

loading效果
