VueJS:同时使用 v-model 和 :value

Posted

技术标签:

【中文标题】VueJS:同时使用 v-model 和 :value【英文标题】:VueJS: Use v-model and :value in the same time 【发布时间】:2019-07-28 02:16:43 【问题描述】:

我正在寻找一种在同一对象上同时使用v-model:value 的方法。

我收到了这个错误:

:value="user.firstName" 与同一元素上的 v-model 冲突 因为后者已经在内部扩展为值绑定。

目的是将来自mapGetters(来自一个商店)的值设置为默认值,并在用户提交修改时设置正确的值。 (在onSubmit

<div class="form-group m-form__group row">
    <label for="example-text-input" class="col-2 col-form-label">
         $t("firstname") 
    </label>
    <div class="col-7">
        <input class="form-control m-input" type="text" v-model="firstname" :value="user.firstName">
    </div>
</div>


<script>
import  mapGetters, mapActions  from 'vuex';

export default 
    data () 
        return 
            lang: "",
            firstname: ""
        
    ,
    computed: mapGetters([
        'user'
    ]),
    methods: 
        ...mapActions([
            'updateUserProfile'
        ]),
        onChangeLanguage () 
            this.$i18n.locale = lang;
        ,
        // Function called when user click on the "Save changes" btn
        onSubmit () 
            console.log('Component(Profile)::onSaveChanges() - called');
            const userData = 
                firstName: this.firstname
            
            console.log('Component(Profile)::onSaveChanges() - called', userData);
            //this.updateUserProfile(userData);
        ,
        // Function called when user click on the "Cancel" btn
        onCancel () 
            console.log('Component(Profile)::onCancel() - called');
            this.$router.go(-1);
        
    

</script>

【问题讨论】:

【参考方案1】:

通常您希望在对象本身上设置v-model 的“初始”值,例如:

data() 
  return 
    firstname: 'someName'
  

但由于您是从商店获取的,您可以使用this.$store.getters[your_object] 访问特定的getter 对象,因此我将删除:value 绑定并单独使用v-model

<div class="col-7">
  <input class="form-control m-input" type="text" v-model="firstname">
</div>
<script>
export default 
  data() 
    return 
      lang: "",

      firstname: this.$store.getters.user.firstName
    
  ,

  // ...

</script>

【讨论】:

谢谢,现在可以使用了。我会记住,最好的选择是在数据对象中声明变量,无论初始值来自于 @wawanopoulos 没问题。尽管我们可以直接从存储中获取对象,但我们可能真的想将“范围”限制在当前组件中,因为我们将它们用作v-model,这意味着它们很容易发生变化;使用 Vuex,我们可能无法在不使用 store.commit() 的情况下改变状态。【参考方案2】:

Vue v-model 指令是 v-bind:valuev-on:input 的语法糖。 This alligator.io article 帮助我理解了它的工作原理。

所以基本上你的问题是v-model 指令将value 设置为firstname,而你也明确地将value 设置为user.firstName

有很多方法可以处理这个问题。我认为一个快速而直接的解决方案是将firstname 存储为一个数据变量(就像你已经在做的那样),然后只使用v-model,而不考虑v-bind:value

然后,要将来自商店的用户设置为默认用户名,您可以在 created 挂钩中将 fristname 设置为商店用户的用户名:

脚本:

<script>
import  mapGetters, mapActions  from 'vuex';

export default 
    created() 
      this.firstname = this.user.username; // is this right? no used to the map getters syntax, but this is the idea
    ,
    data () 
        return 
            lang: "",
            firstname: ""
        
    ,
    computed: mapGetters([
        'user'
    ]),
    methods: 
        ...mapActions([
            'updateUserProfile'
        ]),
        onChangeLanguage () 
            this.$i18n.locale = lang;
        ,
        // Function called when user click on the "Save changes" btn
        onSubmit () 
            console.log('Component(Profile)::onSaveChanges() - called');
            const userData = 
                firstName: this.firstname
            
            console.log('Component(Profile)::onSaveChanges() - called', userData);
            //this.updateUserProfile(userData);
        ,
        // Function called when user click on the "Cancel" btn
        onCancel () 
            console.log('Component(Profile)::onCancel() - called');
            this.$router.go(-1);
        
    

</script>

【讨论】:

【参考方案3】:

您应该只使用 v-model,它会与脚本中的值创建一个 2 路绑定:在 js 中更改变量将更新输入元素,与输入元素交互将更新变量。

如果您想使用默认值,只需将变量设置为该值(无论它来自何处)。

【讨论】:

以上是关于VueJS:同时使用 v-model 和 :value的主要内容,如果未能解决你的问题,请参考以下文章

VueJS:输入动态值+ v-model

v-model 不使用开关更改数据并选择 vuejs 中的下拉菜单

vuejs - v-model 不更新类属性

VueJS v3、Vuex 和 Composition API 以及输入字段上的 v-model

请问vuejs里的v-model 和:model有啥区别

VueJS v-model 和组件之间的数据绑定