【问题标题】:image cannot update on vue js with axios图像无法使用 axios 在 vue js 上更新
【发布时间】:2026-01-12 12:50:02
【问题描述】:

我在使用 axios 的 vue js 上的图像更新功能有问题。我已成功使用图像创建数据,但现在我正在更新图像

这是模板代码部分

   <template>
  <q-page-container>
    <transition
      enter-active-class="animated fadeInLeft"
      leave-active-class="animated fadeOutRight"
      appear
      :duration="700"
    >
      <q-page>
        <q-toolbar elevated class="text-primary">
          <q-btn
            flat
            round
            dense
            icon="arrow_back"
            @click="$router.push('/produk')"
          />
          <q-toolbar-title>
            Edit produk
          </q-toolbar-title>
        </q-toolbar>
        <form>
          <div class="row justify-center">
            <p style=" width:90%; margin-top:10px;">Nama barang :</p>
            <q-input
              name="namaproduk"
              dense
              outlined
              v-model="dataproduk.namaproduk"
              lazy-rules
              :rules="[
                val => (val && val.length > 0) || 'Please type something'
              ]"
              label="Nama produk"
              style="width:90%; margin-right:10px; margin-left:10px; margin-bottom: 20px; justify-content: center;"
            />
            <p style=" width:90%; ">Harga barang :</p>
            <q-input
              name="harga"
              dense
              outlined
              v-model="dataproduk.harga"
              type="number"
              label="Harga produk"
              style="width:90%; margin-right:10px; margin-left:10px; margin-bottom: 20px; justify-content: center;"
              lazy-rules
              :rules="[
                val => (val && val.length > 0) || 'Please type something'
              ]"
            />
            <p style=" width:90%;">Deskripsi :</p>
            <q-editor
              v-if="dataproduk.deskripsi"
              name="deskripsi"
              style="width:90%; margin-right:10px; margin-left:10px; margin-bottom: 20px; justify-content: center;"
              v-model="dataproduk.deskripsi"
              :definitions="{
                bold: { label: 'Bold', icon: null, tip: 'My bold tooltip' }
              }"
            />
            <p style=" width:90%;">Gambar sekarang :</p>
            <img
              v-if="dataproduk.gambar"
              :src="'http://127.0.0.1:8000/storage/' + dataproduk.gambar"
              style="width:150px; height:150px;"
            />
            <p style=" width:90%;">Ubah Gambar :</p>
            <q-file
              name="gambar"
              @change="handleFileObject()"
              dense
              outlined
              v-model="image"
              label="Gambar produk"
              style="width:90%; margin-right:10px; margin-left:10px; margin-bottom: 20px; "
            />
            <q-btn
              @click.prevent="ubah"
              type="submit"
              dense
              color="primary"
              label="Edit"
              style="width:90%; margin: 20px; justify-content: center;"
            />
          </div>
        </form>
      </q-page>
    </transition>
  </q-page-container>
</template>

该方法用于修改数据

methods: {
handleFileObject() {
  this.image = this.$refs.file.files[0];
},
ubah() {
  var dataproduk = new FormData();
  dataproduk.append("namaproduk", this.dataproduk.namaproduk);
  dataproduk.append("harga", this.dataproduk.harga);
  dataproduk.append("deskripsi", this.dataproduk.deskripsi);
  dataproduk.append("gambar", this.image);
  _.each(this.dataproduk, (value, key) => {
    dataproduk.append(key, value);
  });
  axios
    .put(
      "http://127.0.0.1:8000/api/produk/update/" + this.id,
      this.dataproduk,
      {
        headers: {
          "Content-Type":
            "multipart/form-data; charset=utf-8; boundary=" +
            Math.random()
              .toString()
              .substr(2)
        }
      }
    )
    .then(response => this.$router.push("/indexadmin"))
    .catch(err => {
      if (err.response.status === 422) {
        this.errors = [];
        _.each(err.response.data.errors, error => {
          _.each(error, e => {
            this.errors.push(e);
          });
        });
      }
    });
}

如果我不使用字符串和整数形式的“content-type:multipart/form-data”数据,它会成功更改。如果我使用“content-type:multipart/form-data”,那么所有数据都无法更新

添加“content-type:multipart/form-data”时出错

异常:“Illuminate\Database\QueryException” 文件:“D:\magang\serverapi\vendor\laravel\framework\src\Illuminate\Database\Connection.php” 线路:678 消息:“SQLSTATE [23000]:完整性约束违规:1048 列 'namaproduk' 不能为空(SQL:更新 produkdatas 设置 namaproduk = ?、deskripsi = ?、harga = ?、produkdatasupdated_at = 2021-04-09 01:50:07 其中id = 13)" trace: [{file: "D:\magang\serverapi\vendor\laravel\framework\src\Illuminate\Database\Connection.php",…},…]

【问题讨论】:

  • 这个问题本质上是服务器端的。读取例外 Integrity constraint violation: 1048 Column 'namaproduk' cannot be null 您的 DBMS 中有一个约束,防止列 namaproduk 为空。这意味着没有数据被添加到该列。向该列添加一些数据,它会通过删除表定义中的not null 来插入或更改列约束以允许为空。如果那是您的 blob 列,请确保您在服务器端正确处理 blob
  • 我试过了,但是我要改成value的数据提交后变成了null
  • 这是服务器端问题,不是 Axios 或 Vue 问题。此问题源于尝试将 blob 错误地插入到您正在使用的任何数据库中。这是 PHP 和 Mysql 的示例phppot.com/php/mysql-blob-using-php
  • 但是当添加数据成功时

标签: php laravel


【解决方案1】:

您好,有 laravel + vue 文件输入的工作示例

<img v-if="user.photo" class="block w-8 h-8 rounded-full ml-4" :src="user.photo" />

 <file-input v-model="form.photo" :error="form.errors.photo" class="pr-6 pb-8 w-full lg:w-1/2" type="file" accept="image/*" label="Photo" />

文件输入.vue

<template>
  <div>
    <label v-if="label" class="form-label">{{ label }}:</label>
    <div class="form-input p-0" :class="{ error: errors.length }">
      <input ref="file" type="file" :accept="accept" class="hidden" @change="change" />
      <div v-if="!value" class="p-2">
        <button type="button" class="px-4 py-1 bg-gray-500 hover:bg-gray-700 rounded-sm text-xs font-medium text-white" @click="browse">
          Browse
        </button>
      </div>
      <div v-else class="flex items-center justify-between p-2">
        <div class="flex-1 pr-1">
          {{ value.name }} <span class="text-gray-500 text-xs">({{ filesize(value.size) }})</span>
        </div>
        <button type="button" class="px-4 py-1 bg-gray-500 hover:bg-gray-700 rounded-sm text-xs font-medium text-white" @click="remove">
          Remove
        </button>
      </div>
    </div>
    <div v-if="errors.length" class="form-error">{{ errors[0] }}</div>
  </div>
</template>

<script>
export default {
  props: {
    value: File,
    label: String,
    accept: String,
    errors: {
      type: Array,
      default: () => [],
    },
  },
  watch: {
    value(value) {
      if (!value) {
        this.$refs.file.value = ''
      }
    },
  },
  methods: {
    filesize(size) {
      var i = Math.floor(Math.log(size) / Math.log(1024))
      return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]
    },
    browse() {
      this.$refs.file.click()
    },
    change(e) {
      this.$emit('input', e.target.files[0])
    },
    remove() {
      this.$emit('input', null)
    },
  },
}
</script>

【讨论】: