You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Vue.js、Bootstrap-Vue实现多用户表单权限:禁用指定输入项

嘿,这个需求在Vue + Bootstrap-Vue的技术栈下实现起来挺顺畅的,我给你整理了几个实用的方案,从基础实现到进阶优化都有:

实现方案:多角色表单权限控制(用户1编辑/用户2只读+专属编辑)

核心思路

本质是根据用户角色动态控制表单字段的可交互状态:

  1. 识别当前登录用户的角色(用户1/用户2)
  2. 预加载用户1已提交的表单数据
  3. 对用户1的字段,给用户2设置只读/禁用属性
  4. 对用户2的专属字段,仅开放给用户2编辑
  5. 后端做最终校验(前端控制只是体验层面,不能替代后端权限)

1. 基础实现:角色识别与动态绑定字段状态

第一步:角色与表单数据管理

先在组件里维护当前用户角色和表单数据(实际项目中角色从登录态/后端接口获取,表单数据从后端拉取用户1已提交的内容):

<script>
export default {
  data() {
    return {
      currentUserRole: 'user2', // 实际项目替换为真实角色判断
      formData: {
        // 用户1专属字段
        user1_name: '',
        user1_department: '',
        // 用户2专属字段
        user2_feedback: '',
        user2_approval_status: ''
      }
    }
  },
  mounted() {
    // 模拟从后端拉取用户1的已填数据
    this.fetchUser1FormData()
  },
  methods: {
    async fetchUser1FormData() {
      const res = await fetch('/api/form/user1-data')
      const user1Data = await res.json()
      // 合并用户1数据到表单
      this.formData = {...this.formData, ...user1Data}
    },
    async handleSubmit() {
      // 提交时只传给后端用户2的字段(或由后端过滤)
      const submitData = {
        user2_feedback: this.formData.user2_feedback,
        user2_approval_status: this.formData.user2_approval_status
      }
      await fetch('/api/form/submit-user2', {
        method: 'POST',
        body: JSON.stringify(submitData)
      })
    }
  }
}
</script>

第二步:用Bootstrap-Vue组件动态控制权限

Bootstrap-Vue的所有表单组件(b-form-input、b-form-select、b-form-textarea等)都支持disabled和readonly属性,我们可以根据角色动态绑定:

<template>
  <b-form @submit.prevent="handleSubmit">
    <!-- 用户1字段:用户2只读禁用 -->
    <b-form-group label="用户1姓名">
      <b-form-input 
        v-model="formData.user1_name"
        :readonly="currentUserRole === 'user2'"
        :disabled="currentUserRole === 'user2'"
      />
    </b-form-group>

    <b-form-group label="用户1部门">
      <b-form-select 
        v-model="formData.user1_department"
        :options="['技术部', '市场部', '人事部']"
        :disabled="currentUserRole === 'user2'"
        readonly
      />
    </b-form-group>

    <!-- 用户2字段:仅用户2可编辑 -->
    <b-form-group label="用户2反馈">
      <b-form-textarea 
        v-model="formData.user2_feedback"
        :disabled="currentUserRole !== 'user2'"
        rows="3"
      />
    </b-form-group>

    <b-form-group label="用户2审批状态">
      <b-form-radio-group 
        v-model="formData.user2_approval_status"
        :options="['同意', '驳回', '待确认']"
        :disabled="currentUserRole !== 'user2'"
      />
    </b-form-group>

    <!-- 提交按钮:仅用户2可见/可用 -->
    <b-button 
      type="submit" 
      variant="primary"
      :disabled="currentUserRole !== 'user2'"
    >
      提交我的内容
    </b-button>
  </b-form>
</template>

小贴士:readonly和disabled的区别:readonly字段可以选中复制,disabled字段完全不可交互,根据你的需求选择即可。


2. 进阶优化:封装权限逻辑减少重复代码

如果表单字段很多,重复写currentUserRole === 'user2'会很冗余,可以用以下方式优化:

方式一:封装计算属性

<script>
export default {
  // ...其他代码
  computed: {
    isUser2() {
      return this.currentUserRole === 'user2'
    },
    isUser1() {
      return this.currentUserRole === 'user1'
    }
  }
}
</script>

模板里简化为:

<b-form-input 
  v-model="formData.user1_name"
  :readonly="isUser2"
/>

方式二:全局权限指令(适合多页面复用)

如果整个项目都有类似的权限控制,可以写一个全局指令:

// main.js
Vue.directive('form-permission', {
  inserted(el, binding) {
    // binding.value 接收角色和权限类型
    const { role, permission } = binding.value
    const currentRole = Vue.prototype.$currentUser.role // 全局存储的当前用户角色

    if (role === 'user2' && permission === 'readonly') {
      el.setAttribute('readonly', true)
    } else if (role === 'user2' && permission === 'disabled') {
      el.setAttribute('disabled', true)
    }
  }
})

模板里使用:

<b-form-input 
  v-model="formData.user1_name"
  v-form-permission="{role: 'user2', permission: 'readonly'}"
/>

3. 关键注意事项:后端校验不可少

前端的权限控制只是提升用户体验,一定要在后端做最终校验:

  • 用户2提交时,后端要过滤掉用户1的字段,只接受用户2的专属字段
  • 禁止用户2通过接口修改用户1的已填数据
  • 接口层面限制:用户2只能获取表单数据,不能修改用户1的部分

内容的提问来源于stack exchange,提问作者omiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:10:40