vue插件element ui,element plus,ElMessage消息框,ref,动态绑定语法

文章目录

element系列插件用途广泛。

安装并引入

通用组件推荐在main.js引入,以下内容添加到main.js文件中:

js 复制代码
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(ElementPlus) // 注册插件

el-dialog组件

弹框插件,将常用的功能,如标题,点击事件作为属性,避免了重复写代码。

el-dialog属性列表

el-dialog新增示例-html部分
html 复制代码
<el-dialog v-model="showAddDialog" title="新增项目资料" width="500px" :close-on-click-modal="false">
  <el-form :model="newResourceForm" label-width="80px">
    <el-form-item label="资料名称">
      <el-input v-model="newResourceForm.resourceName" placeholder="请输入资料名称" />
    </el-form-item>
    <el-form-item label="上传文件">
      <el-upload
        :action="uploadUrl"
        :on-success="handleUploadSuccess"
        :limit="1"
        accept=".pdf,.zip,.rar,.doc,.docx">
        <el-button type="primary">点击上传</el-button>
        <template #tip>
          <div class="el-upload__tip">支持 pdf/zip/doc 等格式</div>
        </template>
      </el-upload>
    </el-form-item>
  </el-form>
  
  <template #footer>
    <el-button @click="showAddDialog = false">取消</el-button>
    <el-button type="primary" :loading="submitting" @click="handleSubmit">保存</el-button>
  </template>
</el-dialog>
el-dialog新增示例-js部分
js 复制代码
// 表单数据
const newResourceForm = ref({
  resourceName: '',
  resourcePath: '' // 上传成功后由接口返回
});

// 1. 处理文件上传成功
const handleUploadSuccess = (response) => {
  if (response.success && response.data && response.data.length > 0) {
    // 你的接口返回的 data 是一个数组,取第一个作为路径
    newResourceForm.value.resourcePath = response.data[0];
    ElMessage.success('文件上传成功');
  } else {
    ElMessage.error(response.message || '文件上传失败');
  }
};

// 2. 提交保存
const handleSubmit = async () => {
  if (!newResourceForm.value.resourceName || !newResourceForm.value.resourcePath) {
    ElMessage.warning('请填写资料名称并上传文件');
    return;
  }

  submitting.value = true;
  try {
    const response = await fetch('/mysite/api/projectResource/insert', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        projectId: projectId,
        resourceName: newResourceForm.value.resourceName,
        resourcePath: newResourceForm.value.resourcePath
      })
    });

    const result = await response.json();
    if (result.success) {
      ElMessage.success('新增资料成功');
      showAddDialog.value = false;
      // 核心:保存成功后,重新拉取项目详情,刷新列表
      fetchProjectDetail(); 
    } else {
      ElMessage.error(result.message || '保存失败');
    }
  } catch (err) {
    ElMessage.error('网络请求失败');
  } finally {
    submitting.value = false;
  }
};

el-upload

el-upload属性列表

:action

:action 用于指定文件上传的后台接口地址(url)

示例
python 复制代码
<el-upload
        :action="uploadUrl" // 
        :on-success="handleUploadSuccess"
        :limit="1"
        accept=".pdf,.zip,.rar,.doc,.docx">
        <el-button type="primary">点击上传</el-button>
        <template #tip>
          <div class="el-upload__tip">支持 pdf/zip/doc 等格式</div>
        </template>
      </el-upload>

解读:
:action="uploadUrl" # 绑定上传地址
:on-success="handleUploadSuccess" # 成功后回调函数
:limit="1" # 限制允许上传的文件最大数量为1个
accept=".pdf,.zip,.rar,.doc,.docx" # 允许的文件类型

<el-button type="primary">点击上传</el-button>
type="primary" # 
按钮类型

除了 primary,Element 还提供了其他几种内置类型,用于区分不同的操作场景:

默认(不写 type):用于一般性操作(如:取消、返回)。

type="primary":常规按钮(蓝色)。

type="success":成功按钮(绿色),用于正向操作(如:通过、发布)。

type="warning":警告按钮(橙色/黄色),用于需要谨慎的操作。

type="danger":危险按钮(红色),用于破坏性操作(如:删除、清空)。

type="info":信息按钮(灰色),用于中性信息展示。

上传弹框更换图片的原理?

这块开始没看懂,其实很简单。

点更换图片相当于触发文件选择控件,选完文件后触发回调函数,这个函数里面主要做如下逻辑:

1、请求上传接口,解析返回报文

2、将表单该字段赋值为文件地址,如:

js 复制代码
直接赋值:
form.value.coverUrl = result.data[0];

拼接地址的赋值:
form.value.coverUrl = PREVIEW_BASE + result.data[0];

const fileInputRef = ref(null); // 用于触发文件选择框

