【Vue】Element-Plus快速入门 && Form && Card && Table && Tree && Dialog && Menu

文章目录

Ⅰ. 基本介绍

一、什么是组件

一个可复用的Vue实例、一段独立的 UI 界面,有自己的 HTML + CSS + JavaScript,代码上体现在一个独立的 .vue 文件。

javascript 复制代码
<script setup></script>
<template></template>
<style lang="scss" scoped></style>

二、什么是ElementPlus组件库

官方文档

ElementPlus 是由饿了么团队开发的。是一个基于 Vue3 开发PC端开源UI组件库,专为开发者提供了一套优雅而灵活的UI组件。它包含了各种常用的Web组件,如按钮、表单、导航等;以及高级组件,如日期选择器、对话框等。ElementPlus 默认语言环境是中文,但可以通过指定 locale 属性来实现其他语言环境,如英文。总之,ElementPlus 提供了丰富的PC组件,有效地降低了开发难度。

组件分类:

  • 基础组件
  • 表单组件
  • 数据展示
  • 导航组件
  • 反馈组件

其他组件

Ⅱ. 快速入门

一、安装

bash 复制代码
npm i element-plus

二、完整引入

javascript 复制代码
// 导入 ElementPlus 组件
import ElementPlus from 'element-plus'
// 导入组件样式
import 'element-plus/dist/index.css'

// 全局注册所有组件
app.use(ElementPlus)

三、测试

Button 组件为例,在 App.vue 中测试:

javascript 复制代码
<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>

Ⅲ. 学习ElementPlus常用组件

一、Form表单组件

https://element-plus.org/zh-CN/component/form.html

1. 介绍

表单包含 输入框单选框下拉选择多选框 等用户输入的组件。使用表单可以收集、验证和提交数据。

2. 基本使用

  • 创建一个表单对象 form,写上需要双向绑定到组件上的字段
  • <el-form> 表单组件中通过 :model 绑定表单对象 form
  • <el-form-item> 中的各个子组件比如 <el-input>通过 v-model 绑定表单对象中要双向绑定的元素 ,比如 form.name
javascript 复制代码
<script setup>
    import { reactive } from 'vue'
    
    // 表单对象
    const form = reactive({
      name: '',
      region: '',
      date1: '',
      date2: '',
      delivery: false,
      type: [],
      resource: '',
      desc: ''
    })
    
    // 提交
    const onSubmit = () => {
      console.log('submit!')
    }
</script>

<template>
  <!--
    model: 表单数据对象
    label-width: 标签的宽度,可使用 auto
    style: 行内样式
  -->
  <el-form
    :model="form"
    label-width="auto"
    style="max-width: 600px">
    
    <!-- label: 标签文本 -->
    <el-form-item label="Activity name">
      <!-- v-model: 双向绑定,收集或设置表单数据 -->
      <el-input v-model="form.name" />
    </el-form-item>
    
    <el-form-item label="Activity zone">
      <!--
        下拉列表
        placeholder: 占位提示文本
      -->
      <el-select
        v-model="form.region"
        placeholder="please select your zone">
        <!--
          选项
          label: 展示的文本
          value: 同步到v-model的值
        -->
        <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">
      <!-- 列 span: 占据的宽度份数,一行分为24份 -->
      <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
          value="Online activities"
          name="type">
          Online activities
        </el-checkbox>
        <el-checkbox
          value="Promotion activities"
          name="type">
          Promotion activities
        </el-checkbox>
        <el-checkbox
          value="Offline activities"
          name="type">
          Offline activities
        </el-checkbox>
        <el-checkbox
          value="Simple brand exposure"
          name="type">
          Simple brand exposure
        </el-checkbox>
      </el-checkbox-group>
    </el-form-item>
    
    <el-form-item label="Resources">
      <!-- 单选框组 -->
      <el-radio-group v-model="form.resource">
        <el-radio value="Sponsor">Sponsor</el-radio>
        <el-radio value="Venue">Venue</el-radio>
      </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>

3. 表单校验

Form 组件允许你验证用户的输入是否符合规范,来帮助找到和纠正错误。

Form 组件提供了表单验证的功能,只需 rules 属性传入约定的验证规则并将 form-item prop 属性设置为需要验证的特殊键值即可

下面是常见的规则属性:

