为什么观察者无法检测到变化?

问题描述 投票:0回答:1

下面的代码中有App.vue、appSidebar.vue和invoiceContent.vue文件,观察者没有检测到invoiceContent.vue中clearForm属性的变化,并且

console.log("clearForm :>> ", clearForm)
没有被执行。有人可以告诉为什么吗?我在这里失去了理智。我检查了当我单击 appSidebar.vue 中的红色按钮时,clearInvoice 正在执行,并且clearForm 正在更改为
true
.

应用程序.vue;

<template>
  <div class="w-screen h-full bg-gray-800 flex flex-row text-white items-start justify-center">
    <app-sidebar
      :invoices="invoiceList"
      :editInvoice="editInvoice"
      :deleteInvoice="deleteInvoice"
      :toggleButton="toggleButton"
      :clearInvoice="clearInvoice"
    />
    <invoice-content
      :saveInvoice="saveInvoice"
      :activeInvoice="state.activeInvoice"
      :showButton="showButton"
      :clearForm="clearForm"
    />
  </div>
</template>
<script setup>
import { reactive, ref } from "vue"
import appSidebar from "./components/appSidebar.vue"
import invoiceContent from "./components/invoiceContent.vue"

const invoiceList = ref([
  {
    id: new Date().getTime(),
    contact: {
      contact_name: "Demo1",
      email: "demo@demo",
      city: "demoland",
      country: "Demoika",
      zipcode: "22222"
    },
    items: [
      {
        id: new Date().getTime(),
        name: "Demo ürün",
        qty: 1,
        unit_price: 10.0,
        total_price: 15.0
      }
    ]
  }
])
const state = reactive({ activeInvoice: null })
const saveInvoice = (invoice) => {
  console.log("invoice :>> ", invoice)
  invoiceList.value.push(invoice)
}
const editInvoice = (invoice) => {
  console.log(invoice)
  state.activeInvoice = invoice
  console.log("state.activeInvoice :>> ", state.activeInvoice)
}

const deleteInvoice = (invoice) => {
  console.log("invoice to be deleted :>>", invoice)
  invoiceList.value = invoiceList.value.filter((i) => i.id !== invoice.id)
}

const showButton = ref(false)

const toggleButton = () => {
  showButton.value = !showButton.value
}

const clearForm = ref(false)

const clearInvoice = () => {
  clearForm.value = !clearForm.value
}
</script>

appSidebar.vue;

<template>
  <aside style="height: 830px" class="bg-gray-700 w-[300px] h-screen">
    <h3 class="text-2xl font-bold mt-2 p-2">Fatura Listesi</h3>
    <div
      v-for="(invoice, i) in invoices"
      :key="invoice.id"
      class="odd:bg-gray-600 flex justify-between items-center p-2"
    >
      <span> #{{ i + 1 }}</span>
      <span>{{ invoice.contact.contact_name }}</span>
      <span>
        <button @click="redButtonClick(invoice)" class="danger-button mr-1">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            class="fill-current"
            height="16"
            viewBox="0 0 24 24"
            width="16"
          >
            <path d="M0 0h24v24H0V0z" fill="none" />
            <path
              d="M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z"
            />
          </svg>
        </button>
        <button @click="purpleButtonClick(invoice)" class="purple-button">
          <svg
            class="fill-current"
            xmlns="http://www.w3.org/2000/svg"
            height="16"
            viewBox="0 0 24 24"
            width="16"
          >
            <path d="M0 0h24v24H0V0z" fill="none" />
            <path
              d="M12 6c3.79 0 7.17 2.13 8.82 5.5C19.17 14.87 15.79 17 12 17s-7.17-2.13-8.82-5.5C4.83 8.13 8.21 6 12 6m0-2C7 4 2.73 7.11 1 11.5 2.73 15.89 7 19 12 19s9.27-3.11 11-7.5C21.27 7.11 17 4 12 4zm0 5c1.38 0 2.5 1.12 2.5 2.5S13.38 14 12 14s-2.5-1.12-2.5-2.5S10.62 9 12 9m0-2c-2.48 0-4.5 2.02-4.5 4.5S9.52 16 12 16s4.5-2.02 4.5-4.5S14.48 7 12 7z"
            />
          </svg>
        </button>
      </span>
    </div>
  </aside>
