Vuejs + onClick 不适用于安装后加载的动态元素

Vuejs + onClick doesn't work on dynamic element loaded after mounted

我被这个问题困住了。当我点击某个元素时,它会将一个项目推送到一个数组中,然后我将这个数组显示在 table 中。我想添加一个操作来删除 table 中的任何行,例如: Table

我的代码:

<div id="pos">
<div class="container-fluid" style="font-size: 0.8em;">
    <div class="row grid-columns">
        <div class="col-md-6 col">
            <table class="table">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>Descripcion</th>
                        <th>Stock</th>
                        <th>Precio uni</th>
                        <th>Precio alt</th>
                        <th>Cant</th>
                        <th>Subtotal</th>
                        <th>Acciones</th>
                    </tr>
                </thead>
                <tbody>
                    <pos-products
                        :products="products"
                        v-on:remove-product="removeProduct"
                    >
                    </pos-products>
                    <!-- <tr v-for="item in products" :key="item.id">
                        <th scope="row">${item.id}</th>
                        <td>${ item.descripcion }</td>
                        <td>${ item.stock }</td>
                        <td>${ item.precio } $</td>
                        <td>${ item.precio_alt } $</td>
                        <td>
                            <v-minusplusfield :value="1" :min="1" :max="100" v-model="item.cant"></v-minusplusfield>
                        </td>
                        <td>${ getSubtotal(item) }</td>
                        <td><a href="#" @click="removeItem(item)"> Borrar </a></td>
                    </tr> -->
                </tbody>
            </table>
        </div>
        <div class="col-md-6 col">
            <div>
                <div id="grid-header" class="p-2 border-b ">
                    <input class="form-control" name="searchString" placeholder="Buscar producto" type="text" v-model="searchString" />
                </div>
            </div>
            <div style="background-color:#fff">
                <div class="col-md-3" v-for="item in searchResults">
                    <a
                        href="#"
                        class="list-group-item"
                        :key="item.id"
                        @click="loadItem(item)"
                    >
                        <img src="//images03.nicepage.com/a1389d7bc73adea1e1c1fb7e/af4ca43bd20b5a5fab9f188a/pexels-photo-3373725.jpeg" alt="" class="u-expanded-width u-image u-image-default u-image-1" width="25" height="30">
                        <h6 class="u-text u-text-default u-text-1">${item.descripcion}</h6>
                        <h4 class="u-text u-text-default u-text-2">${item.precio}$ / ${item.precio_alt}$</h4>
                    </a>
                </div>
            </div>
        </div>
    </div>
</div>

Vue代码:

const app = new Vue({
el: "#pos",
delimiters: ["${", "}"],
data () {
    return {
        products: [],
        total: 0,
        client: "",
        user: "",
        paymentDetail: [],
        errors: {},
        garantia: false,
        saveButton: false,
        seller: "",
        searchString: "",
        searchTypingTimeout: "",
        searchResults: [],
    }
},
methods: {
    getSubtotal: function (item) {
        return parseInt(item.cant) * parseFloat(item.precio);
    },
    loadItem: function (item) {
        this.products.push({
            id: item.id,
            descripcion: item.descripcion,
            stock: item.stock,
            precio: item.precio,
            precio_alt: item.precio_alt,
            cant: 1,
        });
    },
    removeItem: () => {
        products = products.filter((el) => el !== item);
    },
    searchProducts: function (value) {
        axios
            .post("/v2/producto/search", {
                query: value
            })
            .then((response) => {
                if (!response.status == 200 || response.data.error) {
                    console.log('error')
                    const errorMessage = response.data.error
                        ? response.data.error
                        : "Ha ocurrido un error";
                    console.log("mensaje: " + errorMessage);
                    this.$swal({
                        icon: "error",
                        title: "Oops...",
                        text: errorMessage,
                    });
                    return;
                }
                this.searchResults = response.data.data;
            })
            .catch((error) => {
                console.log("catch error", error);
            });
    },
},
mounted() {
    var csrf = document
        .querySelector('meta[name="csrf-token"]')
        .getAttribute("content");
    this.products = [];
},
computed: {},
watch: {
    total(val) {
        this.total = parseFloat(val);
    },
    searchString(val) {
        if (this.searchTypingTimeout) clearTimeout(this.searchTypingTimeout);
        this.searchTypingTimeout = setTimeout(
            () => this.searchProducts(this.searchString),
            850
        );
    },
},

});

我知道了:

vue.js?3de6:634 [Vue warn]: Property or method "removeItem" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

尝试像这样使用经典函数:

removeItem(item){
   const index = this.items.findIndex(x => x.id === item.id)
   this.items.splice(index, 1)
},

我在这里用 jsonplaceholder.typicode.com api

加载了数据

new Vue({
      el: '#app',
      data: () => ({
        items: []
      }),
      
      async mounted(){
        await axios.get('https://jsonplaceholder.typicode.com/posts')
        .then(res => {
          this.items = res.data
        })
      },
      
      methods: {
        removeItem(item){
          const index = this.items.findIndex(x => x.id === item.id)
          this.items.splice(index, 1)
        },
      }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js" integrity="sha512-odNmoc1XJy5x1TMVMdC7EMs3IVdItLPlCeL5vSUPN2llYKMJ2eByTTAIiiuqLg+GdNr9hF6z81p27DArRFKT7A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="app">

<h1>List </h1>
  <ul>
    <li v-for="item of items" :key="item.id">
      <a @click="removeItem(item)">{{item.id}} - {{item.title}}</a>
    </li>
  </ul>
</div>