html 复制代码
<div class="upload-actions">
      <input
        type="file"
        ref="fileInputRef"
        @change="handleUpload"
        accept="image/*"
        style="display: none"
      />
      <button
        type="button"
        @click="$refs.fileInputRef.click()"
        :disabled="loading"
        class="upload-btn"
      >
        {{ form.coverUrl ? "更换封面" : "上传封面" }}
      </button>
      <span v-if="uploading" class="upload-status">上传中...</span>
    </div>
  </div>
</div>

ElMessage

ElMessage是消息框,属于弹框的一种。

例如上传用对话框,成功后用消息框。

作用是简化了,消息框的使用,一行代码搞定。

js 复制代码
import { ElMessage } from 'element-plus'

// 普通提示(灰色)
ElMessage('这是一条普通消息')

// 成功提示(绿色,带对勾图标)
ElMessage.success('操作成功!')

// 警告提示(黄色,带感叹号图标)
ElMessage.warning('请先选择文件')

// 错误提示(红色,带叉号图标)
ElMessage.error('网络异常,请稍后再试')

ref

最核心的机制之一。

示例
js 复制代码
  // 弹窗相关状态
const showAddDialog = ref(false);
const submitting = ref(false);
const uploadUrl = '/mysite/api/projectResource/upload'; // 你的上传接口地址

// 表单数据
const newResourceForm = ref({
  resourceName: '',
  resourcePath: '' // 上传成功后由接口返回
});
为什么要用ref,直接定义变量不行吗?

ref好。

1、可变 # vue setup中顶层声明的变量不可变

2、响应式 # 不使用ref,值变化不会告诉浏览器

vue的渲染过程

之前会有个疑问,vue中html先执行还是js先执行的呢?

举个例子就明白了。

1、vue内容

html 复制代码
<div class="box">{{ message }}</div>

2、解析为抽象语法树

js 复制代码
{
  type: 'Element',
  tag: 'div',
  attrs: [{ name: 'class', value: 'box' }],
  children: [
    { 
      type: 'Interpolation', // 标记这是一个插值表达式
      content: 'message' 
    }
  ]
}

3、输出渲染函数

js 复制代码
function render(_ctx) {
  // _ctx 代表组件的上下文(即你的 data 或 setup 返回的数据)
  // h (或 _createVNode) 是 Vue 内部用来创建虚拟 DOM 的函数
  return h('div', { class: 'box' }, _ctx.message);
}

这个渲染函数是如何工作的?

1、当Vue需要渲染页面时,它会执行这个render函数:

2、函数读取_ctx.message的值(比如"HelloVue")。

3、通过h()函数,在内存中生成一个轻量级的JavaScript对象,也就是虚拟DOM(VNode)。

4、Vue的运行时(Runtime)拿到这棵虚拟DOM树后,再调用浏览器原生的API(如document.createElement),将其映射为真实的DOM节点并插入到页面中。

动态绑定语法

:src示例

静态地址:

html 复制代码
<img src="../../public/placeholder-image.jpg" alt="项目封面" class="cover-img" />

动态地址:

如果图片在/public目录下,不用加/public前缀,直接写文件名即可。

html 复制代码
<img :src="'placeholder-image.jpg'" alt="项目封面" class="cover-img" />
:class示例
html 复制代码
<button
  class="tab-btn"
  :class="{ active: activeTab === 'resources' }"
  @click="activeTab = 'resources'"
>


:class # 这是动态绑定语法,作用是告诉vue,引号里面是js表达式,请计算结果并将结果作为css类名添加到元素上
active: # 类似于三目运算法符
activeTab # 这个是自定义的ref对象

整体的作用是:如果activeTab === 'resources',就给这个按钮添加active样式。

css为:

