开发者问题收集

TypeError:无法读取 Vue 中未定义的属性

2021-10-28
13752

我是初级 Web 开发人员。我在 VUE 中创建了我的第一个项目。

我有此代码:

<script type="text/ecmascript-6">
import axios from 'axios';
import Vue from 'vue';
import 'vuejs-datatable/dist/themes/bootstrap-4.esm';
import {
  VuejsDatatableFactory,
  IDataFnParams,
  IDisplayHandlerParam,
  ITableContentParam,
  TColumnsDefinition,
  VueDatatable
} from 'vuejs-datatable';

Vue.use(VuejsDatatableFactory, VueDatatable);
import Swal from 'sweetalert2';

export default {
  props: {
    fetchUrl: {type: String, required: true},
    columns: {type: Array, required: true},
    headers: {type: Object, required: true},
    routeName: {type: String, required: true},
    showUrl: {type: String, required: false},
  },
  data() {
    return {
      tableData: [],
      url: '',
      pagination: {
        meta: {to: 1, from: 1}
      },
      offset: 4,
      currentPage: 1,
      perPage: 100,
      sortedColumn: this.columns[0],
      order: 'asc',
      search: '',
      pageOptions: [100, 200, 500, 1000],
    }
  },
  watch: {
    fetchUrl: {
      handler: function (fetchUrl) {
        this.url = fetchUrl
      },
      immediate: true
    }
  },
  created() {
    console.log(this.fetchUrl);
    return this.fetchData()
  },
  computed: {
    /**
     * Get the pages number array for displaying in the pagination.
     * */
    pagesNumber() {
      if (!this.pagination.meta.to) {
        return []
      }
      let from = this.pagination.meta.current_page - this.offset
      if (from < 1) {
        from = 1
      }
      let to = from + (this.offset * 2)
      if (to >= this.pagination.meta.last_page) {
        to = this.pagination.meta.last_page
      }
      let pagesArray = []
      for (let page = from; page <= to; page++) {
        pagesArray.push(page)
      }
      return pagesArray
    },
    /**
     * Get the total data displayed in the current page.
     * */
    totalData() {
      return (this.pagination.meta.to - this.pagination.meta.from) + 1
    }
  },
  methods: {
    fetchData() {
      let dataFetchUrl = `${this.url}&page=${this.currentPage}&column=${this.sortedColumn}&order=${this.order}&per_page=${this.perPage}&search=${this.search}`
      axios.get(dataFetchUrl)
        .then(({data}) => {
          this.pagination = data
          this.tableData = data.data
        }).catch(error => this.tableData = [])
    },
    /**
     * Get the serial number.
     * @param key
     * */
    serialNumber(key) {
      return (this.currentPage - 1) * this.perPage + 1 + key
    },
    /**
     * Change the page.
     * @param pageNumber
     */
    changePage(pageNumber) {
      this.currentPage = pageNumber
      this.fetchData()
    },
    /**
     * Sort the data by column.
     * */
    sortByColumn(column) {
      if (column === this.sortedColumn) {
        this.order = (this.order === 'asc') ? 'desc' : 'asc'
      } else {
        this.sortedColumn = column
        this.order = 'asc'
      }
      this.fetchData()
    },
    handleSearch() {
      this.fetchData()
    },
    handlePerPage($event) {
      this.perPage = $event.target.value;
      this.fetchData()
    },

    recordLink(id) {
      return this.routeName + `/${id.toString()}`
    },
    editRecordLink(id) {
      return this.routeName + `/${id.toString()}/edit`
    },
    showRecord(id) {
      const recordLink = this.recordLink(id);
      this.$router.push({path: recordLink});
    },
    editRecord(id) {
      const editRecordLink = this.editRecordLink(id);
      this.$router.push({path: editRecordLink});
    },
    deleteRecord(id) {
      let self = this;
      axios.post(this.$apiAdress + '/api/' + this.routeName + '/' + id + '?token=' + localStorage.getItem("api_token"), {
        _method: 'DELETE'
      })
        .then(function (response) {
          Swal.fire(
            'Sukces!',
            'Rekord usunięty poprawnie!',
            'success'
          )
          self.fetchData();
        }).catch(function (error) {
        console.log(error);
        self.$router.push({path: '/login'});
      });
    },
    prepareRemove(id){
      const removeId = id;
      Swal.fire({
        title: 'Czy na pewno',
        text: "Chcesz usunąć ten rekord?",
        type: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#d33',
        cancelButtonColor: '#3085d6',
        confirmButtonText: 'Tak, usuń!',
        cancelButtonText: 'Anuluj',
        buttonsStyling: true
      }).then(function (isConfirm) {
        if(isConfirm.value === true) {
          this.deleteRecord(removeId);
        }
      });
    }


    ///
  },
  filters: {
    columnHead(value) {
      return value.split('_').join(' ').toUpperCase()
    }
  },
  name: 'DataTable'
}
</script>

它工作正常。我在 prepareRemove(id) 方面遇到问题。当我在点击链接 <button class="btn btn-danger" @click="prepareRemove(data.id)"> 后运行此函数时

我收到了带有问题的 sweetalert(没问题)。确认后出现错误:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'deleteRecord')

我该如何修复它?

1个回答

这是一个与 this 绑定相关的问题。将函数声明写为方法选项内的回调是一个常见错误。我建议在这些情况下使用箭头函数。

Swal.fire({
  title: 'Czy na pewno',
  text: "Chcesz usunąć ten rekord?",
  type: 'warning',
  showCancelButton: true,
  confirmButtonColor: '#d33',
  cancelButtonColor: '#3085d6',
  confirmButtonText: 'Tak, usuń!',
  cancelButtonText: 'Anuluj',
  buttonsStyling: true
  }).then((isConfirm) => {
    // now 'this' depends on the lexical enviroment.
    if(isConfirm.value === true) {
      this.deleteRecord(removeId);
    }
});
Lucas David Ferrero
2021-10-28