javascript - 在 Vuejs 和 Bootstrap Vue 中编辑行

标签 javascript vuejs2 bootstrap-vue

我正在尝试实现一个表,该表允许用户通过使用编辑按钮切换来编辑行。
我能够实现切换功能,但遇到了一个问题,它切换所有行而不是单行。
我相信我必须按索引选择行,并且通过我的实现我可以这样做,但似乎我无法找到它的任何用途。

Vue.component('employee-data', {
    template:
        /*html*/
        `
        <b-container>
            <h3>Employee Data</h3>
            
            <b-pagination v-model="currentPage" :total-rows="rows" :per-page="perPage" 
                            aria-controls="employee-table"></b-pagination>
            <b-table striped hover :items="employees" id="employee-table"
                    :per-page="perPage" :current-page="currentPage" :fields="fields">

                <template v-slot:cell(employeeName)="row" v-if="edit">
                    <b-form-input v-model="row.item.employeeName"/>
                </template>

                <template v-slot:cell(joinDate)="row" v-if="edit">
                    <b-form-input v-model="row.item.joinDate"/>
                </template>

                <template v-slot:cell(selectedDepartment)="row" v-if="edit">
                    <b-form-input v-model="row.item.selectedDepartment"/>
                </template>
                
                <template v-slot:cell(jobDescription)="row" v-if="edit">
                    <b-form-input v-model="row.item.jobDescription"/>
                </template>

                <template v-slot:cell(actions)="row">
                    <b-button @click="toggleEdit(row.index)">
                        {{ edit ? 'Save' : 'Edit' }}
                    </b-button>
                </template>

            </b-table>
        </b-container>
    `,
    props: {
        employees: {
            type: Array,
            required: true
        }
    },
    data() {
        return {
            edit: false,
            perPage: 3,
            currentPage: 1,
            fields: [
                {
                    key: 'employeeName',
                    label: 'Employee Name',
                    sortable: true
                  },
                  {
                    key: 'joinDate',
                    label: 'Join Date',
                    sortable: true
                  },
                  {
                    key: 'selectedDepartment',
                    label: 'Selected Department',
                    sortable: true,
                  },
                  {
                    key: 'jobDescription',
                    label: 'Job Description',
                    sortable: true,
                  },
                  {
                    key: 'actions',
                    label: 'Actions',
                    sortable: false,
                  }
              ]
        }
    },
    computed: {
        rows() {
            return this.employees.length
        }
    },
    methods: {
        toggleEdit(index){
            this.edit = !this.edit
        }
    }
})
编辑:
Here is the JSFiddle showing the issue

最佳答案

如果您有一个唯一标识符(如 id)并且只想允许一次编辑一行,您可以设置您的 edit id 的变量当前正在编辑的行。
您也可以使用通用插槽 v-slot:cell() , 以减少您编写的模板数量。
例子

new Vue({
  el: "#app",
  data() {
    return {
      edit: null,
      employees: [{
          id: 0,
          employeeName: "Jane",
          joinDate: "11-11-1111",
          selectedDepartment: "IT",
          jobDescription: "Nerd"
        },
        {
          id: 1,
          employeeName: "Peter",
          joinDate: "12-12-1212",
          selectedDepartment: "Accounting",
          jobDescription: "Moneier"
        }
      ],
      fields: [{
          key: 'employeeName',
          label: 'Employee Name',
          sortable: true
        },
        {
          key: 'joinDate',
          label: 'Join Date',
          sortable: true
        },
        {
          key: 'selectedDepartment',
          label: 'Selected Department',
          sortable: true
        },
        {
          key: 'jobDescription',
          label: 'Job Description',
          sortable: true
        },
        {
          key: 'actions',
          label: 'Actions'
        }
      ]
    }
  },
  computed: {
    rows() {
      return this.employees.length
    }
  },
  methods: {
    onEdit(id) {
      this.edit = this.edit !== id ? id : null;
    }
  }
})
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-vue/2.18.1/bootstrap-vue.min.css" />

