vue3+ts+element-plus

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
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Vue 3和TypeScript(TS)结合使用Element Plus来进行角色菜单分配,是一种很好的选择。下面是一个关于如何实现角色菜单分配的简单示例。 首先,我们需要安装Vue 3、TypeScript和Element Plus。可以使用npm命令进行安装。 ```bash npm install vue@next npm install typescript npm install element-plus ``` 然后,在Vue 3项目的入口文件中,可以引入Element Plus的模块,以及一些额外的样式文件。 ```javascript import { createApp } from 'vue' import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' import App from './App.vue' const app = createApp(App) app.use(ElementPlus) app.mount('#app') ``` 在组件中,我们可以使用Element Plus的Menu组件来展示菜单,并通过V-if指令来根据角色进行菜单项的展示与隐藏。 ```vue <template> <div> <el-menu> <el-menu-item v-if="hasAccess('dashboard')">仪表盘</el-menu-item> <el-menu-item v-if="hasAccess('users')">用户管理</el-menu-item> <el-menu-item v-if="hasAccess('roles')">角色管理</el-menu-item> </el-menu> </div> </template> <script> import { defineComponent } from 'vue' export default defineComponent({ data() { return { userRoles: ['dashboard', 'users', 'roles'] } }, methods: { hasAccess(role) { return this.userRoles.includes(role) } } }) </script> <style> /* 根据需要自定义样式 */ </style> ``` 在该示例中,假设用户角色以数组的形式存储在`userRoles`属性中。通过定义一个`hasAccess`方法,我们可以判断用户是否拥有某个角色,然后根据判断结果,在菜单项上使用V-if指令来展示或隐藏对应的菜单项。 当用户拥有某个角色时,该菜单项将会在界面上显示出来,反之,则不会显示。需要注意的是,需根据实际需求对示例中的角色判断逻辑进行调整。 这只是一个简单的示例,实际的角色菜单分配功能可能涉及到更复杂的逻辑和接口调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值