首页 文章

在VueJS中动态生成按钮和页面生成

提问于
浏览
-1

我有一个JSON文件,它从后端向表中提供数据(内置Bootstrap-Vue) . 在该表中,我想让VueJS创建一个按钮,该按钮将在特定条件下生成,如果单击则会生成一个包含其他详细信息的新页面 .

以下是JSON输出的示例:

{"driver_id":2,"driver_name":"{driver_first_name}, {driver_last_name}","driver_truck":"58","driver_trailer":"37","driver_status":"sleeping","has_violations":true},

因此,如果“has_violations”为真,那么将生成按钮,onclick将通过JSON从后端请求其他数据,然后根据该数据生成新页面 .

所以类似于 event.target.closest('tr').dataset.userId 的香草js

但是我怎么能在VueJS中做到这一点?

Edited in Table Code (Per Request):

<template>
  <b-container fluid>

    <!--Search Controls-->
    <b-row>
      <b-col md="6" class="my-1">
        <b-form-group horizontal label="Filter" class="mb-0">
          <b-input-group>
            <b-form-input v-model="filter" placeholder="Type to Search" />
            <b-input-group-append>
              <b-btn :disabled="!filter" @click="filter = ''">Clear</b-btn>
            </b-input-group-append>
          </b-input-group>
        </b-form-group>
      </b-col>
      <b-col md="6" class="my-1">
        <b-form-group horizontal label="Sort" class="mb-0">
          <b-input-group>
            <b-form-select v-model="sortBy" :options="sortOptions">
              <option slot="first" :value="null">-- none --</option>
            </b-form-select>
            <b-form-select :disabled="!sortBy" v-model="sortDesc" slot="append">
              <option :value="false">Asc</option>
              <option :value="true">Desc</option>
            </b-form-select>
          </b-input-group>
        </b-form-group>
      </b-col>
      <b-col md="6" class="my-1">
        <b-form-group horizontal label="Sort direction" class="mb-0">
          <b-input-group>
            <b-form-select v-model="sortDirection" slot="append">
              <option value="asc">Asc</option>
              <option value="desc">Desc</option>
              <option value="last">Last</option>
            </b-form-select>
          </b-input-group>
        </b-form-group>
      </b-col>
      <b-col md="6" class="my-1">
        <b-form-group horizontal label="Per page" class="mb-0">
          <b-form-select :options="pageOptions" v-model="perPage" />
        </b-form-group>
      </b-col>
    </b-row>
    <!--Search Controls-->

    <!-- Main table element -->
    <b-table show-empty
             stacked="md"
             :items="items"
             :fields="fields"
             :current-page="currentPage"
             :per-page="perPage"
             :filter="filter"
             :sort-by.sync="sortBy"
             :sort-desc.sync="sortDesc"
             :sort-direction="sortDirection"
             @filtered="onFiltered"
    >
      <template slot="driverName" slot-scope="row">{{row.value.driver_first_name}} {{row.value.driver_last_name}}</template>
      <template slot="truckNumber" slot-scope="row">{{row.value.driver_truck}}</template>
      <template slot="truckNumber" slot-scope="row">{{row.value.driver_trailer}}</template>
      <template slot="status" slot-scope="row">{{row.value.driver_status}}</template>
      <template slot="violations" slot-scope="row">{{row.value?'Yes':'No'}}</template>
      <template slot="actions" slot-scope="row">
        <router-link :to="{name: 'driver_violations_list'}">
          <b-button id="driverLogs">View Driver Logs</b-button>
        </router-link>
      </template>

    </b-table>

    <b-row>
      <b-col md="6" class="my-1">
        <b-pagination :total-rows="totalRows" :per-page="perPage" v-model="currentPage" class="my-0" />
      </b-col>
    </b-row>

  </b-container>
</template>

<script>