<script src="//cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-vue/2.18.1/bootstrap-vue.min.js"></script>

<div id="app">
  <b-table striped hover :items="employees" :fields="fields">
    <template v-slot:cell()="{ value, item, field: { key }}">
      <template v-if="edit != item.id">{{ value }}</template>
    <b-form-input v-else v-model="item[key]" />
    </template>

    <template v-slot:cell(actions)="{ item: { id }}">
        <b-dropdown variant="primary" text="Actions">
          <b-dropdown-item @click="onEdit(id)">{{ edit === id ? 'Save' : 'Edit' }}</b-dropdown-item>
          <b-dropdown-divider></b-dropdown-divider>
          <b-dropdown-item @click="onDelete(id)">Delete</b-dropdown-item>
        </b-dropdown>
      </template>
  </b-table>
</div>

如果您没有每行的唯一标识符,或者希望能够一次编辑多行,您可以为您的项目添加一个标志(在示例中为 isEditing),这将切换该行是否为当前是否正在编辑。
示例 2

new Vue({
  el: "#app",
  data() {
    return {
      employees: [{
          id: 0,
          employeeName: "Jane",
          joinDate: "11-11-1111",
          selectedDepartment: "IT",
          jobDescription: "Nerd"
        },
        {
          id: 1,
          employeeName: "Peter",
          joinDate: "12-12-1212",
          selectedDepartment: "Accounting",
          jobDescription: "Moneier"
        }
      ],
      fields: [{
          key: 'employeeName',
          label: 'Employee Name',
          sortable: true
        },
        {
          key: 'joinDate',
          label: 'Join Date',
          sortable: true
        },
        {
          key: 'selectedDepartment',
          label: 'Selected Department',
          sortable: true
        },
        {
          key: 'jobDescription',
          label: 'Job Description',
          sortable: true
        },
        {
          key: 'actions',
          label: 'Actions'
        }
      ]
    }
  },
  computed: {
    rows() {
      return this.employees.length
    }
  },
  methods: {
    onEdit(item) {
      if (item.isEditing)
        item.isEditing = false;
      else
        this.$set(item, 'isEditing', true)
    }
  }
})
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-vue/2.18.1/bootstrap-vue.min.css" />

<script src="//cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-vue/2.18.1/bootstrap-vue.min.js"></script>

<div id="app">
  <b-table striped hover :items="employees" :fields="fields">
    <template v-slot:cell()="{ value, item, field: { key }}">
      <template v-if="!item.isEditing">{{ value }}</template>
    <b-form-input v-else v-model="item[key]" />
    </template>

    <template v-slot:cell(actions)="{ item }">
        <b-dropdown variant="primary" text="Actions">
          <b-dropdown-item @click="onEdit(item)">{{ item.isEditing ? 'Save' : 'Edit' }}</b-dropdown-item>
          <b-dropdown-divider></b-dropdown-divider>
          <b-dropdown-item>Delete</b-dropdown-item>
        </b-dropdown>
      </template>
  </b-table>
</div>

关于javascript - 在 Vuejs 和 Bootstrap Vue 中编辑行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64629051/

相关文章:

javascript - Vue 键的类型转换 v-for

javascript - 如何忽略 TestCafe 中的 "ResizeObserver loop limit exceeded"

javascript - 使用 Vue.js 为恒定(未知)数据流设置动画的最佳方式?

javascript - 在 CSS/JS 中可以有一个半透明层覆盖另一个层而不会阻塞/捕获点击

vue.js - vue^2.6.14版本如何安装vue-router 4

javascript - Bootstrap-Vue b-tab : CSS does not seem to be applying to active-nav-item-class

vue.js - 如何在 Vue.js 中使用 bootstrap 轮播

javascript - 如何使用 Bootstrap Vue 通过悬停禁用工具提示打开

javascript - 如何使用 JQuery 为所有具有特定类的 div 分配唯一 ID

javaScript - 求给定整数的所有除数之和