</template>
<script setup>
const props = defineProps({
  invoices: Array,
  editInvoice: Function,
  deleteInvoice: Function,
  toggleButton: Function,
  clearInvoice: Function
})

const purpleButtonClick = (invoice) => {
  props.editInvoice(invoice)
  props.toggleButton()
}

const redButtonClick = (invoice) => {
  props.deleteInvoice(invoice)
  props.clearInvoice()
}
</script>

发票内容.vue;

<template>
  <section class="bg-gray-900 w-3/5 mx-auto mt-10 p-2 px-5 rounded-md shadow-2xl">
    <contact-section :contact="state.contact" />
    <div class="mt-5">
      <app-heading title="Some Title" />
      <invoice-items :items="state.items" :AddInvoiceItem="AddInvoiceItem" />
    </div>
    <invoice-summary :items="state.items" />

    <hr class="bg-gradient-to-r h-[1px] border-none from-gray-700 mt-5" />
    <div id="actionbar" class="actionbar text-right my-5">
      <button v-if="showButton" class="mr-3 purple-button">Update</button>
      <button @click="onSubmit" class="purple-button">Save</button>
    </div>
  </section>
</template>
<script setup>
import { ref, reactive, provide, watch } from "vue"
import invoiceItems from "./invoiceItems.vue"
import invoiceSummary from "./invoiceSummary.vue"
import contactSection from "./contactSection.vue"

const props = defineProps({
  saveInvoice: Function,
  activeInvoice: [Object, null],
  showButton: Boolean,
  clearForm: Boolean
})

const state = reactive({
  id: null,
  created_at: null,
  contact: {
    contact_name: null,
    email: null,
    city: null,
    country: null,
    zipcode: null
  },
  items: []
})
const AddInvoiceItem = () => {
  state.items.push({
    id: new Date().getTime(),
    name: null,
    qty: null,
    unit_price: 0.0,
    total_price: 0.0
  })
}

const DeleteInvoiceItem = (invoiceItem) => {
  state.items = state.items.filter((i) => i.id !== invoiceItem.id)
}

provide("DeleteInvoiceItem", DeleteInvoiceItem)

const onSubmit = () => {
  props.saveInvoice({ ...state, created_at: new Date(), id: new Date().getTime() })
  state.contact = {
    contact_name: null,
    email: null,
    city: null,
    country: null,
    zipcode: null
  }
  state.items = []
}
console.log("props.activeInvoice :>> ", props.activeInvoice)

const actionBarContent = ref('<button class="mr-3 purple-button">Güncelle</button>')

watch(
  () => props.activeInvoice,
  (activeInvoice) => {
    if (activeInvoice) {
      state.contact = { ...activeInvoice.contact }
      state.items = [...activeInvoice.items]
    }
    console.log("activeInvoice :>> ", activeInvoice)
  },
  () => props.showButton,
  (showButton) => {
    if (showButton) {
      actionBarContent.value =
        '<button @click="customAction" class="purple-button">Update</button>'
    } else {
      actionBarContent.value = ""
    }
  },
  () => props.clearForm,
  (clearForm) => {
    if (clearForm) {
      console.log("clearForm :>> ", clearForm)
    }
  }
)
</script>

我在观察者中尝试了

{immediate: true}
,并尝试将clearForm放入watchEffect中,但仍然不起作用。我不知道为什么,我的意思是 showButton 几乎是一样的,而且工作得很好,但这个不行。

vuejs3 vite watch vue-props
1个回答
0
投票

正如 @yoduh 上面建议的那样,我为每个道具设置了不同的观察者,并且它有效。

© www.soinside.com 2019 - 2024. All rights reserved.