export default {
  data () {
    return {
      items: items,
      fields: [
        { key: 'driver_name', label: 'Driver Name', sortable: true, sortDirection: 'desc' },
        { key: 'truck_number', label: 'Truck Number', sortable: true, 'class': 'text-center' },
        { key: 'trailer_number', label: 'Trailer Number', sortable: true, 'class': 'text-center' },
        { key: 'has_violations', label: 'Violations' },
        { key: 'driver_status', label: 'Status' },
        { key: 'actions', label: 'Actions' }
      ],
      currentPage: 1,
      perPage: 5,
      totalRows: items.length,
      pageOptions: [ 5, 10, 15 ],
      sortBy: null,
      sortDesc: false,
      sortDirection: 'asc',
      filter: null,
    }
  },
  computed: {
    sortOptions () {
      return this.fields
        .filter(f => f.sortable)
        .map(f => { return { text: f.label, value: f.key } })
    }
  },
  methods: {
    onFiltered (filteredItems) {
      // Trigger pagination to update the number of buttons/pages due to filtering
      this.totalRows = filteredItems.length
      this.currentPage = 1
    }
    //Get JSON
    getDriverStatus: function () {
      const url = 'driver_status_data.json'
        axios.get(url, {
          dataType: 'json',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
          },
          mode: 'no-cors',
          credentials: 'include'
        })
        .then(function (response) {
          console.log(JSON.stringify(response.data))
          this.courses = JSON.stringify(response.data)
        })
        .catch(function (error) {
          console.log(error)
        })
      }
  }
}
</script>

1 回答

  • 0

    使用文档here中的表格插槽有条件地渲染按钮 .

    这是一个例子:

    new Vue({
      el: '#app',
      computed: {
        driverName () {
          return this.driver ? `${this.driver.driver_name.driver_first_name} ${this.driver.driver_name.driver_last_name}` : 'N / A'
        }
      },
      methods: {
        showViolations (driver) {
          this.driver = driver
          
          this.loading = true
    
          // Simulate an async api call with setInterval and setTimeout
          
          let interval = setInterval(() => {
            this.progress += 10
          }, 250)
          
          setTimeout(() => {
            this.loading = false
            this.progress = 0
            clearInterval(interval)
          }, 2500)
        }
      },
      data () {
        return {
          progress: 0,
          driver: null,
          loading: false,
          violations: [
            'Violation 1',
            'Violation 2',
            'Violation 3'
          ],
          fields: {
            driver_id: {
              label: 'ID',
              sortable: true
            },
            first_name: {
              key: 'driver_name.driver_first_name',
              label: 'First Name',
              sortable: true
            },
            last_name: {
              key: 'driver_name.driver_last_name',
              label: 'Last Name',
              sortable: true
            },
            driver_truck: {
              label: 'Truck',
              sortable: true
            },
            driver_trailer: {
              label: 'Trailer',
              sortable: true
            },
            driver_status: {
              label: 'Status',
              sortable: true
            },
            has_violations: {
              label: 'Violations',
              sortable: true
            }
          },
          items: [
            {
              driver_id:2,
              driver_name: {
                driver_first_name: 'Bob',
                driver_last_name: 'Dole'
              },
              driver_truck: 58,
              driver_trailer: 37,
              driver_status: 'Sleeping',
              has_violations: true
            },
            {
              driver_id:3,
              driver_name: {
                driver_first_name: 'John',
                driver_last_name: 'Lennon'
              },
              driver_truck: 69,
              driver_trailer: 34,
              driver_status: 'Deep Sleeping',
              has_violations: false
            }
          ]
        }
      }
    })
    
    <!-- Add this to <head> -->
    <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.css"/>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <!-- Add this after vue.js -->
    <script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
    <script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
    
    <div id="app">
      <b-table striped hover :fields="fields" :items="items">
        <template slot="has_violations" slot-scope="data">
          <template v-if="data.item.has_violations">
            <b-button size="md" variant="primary" v-b-modal.violations @click="showViolations(data.item)">
                See Violations
            </b-button>
          </template>
        </template>
      </b-table>
      <b-modal id="violations" :title="`Violations By: ${driverName}`">
        <b-progress v-show="loading" :value="progress" :max="100" animated></b-progress>
        <p v-if="!loading" class="my-4" v-for="violation in violations" :key="violation">{{ violation }}</p>
      </b-modal>
    </div>
    

相关问题