Skip to content

Element-Plus

安装

bash
pnpm i element-plus @element-plus/locale @element-plus/icons-vue

挂载

  • main.js
js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import locale from '@element-plus/locale/lang/zh-cn'

// webpack解决方案,vite无需配置
const debounce = (fn, delay) => {
    let timer = null;
    return function () {
        let context = this;
        let args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function () {
            fn.apply(context, args);
        }, delay);
    }
}

const _ResizeObserver = window.ResizeObserver;
window.ResizeObserver = class ResizeObserver extends _ResizeObserver{
    constructor(callback) {
        callback = debounce(callback, 16);
        super(callback);
    }
}

let app = createApp(App)
    .use(store)
    .use(router)
    .use(ElementPlus, {locale});

for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component)
}

app.mount('#app');

组件

vue
<template>
  <el-menu
      :default-active="activeIndex2"
      :ellipsis="false"
      mode="horizontal"
      background-color="#545c64"
      text-color="#fff"
      active-text-color="#ffd04b"
      @select="handleSelect">
    <el-menu-item index="1">Processing Center</el-menu-item>
    <div class="flex-grow"></div>
    <el-sub-menu index="2">
      <template #title>Workspace</template>
      <el-menu-item index="2-1">item one</el-menu-item>
      <el-menu-item index="2-2">item two</el-menu-item>
      <el-menu-item index="2-3">item three</el-menu-item>
      <el-sub-menu index="2-4">
        <template #title>item four</template>
        <el-menu-item index="2-4-1">item one</el-menu-item>
        <el-menu-item index="2-4-2">item two</el-menu-item>
        <el-menu-item index="2-4-3">item three</el-menu-item>
      </el-sub-menu>
    </el-sub-menu>
    <el-menu-item index="3" disabled>Info</el-menu-item>
    <el-menu-item index="4">Orders</el-menu-item>
  </el-menu>

  <el-row class="tac">
    <el-col :span="6">
      <el-menu
          active-text-color="#ffd04b"
          background-color="#545c64"
          text-color="#fff"
          :router="true">
        <el-menu-item index="/button">
          <span>button</span>
        </el-menu-item>
        <el-menu-item index="/icon">
          <span>icon</span>
        </el-menu-item>
        <el-menu-item index="/form">
          <span>form</span>
        </el-menu-item>
        <el-menu-item index="/table">
          <span>table</span>
        </el-menu-item>
      </el-menu>
    </el-col>
    <el-col :span="18">
      <router-view></router-view>
    </el-col>
  </el-row>
</template>

<script>
export default {
  data() {
    return {
      activeIndex2: '4'
    }
  },
  methods: {
    handleSelect(key, keyPath) {
      console.log(key, keyPath);
    },
    handleOpen(key, keyPath) {
      console.log(key, keyPath);
    },
    handleClose(key, keyPath) {
      console.log(key, keyPath);
    }
  }
}
</script>

<style>
.flex-grow {
  flex-grow: 1;
}
</style>
vue
<template>
  <el-breadcrumb separator-icon="DArrowRight">
    <el-breadcrumb-item to="/">homepage</el-breadcrumb-item>
    <el-breadcrumb-item>promotion management</el-breadcrumb-item>
    <el-breadcrumb-item>promotion list</el-breadcrumb-item>
    <el-breadcrumb-item>promotion detail</el-breadcrumb-item>
  </el-breadcrumb>
</template>

Page Header 页头

vue
<template>
  <el-page-header>
    <template #breadcrumb>
      <el-breadcrumb separator-icon="DArrowRight">
        <el-breadcrumb-item to="/">homepage</el-breadcrumb-item>
        <el-breadcrumb-item>promotion management</el-breadcrumb-item>
        <el-breadcrumb-item>promotion list</el-breadcrumb-item>
        <el-breadcrumb-item>promotion detail</el-breadcrumb-item>
      </el-breadcrumb>
    </template>
    <template #content>
      <el-tag size="large">面包屑下边,返回按钮右边</el-tag>
    </template>
    <template #extra>
      <el-tag size="large">面包屑下边,返回按钮的最右边</el-tag>
    </template>
    <el-descriptions>
      <template #title>描述列表标题</template>
    </el-descriptions>
  </el-page-header>
</template>

Basic基础组件

Button按钮

vue
<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>

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

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

  <el-row>
    <el-button icon="Search" circle/>
    <el-button type="primary" icon="Edit" circle/>
    <el-button type="success" icon="Check" circle/>
    <el-button type="info" icon="Message" circle/>
    <el-button type="warning" icon="Star" circle/>
    <el-button type="danger" icon="Delete" circle/>
  </el-row>
</template>

Icon图标

vue
<template>
  <el-button><el-icon><Plus /></el-icon></el-button>
  <el-icon><Minus /></el-icon>
  <el-icon><CirclePlus /></el-icon>
  <el-icon><Search /></el-icon>
  <el-icon><Female /></el-icon>
  <el-icon><Male /></el-icon>
  <el-icon><Aim /></el-icon>
</template>

表单组件

vue
<template>
  <el-form :model="form" label-width="120px">
    <el-form-item label="Activity name">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="Activity zone">
      <el-select v-model="form.region" placeholder="please select your zone">
        <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-col :span="11">
        <el-date-picker
            v-model="form.date1"
            type="date"
            placeholder="Pick a date"
            style="width: 100%"
        />
      </el-col>
      <el-col :span="2" class="text-center">
        <span class="text-gray-500">-</span>
      </el-col>
      <el-col :span="11">
        <el-time-picker
            v-model="form.date2"
            placeholder="Pick a time"
            style="width: 100%"
        />
      </el-col>
    </el-form-item>
    <el-form-item label="Instant delivery">
      <el-switch v-model="form.delivery" />
    </el-form-item>
    <el-form-item label="Activity type">
      <el-checkbox-group v-model="form.type">
        <el-checkbox label="Online activities" name="type" />
        <el-checkbox label="Promotion activities" name="type" />
        <el-checkbox label="Offline activities" name="type" />
        <el-checkbox label="Simple brand exposure" name="type" />
      </el-checkbox-group>
    </el-form-item>
    <el-form-item label="Resources">
      <el-radio-group v-model="form.resource">
        <el-radio label="Sponsor" />
        <el-radio label="Venue" />
      </el-radio-group>
    </el-form-item>
    <el-form-item label="Activity form">
      <el-input v-model="form.desc" type="textarea" />
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="onSubmit">Create</el-button>
      <el-button>Cancel</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
export default {
  data() {
    return {
      form: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: '',
      }
    }
  },
  methods: {
    onSubmit() {
      console.log("submit...");
    }
  }
}
</script>

Data数据展示

Table表格

vue
<template>
  <el-table :data="diseases" style="width: 100%" ref="table">
    <el-table-column type="selection"/>
    <el-table-column prop="code" label="疾病编码"/>
    <el-table-column prop="name" label="疾病名称"/>
    <el-table-column prop="icdCode" label="国际ICD编码" />
    <el-table-column prop="type" label="疾病类型" />
    <el-table-column>
      <template #header>
        <el-button type="primary" link @click="multiDelete">删除</el-button>
        <el-button type="primary" link>增加</el-button>
      </template>
      <template #default="scope">
        <el-button type="danger" @click="handleDelete(scope.$index, scope.row)">
          删除
        </el-button>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      diseases: [
        {
          code: 1,
          name: '肠毒性大肠埃希氏菌肠炎',
          icdCode: "A04.101",
          type: '肠炎'
        },
        {
          code: 2,
          name: '新生儿肠毒性大肠埃希氏菌肠炎',
          icdCode: "A04.102",
          type: '肠炎'
        },
        {
          code: 3,
          name: '肠毒性大肠埃希氏菌感染',
          icdCode: "A04.151",
          type: '肠炎'
        },
        {
          code: 4,
          name: '侵袭性大肠埃希氏菌肠炎',
          icdCode: "A04.201",
          type: '肠炎'
        },
      ]
    }
  },
  methods: {
    handleDelete(index, row) {
      this.diseases.splice(index, 1);
    },
    multiDelete() {
      this.diseases = this.diseases.filter(item =>
          !this.$refs.table.getSelectionRows().includes(item)
      )
    }
  }
}
</script>

Descriptions 描述列表

vue
<template>
  <el-descriptions
      title="基本信息"
      border>
    <el-descriptions-item>
      <template #label>病历号</template>
      <span>100015</span>
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>姓名</template>
      <span>请输入姓名</span>
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>性别</template>
      <span>男</span>
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>年龄</template>
      <span>20岁</span>
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>出生日期</template>
      <span>2000-01-01</span>
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>身份证号</template>
      <span>210282200001010010</span>
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>家庭住址</template>
      <span>辽宁省大连市旅顺口区博川路</span>
    </el-descriptions-item>
  </el-descriptions>