css 复制代码
.tab-btn.active { background-color: #00b894; color: white; border-color: #00b894; }

注:这个并不是切换tab页的整体效果,只是tab页标签的颜色效果。

如何区分动态绑定语法和伪类?

它们长的很像。

1、在vue中是动态绑定语法

2、在style中是伪类

v-html

核心作用:

将一段包含HTML标签的字符串,直接解析并渲染为真实的DOM结构。

应用场景:

1、markdown页面解析 # 见vue markdown笔记

2、嵌入某个div块

v-html

html 复制代码
<template>
  <!-- 模板保持极简,只负责绑定 -->
  <div class="container" v-html="staticHtml"></div>
</template>

<script setup>
import { computed } from 'vue';

// 在 computed 中定义好完整的 HTML 结构
const staticHtml = computed(() => {
  return `
    <div class="card">
      <h3>这是标题</h3>
      <p>这是一段描述内容,<strong>支持加粗</strong>。</p>
      <ul>
        <li>列表项 1</li>
        <li>列表项 2</li>
      </ul>
    </div>
  `;
});
</script>

指令

在vue中v-开头的表示指令。

v-if指令

v-if,v-else-if ,v-else

可以用来控制显隐,例如作为tab页的基础。

html 复制代码
<div class="content-panel" v-if="activeTab === 'resources'"></div>

实现tab页效果

实现tab页效果-html-导航栏部分
html 复制代码
<div class="resources-section" v-if="!loading && !error">
        <!-- Tab 导航栏 -->
        <div class="tabs">
          <button
            class="tab-btn"
            :class="{ active: activeTab === 'resources' }"
            @click="activeTab = 'resources'"
          >
            项目资料
          </button>
          <button
            class="tab-btn"
            :class="{ active: activeTab === 'intro' }"
            @click="activeTab = 'intro'"
          >
            项目介绍
          </button>
          <button
            class="tab-btn"
            :class="{ active: activeTab === 'videos' }"
            @click="activeTab = 'videos'"
          >
            视频目录
          </button>
          <button
            class="tab-btn"
            :class="{ active: activeTab === 'teacher' }"
            @click="activeTab = 'teacher'"
          >
            讲师介绍
          </button>
        </div>
实现tab页效果-html-内容部分
html 复制代码
<div class="content-panel" v-if="activeTab === 'resources'">项目资料内容</div>
<div class="content-panel" v-else-if="activeTab === 'videos'"></div>
<div class="content-panel" v-else-if="activeTab === 'intro'"></div>
<div class="content-panel" v-else-if="activeTab === 'teacher'"></div>
实现tab页效果-js部分
js 复制代码
const activeTab = ref('resources'); // ✅ 新增:控制当前激活的 Tab,默认显示资料

实现下拉菜单

主要有这个几个标签:

:外层触发器容器,负责控制下拉行为的触发(如你代码中的 trigger="hover")。

:下拉浮层的内容区,必须嵌套在 内部。

:具体的菜单项条目,必须嵌套在 内部。

实现下拉菜单-html部分

html 复制代码
<div class="nav-item dropdown-wrapper">
  <el-dropdown trigger="hover">
    <span class="el-dropdown-link nav-link-text">
      积分专区
      <!-- 小箭头图标 -->
      <el-icon class="el-icon--right"><arrow-down /></el-icon>
    </span>

    <!-- 下拉的内容列表 -->
    <template #dropdown>
      <el-dropdown-menu>
        <el-dropdown-item icon="CircleCheck">
          <router-link to="/points/tasks" style="text-decoration: none; color: inherit;">
            积分任务
          </router-link>
        </el-dropdown-item>
        <el-dropdown-item icon="Document" divided>
          <router-link to="/points/exchange" style="text-decoration: none; color: inherit;">
            兑换免费资料
          </router-link>
        </el-dropdown-item>
      </el-dropdown-menu>
    </template>
  </el-dropdown>
</div>

实现下拉菜单-箭头-js部分

element-plus本来就带下拉菜单,引入方式见上文,属于通用方式。

这里用到了箭头,需要额外再引入下:

js 复制代码
import { ArrowDown } from '@element-plus/icons-vue'

上文中的这部分用到了箭头:

html 复制代码
<el-icon class="el-icon--right"><arrow-down /></el-icon>

实现下拉菜单(简版)(不带router-link)

html 复制代码
<div class="nav-item dropdown-wrapper">
  <el-dropdown trigger="hover">
    <span class="el-dropdown-link nav-link-text">
      主菜单
    </span>
    <template #dropdown>
      <el-dropdown-menu>
        <el-dropdown-item icon="CircleCheck">
            子菜单1
        </el-dropdown-item>
        <el-dropdown-item icon="Document" divided>
            子菜单2
        </el-dropdown-item>
        <el-dropdown-item icon="Document" divided>
            子菜单3
        </el-dropdown-item>
      </el-dropdown-menu>
    </template>
  </el-dropdown>
</div>
相关推荐
li-xun2 小时前
2026年6月10日博客精选
javascript·人工智能·ui
智码看视界3 小时前
老梁聊全栈系列:Vue3核心与组合式API深度解析
javascript·vue.js·ecmascript
阿猫的故乡13 小时前
Vue过渡动画从入门到装X:淡入淡出、滑动、列表动画、第三方库全搞定
前端·javascript·vue.js
裕波13 小时前
Vue&ViteConf 2026 将于 7 月 18 日在上海举办,尤雨溪将现场发表主题演讲
vue.js·vite
狼哥168614 小时前
蛋糕美食元服务_我的实现指南
ui·harmonyos
狼哥168614 小时前
蛋糕美食元服务_美食实现指南
ui·harmonyos
RReality15 小时前
【Unity UGUI】血条 / 进度条(HP Bar)
ui·unity·游戏引擎·图形渲染
如果超人不会飞15 小时前
TinyRobot SuggestionPills紧凑的建议按钮组组件
前端·vue.js
如果超人不会飞15 小时前
TinyRobot Container构建优雅的AI对话容器
前端·vue.js