Search code examples
vue.jsbootstrap-4bootstrap-table

Vuejs bootstrap b-table data not loading/updating


I have an object in Vue that contains a string key for each user and a list (of courses) as the values that I would like to use to populate a b-table.

I'm wondering if there is a way to do this so that the items in the table are reactive, ie the table updates as the data in the userCourses variable updates. A simplified version of the code is shown below:

<div v-for="user in users" v-bind:key="user">
    <b-table :items="userCourses[user]" :fields="courseFields"></b-table>
</div>
userCourses: {
  'userOne': [...],
  'userTwo': [...]
}

Solution

  • Improved example:

    Vue.config.productionTip = false;
    Vue.use(BootstrapVue);
    
    new Vue({
      data() {
        return {
          user: null,
          users: ["userOne", "userTwo"],
          userCourses: {
            userOne: [{ c: "Java" }, { c: "PHP" }, { c: "C#" }],
            userTwo: [{ c: "English" }, { c: "Polish" }, { c: "Spanish" }]
          },
          fields: [{ key: "c", label: "Course" }],
          course: "example"
        };
      },
      methods: {
        addCourse() {
          this.userCourses[this.selectedUser].push({ c: this.course });
        }
      },
      computed: {
        selectedUser: {
          get() {
            return this.user || this.users[0];
          },
          set(v) {
            this.user = v;
          }
        }
      }
    }).$mount("#app");
    <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
    <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
    <script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
    <script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
    <script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
    
    <div id="app">
      <b-form-radio v-for="user in users" v-model="selectedUser" name="selected-user" :key="'u-'+user" :value="user">{{user}}</b-form-radio>
      <b-form-input v-model="course" placeholder="Course name"></b-form-input>
      <b-button @click="addCourse">Add</b-button>
      <div v-for="(courses, user) in userCourses" :key="'c-'+user">
        <strong>{{user}}</strong>
        <b-table :items="courses" :fields="fields"></b-table>
      </div>
    </div>

    Previous example:

    Vue.config.productionTip = false;
    Vue.use(BootstrapVue);
    
    new Vue({
      data() {
        return {
          users: ["userOne", "userTwo"],
          selectedUser: "userOne",
          courseName: "example",
          userCourses: {
            userOne: [{c: "A"}, {c: "B"}, {c: "C"}],
            userTwo: [{c: "X"}, {c: "Y"}, {c: "Z"}]
          }
        };
      },
      methods: {
        addCourse() {
          this.userCourses[this.selectedUser].push({
            c: this.courseName
          });
        }
      }
    }).$mount("#app");
    <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
    <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
    <script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
    <script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
    <script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
    
    <div id="app">
      <b-form-radio v-for="user in users" v-model="selectedUser" name="selected-user" :value="user">{{user}}</b-form-radio>
      <b-form-input v-model="courseName" placeholder="Course name"></b-form-input>
      <b-button @click="addCourse">Add</b-button>
      <div v-for="user in users" v-bind:key="user">
        <b-table :items="userCourses[user]"></b-table>
      </div>
    </div>