规则属性 类型 说明 示例
required boolean 是否必填 { required: true, message: '请输入用户名' }
min number 字符串最小长度 / 数值最小值 { min: 3, message: '至少3个字符' }
max number 字符串最大长度 / 数值最大值 { max: 10, message: '最多10个字符' }
type string 限制字段类型,可选值:string、number、boolean、method、regexp、integer、float、array、object、enum、date、url、hex、email { type: 'email', message: '请输入合法邮箱' }
pattern RegExp 自定义正则校验 { pattern: /^[1](#规则属性 类型 说明 示例 required boolean 是否必填 { required: true, message: ‘请输入用户名’ } min number 字符串最小长度 / 数值最小值 { min: 3, message: ‘至少3个字符’ } max number 字符串最大长度 / 数值最大值 { max: 10, message: ‘最多10个字符’ } type string 限制字段类型,可选值:string、number、boolean、method、regexp、integer、float、array、object、enum、date、url、hex、email { type: ‘email’, message: ‘请输入合法邮箱’ } pattern RegExp 自定义正则校验 { pattern: /1{6}$/, message: ‘请输入6位数字’ } len number 字符串精确长度 / 数组精确长度 { len: 6, message: ‘必须输入6个字符’ } enum string[] 枚举值范围 { type: ‘enum’, enum: [‘A’, ‘B’], message: ‘只能选择 A 或 B’ } whitespace boolean 是否允许输入空格 { required: true, whitespace: true, message: ‘内容不能为空’ } validator (rule, value, callback) => void
len number 字符串精确长度 / 数组精确长度 { len: 6, message: '必须输入6个字符' }
enum string[] 枚举值范围 { type: 'enum', enum: ['A', 'B'], message: '只能选择 A 或 B' }
whitespace boolean 是否允许输入空格 { required: true, whitespace: true, message: '内容不能为空' }
validator (rule, value, callback) => void | Promise 自定义函数校验,最灵活 { validator: (rule, value) => value === 'admin', message: '必须是 admin' }
trigger string | string[] 触发方式,blur 或 change,也可数组形式 { required: true, trigger: ['blur', 'change'] }
javascript 复制代码
<script setup>
    import { reactive, ref } from 'vue'
    
    const formRef = ref(null)
    
    // 表单对象
    const form = reactive({
      name: '',
      region: '',
      date1: '',
      date2: '',
      delivery: false,
      type: [],
      resource: '',
      desc: ''
    })
    
    // 校验规则
    const rules = {
      name: [
        {
          required: true,
          message: 'Please input Activity name',
          trigger: 'blur'
        },
        { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' }
      ],
      region: [
        {
          required: true,
          message: 'Please select Activity zone',
          trigger: 'change'
        }
      ],
      count: [
        {
          required: true,
          message: 'Please select Activity count',
          trigger: 'change'
        }
      ],
      date1: [
        {
          type: 'date',
          required: true,
          message: 'Please pick a date',
          trigger: 'change'
        }
      ],
      date2: [
        {
          type: 'date',
          required: true,
          message: 'Please pick a time',
          trigger: 'change'
        }
      ],
      location: [
        {
          required: true,
          message: 'Please select a location',
          trigger: 'change'
        }
      ],
      type: [
        {
          type: 'array',
          required: true,
          message: 'Please select at least one activity type',
          trigger: 'change'
        }
      ],
      resource: [
        {
          required: true,
          message: 'Please select activity resource',
          trigger: 'change'
        }
      ],
      desc: [
        { required: true, message: 'Please input activity form', trigger: 'blur' }
      ]
    }
    
    // 提交
    const submitForm = async () => {
      // 对整个表单进行验证。
      formRef.value.validate((valid) => {
        if (valid) {
          console.log('submit!')
        } else {
          console.log('error submit!')
        }
      })
    }
    
    // 重置
    const resetForm = () => {
      // 重置该表单项,将其值重置为初始值,并移除校验结果
      formRef.value.resetFields()
    }
</script>

<template>
  <!--
    rules: 校验规则
    ref: 用来调用 Form 提供的方法
  -->
  <el-form
    style="max-width: 600px"
    :model="form"
    :rules="rules"
    ref="formRef"
    label-width="auto"
    status-icon>
    <!--
      prop: 校验的字段
    -->
    <el-form-item
      label="Activity name"
      prop="name">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item
      label="Activity zone"
      prop="region">
      <el-select
        v-model="form.region"
        placeholder="Activity 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"
      required>
      <el-col :span="11">
        <el-form-item prop="date1">
          <el-date-picker
            v-model="form.date1"
            type="date"
            aria-label="Pick a date"
            placeholder="Pick a date"
            style="width: 100%" />
        </el-form-item>
      </el-col>
      <el-col
        class="text-center"
        :span="2">
        <span class="text-gray-500">-</span>
      </el-col>
      <el-col :span="11">
        <el-form-item prop="date2">
          <el-time-picker
            v-model="form.date2"
            aria-label="Pick a time"
            placeholder="Pick a time"
            style="width: 100%" />
        </el-form-item>
      </el-col>
    </el-form-item>
    <el-form-item
      label="Instant delivery"
      prop="delivery">
      <el-switch v-model="form.delivery" />
    </el-form-item>
    <el-form-item
      label="Activity type"
      prop="type">
      <el-checkbox-group v-model="form.type">
        <el-checkbox
          value="Online activities"
          name="type">
          Online activities
        </el-checkbox>
        <el-checkbox
          value="Promotion activities"
          name="type">
          Promotion activities
        </el-checkbox>
        <el-checkbox
          value="Offline activities"
          name="type">
          Offline activities
        </el-checkbox>
        <el-checkbox
          value="Simple brand exposure"
          name="type">
          Simple brand exposure
        </el-checkbox>
      </el-checkbox-group>
    </el-form-item>
    <el-form-item
      label="Resources"
      prop="resource">
      <el-radio-group v-model="form.resource">
        <el-radio value="Sponsorship">Sponsorship</el-radio>
        <el-radio value="Venue">Venue</el-radio>
      </el-radio-group>
    </el-form-item>
    <el-form-item
      label="Activity form"
      prop="desc">
      <el-input
        v-model="form.desc"
        type="textarea" />
    </el-form-item>
    <el-form-item>
      <el-button
        type="primary"
        @click="submitForm">
        Create
      </el-button>
      <el-button @click="resetForm">Reset</el-button>
    </el-form-item>
  </el-form>
</template>

案例

  • 用户名:必填项、长度3-10个字符、失焦做校验
  • 密码:必填项、长度6-15个字符、失焦做校验
  • 输入框前面带上图标
  • 点击登录时做整体校验
  • 点击取消按钮进行重置
javascript 复制代码
<script setup>
    import { reactive, ref } from 'vue';
    import { ElMessage } from 'element-plus'

    const loginForm = reactive({
        name: '',
        password: '',
    })

    const rules = {
        name: [
            { required: true, message: '请输入用户名', trigger: 'blur' },
            { min: 3, max: 10, message: '长度范围:3-10个字符', trigger: 'blur'}
        ],
        password: [
            { required: true, message: '请输入密码', trigger: 'blur' },
            { min: 6, max: 15, message: '长度范围:6-15个字符', trigger: 'blur'}
        ]
    }

    const loginFormRef = ref(null) // 拿到表单组件的引用

    const onSubmit = () => {
        loginFormRef.value.validate((isValid) => {
            if(isValid === false) {
                return ElMessage.error('请进行合法输入!')
            }
        })
        console.log('ok...进行网络请求...');
    }

    const onReset = () => {
        loginFormRef.value.resetFields()
    }
</script>

<template>
<div class="login">
    <el-form 
        :model="loginForm"
        :rules="rules"
        ref="loginFormRef"
        label-width="auto"
        style="max-width: 300px"
    >
        <el-form-item label="用户名" prop="name">
            <el-input 
                v-model="loginForm.name"
                placeholder="请输入用户名"
                prefix-icon="User"
            />
        </el-form-item>

        <el-form-item label="密码" prop="password">
            <el-input 
                v-model="loginForm.password"
                type="password"
                show-password
                placeholder="请输入密码"
                prefix-icon="Lock"
            />
        </el-form-item>

        <el-form-item>
            <el-button type="primary" @click="onSubmit">提 交</el-button>
            <el-button @click="onReset">重 置</el-button>
        </el-form-item>
    </el-form>
</div>
</template>

<style>
body {
    background: #ddd;
    display: flex;
    justify-content: center;   /* 登录框水平居中 */
    align-items: center;       /* 登录框垂直居中 */
    min-height: 100vh;         /* 撑满屏幕高度 */
    margin: 0;
}

.login {
    width: 350px;
    background: white;
    padding: 20px 10px;
    border-radius: 6px;

    display: flex;
    flex-direction: column;    /* 子元素纵向排列 */
    align-items: center;       /* 子元素水平居中 */
}
</style>

二、Card卡片组件

卡片包含标题,内容以及操作区域。

Card 组件使用 <el-card> 标识,并且由 headerbodyfooter组成。 其中 header footer 是可选的,其内容取决于一个具名的 slot。

javascript 复制代码
<template>
<div>
    <el-card style="max-width: 300px" shadow="hover">
        <template #header>
            <div class="card-header">
                <span>Card name</span>
            </div>
        </template>
        <p v-for="o in 4" :key="o" class="text item">{{ 'List item ' + o }}</p>
        <template #footer>Footer content</template>
    </el-card>
</div>
</template>

三、Table表格组件

1. 介绍

表格组件用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。

2. 基础用法

<el-table> 元素中注入 data 对象数组后,在 <el-table-column> 中用 prop 属性来对应对象中的键名即可填入数据,用 label 属性来定义表格的列名。可以使用 width 属性来定义列宽。

javascript 复制代码
<script setup>
    const tableData = [
      {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles'
      },
      {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles'
      },
      {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles'
      },
      {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles'
      }
    ]
</script>

<template>
  <!--
    data: 数据源
    stripe: 带有斑马纹
    border: 带边框
  -->
  <el-table 
    :data="tableData" 
    style="width: 700px"
    stripe
    border
  >
    <!--
      table-column: 列
      label: 列名
      prop: 渲染的字段名
      width: 列宽
    -->
    <el-table-column prop="date" label="日期" width="180" />
    <el-table-column prop="name" label="名称" width="180" />
    <el-table-column prop="address" label="地址" />
  </el-table>
</template>

3. 自定义列模版

自定义列的显示内容,可组合其他组件使用。

通过作用域插槽 ,可以获取到 row, column, $indexstore(table 内部的状态管理)的数据,从而实现表格内容的自定义渲染。

比如下图需要对 "名称" 以及 "操作" 列表进行自定义,而不只是通过 <el-table-column> 中的 prop 属性直接导入对应的数据,这时候就需要使用作用域插槽!

javascript 复制代码
<template>
<div>
    <el-table 
        :data="tableData" 
        style="width: 100%"
        stripe
        border
    >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="date" label="日期" width="180" />
        <el-table-column label="名称" width="180">
            <template #default="obj">
                <el-tag type="success">{{ obj.row.name }}</el-tag>
            </template>
        </el-table-column>
        <el-table-column prop="address" label="地址" />
        <el-table-column label="操作">
            <template #default>
                <el-icon><Edit /></el-icon>
                <el-icon><Delete /></el-icon>
            </template>
        </el-table-column>
    </el-table>
</div>
</template>

<script setup>
    const tableData = [
    {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles'
    },
    {
        date: '2016-05-02',
        name: 'liren',
        address: 'No. 189, Grove St, Los Angeles'
    },
    {
        date: '2016-05-04',
        name: 'jack',
        address: 'No. 189, Grove St, Los Angeles'
    },
    {
        date: '2016-05-01',
        name: 'Tom2',
        address: 'No. 189, Grove St, Los Angeles'
    }
    ]
</script>

四、Tree树形组件

1. 介绍

用清晰的层级结构展示信息,可展开或折叠。

2. 基础用法

使用 <el-tree> 标签,配合各种属性以及数据源,可以搭建对应的树。

javascript 复制代码
<script setup>
    const handleNodeClick = (data) => {
        console.log(data)
    }

    const data = [
    {
        label: 'Level one 1',
        children: [
            {
                label: 'Level two 1-1',
                children: [
                    {
                        label: 'Level three 1-1-1',
                    },
                ],
            },
        ],
    },
    {
        label: 'Level one 2',
        children: [
            {
                label: 'Level two 2-1',
                children: [
                    {
                        label: 'Level three 2-1-1',
                    },
                ],
            },
            {
                label: 'Level two 2-2',
                children: [
                    {
                        label: 'Level three 2-2-1',
                    },
                ],
            },
        ],
    },
    {
        label: 'Level one 3',
        children: [
            {
                label: 'Level two 3-1',
                children: [
                    {
                        label: 'Level three 3-1-1',
                    },
                ],
            },
            {
                label: 'Level two 3-2',
                children: [
                    {
                        label: 'Level three 3-2-1',
                    },
                ],
            },
        ],
    },
    ]

    const defaultProps = {
        children: 'children',
        label: 'label',
    }
</script>

<template>
    <!--
        style: 样内样式
        data: 数据源
        props: 默认渲染的属性名为 label 和 children
        show-checkbox: 节点是否可被选择
        accordion: 是否每次只打开一个同级树节点展开
        @node-click: 节点点击事件
    -->
    <el-tree
        style="max-width: 600px"
        :data="data"
        :props="defaultProps"
        show-checkbox
        accordion
        @node-click="handleNodeClick"
    />
</template>

3. 自定义节点内容

节点的内容支持自定义,可以在节点区添加按钮或图标等内容。

可以通过 具名插槽 进行树节点内容的自定义:使用 具名插槽 时候会传入两个参数 nodedata,分别表示 当前节点的 Node 对象当前节点的数据

javascript 复制代码
<script setup>
    import {ref} from 'vue'
    const dataSource = ref([
        {
            id: 1,
            label: 'Level one 1',
            children: [
                {
                    id: 4,
                    label: 'Level two 1-1',
                    children: [
                        {
                            id: 9,
                            label: 'Level three 1-1-1',
                        },
                        {
                            id: 10,
                            label: 'Level three 1-1-2',
                        },
                    ],
                },
            ],
        },
        {
            id: 2,
            label: 'Level one 2',
            children: [
                {
                    id: 5,
                    label: 'Level two 2-1',
                },
                {
                    id: 6,
                    label: 'Level two 2-2',
                },
            ],
        },
        {
            id: 3,
            label: 'Level one 3',
            children: [
                {
                    id: 7,
                    label: 'Level two 3-1',
                },
                {
                    id: 8,
                    label: 'Level two 3-2',
                },
            ],
        },
    ])
    
    let id = 1000
    const onAdd = (data) => {
        const newNode = { id: id++, label: 'testtest', children: [] }
        if(!data.children) {
            data.children = []
        }
        data.children.push(newNode)
        // dataSource.value = [...dataSource.value]
    }
    
    const onDel = (node, data) => {
        const parent = node.parent
        const children = parent?.data.children || parent?.data
        const index = children.findIndex((d) => d.id === data.id)
        children.splice(index, 1)
    }
</script>

<template>
    <el-tree 
        style="max-width: 600px" 
        :data="dataSource" 
        node-key="id" 
        show-checkbox 
        default-expand-all
        :expand-on-click-node="false"
    >
        <template #default="{ node, data }">
            <div class="custom-tree-node">
                <span>{{ data.label }}</span>
                <div>
                    <el-button type="primary" text="plain" @click="onAdd(data)">添加</el-button>
                    <el-button type="danger" text="plain" @click="onDel(node, data)">删除</el-button>
                </div>
            </div>
        </template>
    </el-tree>
</template>

<style>
    .custom-tree-node {
        flex: 1;
        width: 500px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding-right: 8px;
    }
</style>

五、Dialog弹框组件

弹框组件在保留当前页面状态的情况下,告知用户并承载相关操作,适合需要定制性更大的场景。

使用说明:

  • 需要设置 v-model 属性,它接收 Boolean,当为 true 时显示 Dialog
  • Dialog 分为两个部分:bodyfooterfooter 需要具名为 footerslottitle 属性用于定义标题,它是可选的,默认值为空。
javascript 复制代码
<template>
  <el-button plain @click="dialogVisible = true">
    Click to open the Dialog
  </el-button>

  <!--
        v-model: 控制对话框显示隐藏
        title: 标题
        width: 宽度
        before-close: 关闭前的回调函数
  -->
  <el-dialog
    v-model="dialogVisible"
    title="Tips"
    width="500"
    :before-close="handleClose"
  >
    <!-- 默认插槽:主题内容 -->
    <span>This is a message</span>

    <!-- 具名插槽:底部内容 -->
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="dialogVisible = false">
          Confirm
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
    import { ref } from 'vue'
    import { ElMessageBox } from 'element-plus'

    const dialogVisible = ref(false) // 对话框是否可见

    const handleClose = (done) => {
        ElMessageBox.confirm('Are you sure to close this dialog?')
        .then(() => {
            done()
        })
        .catch(() => {
            // catch error
        })
    }
</script>

六、Menu菜单组件

1. 介绍

为网站提供导航功能的菜单。

2. 基础用法

顶部栏菜单可以在各种场景中使用。

导航菜单默认为垂直模式,通过将 mode 属性设置为 horizontal 来使导航菜单变更为水平模式。另外,在菜单中通过 sub-menu 组件可以生成二级菜单。

Menu还提供了 background-colortext-coloractive-text-color,分别用于设置菜单的背景色、菜单的文字颜色和当前激活菜单的文字颜色。

3. 示例代码

javascript 复制代码
<template>
    <h5 class="mb-2">Custom colors</h5>
    <!--
        菜单外层盒子:
        text-color: 文字颜色
        active-text-color: 激活菜单项的文本颜色
        background-color: 菜单的背景颜色
        default-active: 页面加载时默认激活菜单的 index
        class: 自定义类名
    -->
    <el-menu
        text-color="#fff"
        active-text-color="#ffd04b"
        background-color="#545c64"
        default-active="2"
        class="el-menu-vertical-demo"
        @open="handleOpen"
        @close="handleClose"
    >
        <!-- 二级导航,使用el-sub-menu -->
        <el-sub-menu index="1">
            <!-- 通过template来设置一级导航的标题 -->
            <template #title>
                <el-icon><location /></el-icon>
                <span>Navigator One</span>
            </template>

            <!-- 通过el-menu-item-group进行分组 -->
            <el-menu-item-group title="Group One">
                <el-menu-item index="1-1">item one</el-menu-item>
                <el-menu-item index="1-2">item two</el-menu-item>
            </el-menu-item-group>

            <el-menu-item-group title="Group Two">
                <el-menu-item index="1-3">item three</el-menu-item>
            </el-menu-item-group>

            <!-- 嵌套二级导航 -->
            <el-sub-menu index="1-4">
                <template #title>item four</template>
                <el-menu-item index="1-4-1">item one</el-menu-item>
            </el-sub-menu>
        </el-sub-menu>

        <!-- 一级导航使用el-menu-item -->
        <el-menu-item index="2">
            <el-icon><icon-menu /></el-icon>
            <span>Navigator Two</span>
        </el-menu-item>

        <el-menu-item index="3" disabled>
            <el-icon><document /></el-icon>
            <span>Navigator Three</span>
        </el-menu-item>
        
        <el-menu-item index="4">
            <el-icon><setting /></el-icon>
            <span>Navigator Four</span>
        </el-menu-item>
    </el-menu>
</template>

<script setup>
    import { Document, Menu as IconMenu, Location, Setting } from '@element-plus/icons-vue'

    const handleOpen = (key, keyPath) => {
        console.log(key, keyPath)
    }
    const handleClose = (key, keyPath) => {
        console.log(key, keyPath)
    }
</script>

<style>
    .el-menu {
        width: 300px;
    }
</style>

  1. 0-9 ↩︎
相关推荐
NEXT062 小时前
AI 应用工程化实战:使用 LangChain.js 编排 DeepSeek 复杂工作流
前端·javascript·langchain
念风零壹2 小时前
AI 时代的前端技术:从系统编程到 JavaScript/TypeScript
前端·ai
光影少年2 小时前
react的hooks防抖和节流是怎样做的
前端·javascript·react.js
小毛驴8502 小时前
Vue 路由示例
前端·javascript·vue.js
发现一只大呆瓜3 小时前
AI流式交互:SSE与WebSocket技术选型
前端·javascript·面试
m0_719084114 小时前
React笔记张天禹
前端·笔记·react.js
Ziky学习记录4 小时前
从零到实战:React Router 学习与总结
前端·学习·react.js
wuhen_n4 小时前
JavaScript链表与双向链表实现:理解数组与链表的差异
前端·javascript
wuhen_n4 小时前
JavaScript数据结构深度解析:栈、队列与树的实现与应用
前端·javascript