</template>

Pagination 分页

vue
<template>
  <el-pagination
      :page-size="20"
      :pager-count="11"
      layout="prev, pager, next, jumper, total"
      :total="999"
      background/>
</template>

注意

将图片放置到public/img目录

vue
<template>
    <el-carousel indicator-position="outside">
      <el-carousel-item>
        <img src="/img/1.jpg">
      </el-carousel-item>
      <el-carousel-item>
        <img src="/img/2.jpg">
      </el-carousel-item>
      <el-carousel-item>
        <img src="/img/3.jpg">
      </el-carousel-item>
    </el-carousel>
</template>

Feedback 反馈组件

Dialog 对话框

vue
<template>
  <el-button @click="popDialog">点击弹出对话框</el-button>
  <el-dialog
      v-model="dialogVisible"
      title="标题内容">
    <span>插槽内容...</span>

    <template #footer>
      <el-button @click="ok">确定</el-button>
      <el-button @click="cancel">取消</el-button>
    </template>
  </el-dialog>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false
    }
  },
  methods: {
    popDialog() {
      this.dialogVisible = true;
    },
    ok() {
      this.dialogVisible = false;
    },
    cancel() {
      this.dialogVisible = false;
    }
  }
}
</script>

Message 消息提示

vue
<template>
  <el-button type="success" @click="handleSuccess">success</el-button>
  <el-button type="danger" @click="handleError">error</el-button>
</template>

<script>
import {ElMessage} from "element-plus";

export default {
  methods: {
    handleSuccess() {
      ElMessage({
        showClose: true,
        message: 'Congrats, this is a success message.',
        type: 'success',
      })
    },
    handleError() {
      ElMessage({
        showClose: true,
        message: 'Oops, this is a error message.',
        type: 'error',
      })
    }
  }
}
</script>

MessageBox 消息弹框

vue
<template>
  <el-button @click="popAlert">弹出alert</el-button>
  <el-button @click="popConfirm">弹出confirm</el-button>
</template>

<script>
import {ElMessageBox, ElMessage} from "element-plus";

export default {
  methods: {
    popAlert() {
      ElMessageBox.alert(
          "弹窗内容...",
          "弹窗标题...",{
            showClose: false
          }
      )
          .then(() => ElMessage.success("success"))
          .catch(() => ElMessage.warning("cancel"));
    },
    popConfirm() {
      ElMessageBox.confirm(
          "弹窗内容",
          "弹窗标题",
          {
            confirmButtonText: 'OK',
            cancelButtonText: 'Cancel',
            type: 'warning',
          }
      )
          .then(() => ElMessage.success("success"))
          .catch(() => ElMessage.warning("cancel"));
    }
  }
}
</script>

附录

添加typescript支持

  1. 执行命令
bash
vue add typescript
  1. 交互
bash
# 是否继续执行
- Still proceed? (y/N) 
  y

# 是否使用类型
- Use class-style component syntax? (Y/n)
  n

# 是否使用babel整合typescript、polyfills、jsx...
- Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n)
  n

# 是否将目前的所有js代码转换为ts代码
- Convert all .js files to .ts? (Y/n)
  n

# 是否允许js参与编译
- Allow .js files to be compiled? (y/N)
  y

# 是否要使用typescript的特性对代码进行检查
# typescript可以直接编写js代码,但如果勾了这一条的话,会强制必须按照typescript的语法编写代码
- Skip type checking of all declaration files (recommended for apps)? (Y/n) 
  n

解决 ResizeObserver loop 问题

https://github.com/element-plus/element-plus/discussions/5658

https://blog.csdn.net/sd19871122/article/details/86493069

注意

实测结果: 错误是由 webpack引起的,出现在webpack-dev-server的overlay.js文件中。

解决方案1

无需任何配置,使用将webpack替换为vite即可解决【推荐】

  1. 需要手动添加vue-router
  2. 需要手动添加pinia【vuex平替】

解决方案2

在main.js添加如下配置亦可解决,但页面响应速度会拖慢

https://blog.csdn.net/qq_45112637/article/details/131740110