首页 > 解决方案 > How to add dynamically v-model and it's initial values to existed html elements by vuejs

问题描述

For SEO purposes I need to render html elements by php. For example I have these elements.

<?php foreach ($elements as $key => $element): ?>
    <select name="first" v-model="model[<?= $key; ?>]">
        <option value="">Select</option>
        <option value="1">Some Text</option>
        <option value="2">Some Text</option>
    </select>
    <select name="second" v-model="model[<?= $key; ?>]>
        <option value="">Select</option>
        <option value="4">Some Text</option>
        <option value="5">Some Text</option>
    </select>
    ...
    ...
    ...
    <select name="eleven" v-model="model[<?= $key; ?>]>
        <option value="">Select</option>
        <option value="101">Some Text</option>
        <option value="102">Some Text</option>
    </select>
<?php endforeach; ?>

And probably I can manipulate these elements like this on vue side.

const count_models = <?= count($elements) ?>; // in the html
const app = new Vue({
  el: '#app',
  data: {
    model:[]
  },
  mounted(){
    console.log(this.model);
    for (let $i = 0; $i < count_models; $i++) {
        this.model[$i] = "";
    }
  }
})

I cannot declare the initial values for model[?]. I need an xhr or assign counted items to a javascript variable to get how many select element I have on DOM and to declare initial values as null for each model[]. Even I redeclare the initial values of the models, it doesn't bind. I just put an example on jsFiddle. In Angular1 there was ng-init attribute to declare initial value for the model.

How can I solve this problem ?

https://jsfiddle.net/ks7jmgwv/1/

标签: vue.jsvuejs2

解决方案


您刚刚遇到了 Vuejs 最常见的问题之一:反应性(因此缺乏)!

这里的问题是,当创建模型属性时,它只是一个空数组/对象,并且您添加到该元素的任何属性都不会是反应性的:这意味着以编程方式进行的任何类型的更改都不会触发 Vue 的内部问题, v-model 仍然有效的唯一原因是用户而不是代码所做的更改实际上会触发原生 HTML 事件。

您有两种可能的解决方案:

  • 忽略反应性部分(但您将无法以编程方式更新所选值,或者至少它不可见),只需通过为其分配正确的值来确保默认选择“选择”选项(这样你就可以跳过所有默认的for循环初始化)。

    <option :value="undefined" selected="selected" disabled>Select</option>

  • 按照 Vuejs 文档建议的官方方式向对象添加新属性,并且仍然具有反应性的优势

    this.$set(this.model, $i, "");

您可以查看这个 plunker,我在其中向您展示了实现目标的两种方式: https ://jsfiddle.net/8y7eu39z/18/

另外,您是否知道对于选择中的占位符选项,您可以添加禁用属性?

反应性参考: https ://vuejs.org/v2/guide/reactivity.html


另外:如果你想要一个“null”作为默认值,但没有设法找到一种方法让它被“select”选项识别,那么你应该可以 :value="null"使用value="null"this.$set(this.model, $i, null);


推荐阅读