vue3+ts+element-plus
1.element-plus中form表单的ref不能跟ts定义的一个变量名一致,不然导致input无法输入2. element-plus的rulestrigger的blur和change一起写方式改变了3. 监听watch方式修改
·
1.element-plus中form表单的ref不能跟ts定义的一个变量名一致,不然导致input无法输入
2. element-plus的rules trigger的blur和change一起写方式改变了
3. 监听watch方式修改
4.缓存处理
5.路由跳转
6.组件工程化
components/index.ts
const requireComponent = require.context('./', true, /\.vue$/)
const components:any = []
requireComponent.keys().map(file => {
components.push(requireComponent(file).default)
})
const install = function (Vue:any) {
components.map((component:any) => {
Vue.component(component.name, component)
})
}
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
const CSUI = {
install,
...components
}
export default CSUI
因为会报window错误,所以要在shims-vue.d.ts里添加如下代码
declare interface Window {
Vue: any
}
main.ts
import CSUI from '@/components/index.ts'
createApp(App).use(store).use(router).use(elementPlus, { locale }).use(CSUI).mount('#app')
7.父子组件通讯
父传子
子传父
8.接口代理,实现调用接口
request/index.ts
import axios from 'axios'
const service = axios.create({
baseURL: '/api',
timeout: 10000
})
service.interceptors.request.use(function(config:any):any {
config.headers.Authorization = `Bearer 05f894b3-144f-48ea-bcc5-328ae49d7bf8`
return config
})
service.interceptors.response.use(function(res:any):any {
return res.data
})
export default service
api/index.ts
export * from './role/index'
api/role/index.ts
import http from '@/request/index'
export function getCode(params:any = {}) {
return http.get('/code', { params })
}
代理
module.exports = {
devServer: {
host: '127.0.0.1',
port: 80,
proxy: {
'^/api': {
target: '',
secure: true,
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
9.table组件的封装
父组件
<template>
<table-list
@getInit="getInit"
@detail="detail"
@edit="edit"
@deleted="deleted"
></table-list>
</template>
<script>
import { roleList } from '@/api/index'
import { defineComponent, provide, reactive, ref, onMounted } from 'vue'
import { ElMessageBox, ElMessage } from 'element-plus'
export default defineComponent({
setup(prop, context) {
let data = {
tableData: ref([]),
column: [
{ label: '角色编号', prop: 'roleId', width: 150},
{ label: '角色名称', prop: 'roleName'},
{ label: '权限字符', prop: 'roleKey', width: 200},
{ label: '创建时间', prop: 'createTime', width: 200},
],
loading: ref(true),
tableBtn: [
{ text: '详情', method: 'detail' },
{ text: '编辑', method: 'edit', type: 'primary' },
{ text: '删除', method: 'deleted', type: 'danger' }
],
conditionData: [
{ input_type: 'input', key: 'roleName', placeholder: '输入角色名称', label: '角色名称' },
{ input_type: 'input', key: 'roleKey', placeholder: '输入权限字符', label: '权限字符' },
{ input_type: 'datetimerange', key: 'create_time', label: '创建时间' }
],
totalList: ref(0),
filterData: ref({
roleName: '',
roleKey: '',
create_time: '',
pageNum: 1,
pageSize: 10
})
}
const methods = {
getInit() {
methods.roleList()
},
roleList() {
roleList({
...data.filterData.value
}).then(res => {
data.tableData.value = res.rows
data.loading.value = false
data.totalList.value = res.total
})
},
detail(row) {
console.log(row)
},
edit(row) {
console.log(row)
},
deleted(row) {
ElMessageBox.confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(res => {
ElMessage.success({
message: '删除成功'
})
}).catch(res => {
})
},
}
provide('data', data)
methods.roleList()
return {
...methods
}
}
})
</script>
<style lang="scss" scoped>
</style>
TableList组件
<template>
<el-form ref="form" :model="form" label-width="80px" v-if="conditionData" :inline="true">
<el-form-item :label="item.label" v-for="(item, index) in conditionData" :key="index">
<el-input v-model="filterData[item.key]" :placeholder="item.placeholder" clearable v-if="item.input_type == 'input'" :style="{'width': (item.width || '200')+'px'}"></el-input>
<el-select v-model="filterData[item.key]" :placeholder="item.placeholder" v-if="item.input_type == 'select'" style="margin: 0 20px">
<el-option
v-for="item in item.options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
<el-date-picker
v-model="filterData[item.key]"
:type="item.type"
:placeholder="item.placeholder"
v-if="item.input_type == 'time'"
>
</el-date-picker>
<el-date-picker
v-model="filterData[item.key]"
v-if="item.input_type == 'datetimerange'"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-button type="primary" style="margin-left: 20px" @click="search">搜索</el-button>
<el-button @click="reset">重置</el-button>
</el-form>
<el-table
class="el-table"
:data="tableData"
border
v-loading="loading"
style="width: 100%"
:header-cell-style="{background:'#f4f6fa'}"
>
<el-table-column
type="index"
label="序号"
width="50"
align="center">
</el-table-column>
<el-table-column
v-for="(item, index) in column"
:key="index"
:prop="item.prop"
:label="item.label"
:width="item.width"
v-bind="{align: 'center'}">
</el-table-column>
<el-table-column
fixed="right"
label="操作"
v-bind="{align: 'center'}"
width="300"
>
<template #default="scope">
<el-button @click="handleClick(item.method, scope.row)" :type="item.type || ''" size="mini" v-for="(item, index) in tableBtn" :key="index">{{item.text}}</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage4"
:page-sizes="[10, 20, 30, 40]"
:page-size="10"
layout="total, sizes, prev, pager, next, jumper"
background
:total="totalList"
v-if="tableData.length">
</el-pagination>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, inject } from "vue";
export default defineComponent({
name: 'table-list',
setup(prop,context) {
let data:any = inject('data')
const form = data.filterData.value
let { filterData } = data
const methods = {
// 搜索
search() {
context.emit('getInit')
},
// 重置
reset() {
for(let v in filterData.value) {
filterData.value[v] = ''
}
context.emit('getInit')
},
// 表格页数据量
handleSizeChange(pageSize:number) {
filterData.value.pageSize = pageSize
context.emit('getInit')
},
// 表格页数
handleCurrentChange(pageNum:number) {
filterData.value.pageNum = pageNum
context.emit('getInit')
},
// 点击表格操作
handleClick(method:string ,row:object) {
context.emit(method, row)
}
}
return {
...data,
form,
...methods
}
}
})
</script>
<style lang="scss" scoped>
.el-table{
margin-top: 20px;
}
.pagination{
display: flex;
justify-content: center;
align-items: center;
margin-top: 40px;
}
</style>
10.引入图表echarts,后续改为组件
main.ts
import * as echarts from 'echarts'
const app = createApp(App)
app.config.globalProperties.$echarts = echarts
home.vue
<template>
<echart-init></echart-init>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
})
</script>
echatInit.vue
<template>
<div :id="echartId" style="width: 100%; height: 100%"></div>
</template>
<script>
import { defineComponent, ref, getCurrentInstance, onMounted } from 'vue'
import { uniqueId } from 'lodash'
export default defineComponent({
name: 'echart-init',
setup(prop,context) {
const echartId = ref(uniqueId('echartsId_'))
const { ctx } = getCurrentInstance();
const methods = {
draw(options) {
options = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}]
}
ctx.$nextTick(() => {
const myChart = ctx.$echarts.init(document.getElementById(echartId.value))
myChart.setOption(options)
})
}
}
onMounted(() => {
methods.draw()
})
return {
echartId
}
}
})
</script>
<style lang="scss" scoped>
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)