vue.js - 如何在 VueJS 组件中绑定(bind) v-model

标签 vue.js vuejs2 vue-component vuetify.js

我是 Vue 的新手,所以我尝试使用 Vuetify 创建一个 Input Date Picker

这是我的代码:

Codepen

问题是,当我在选择器中选择一个日期时,控制台出现错误:

[Vue warn]:避免直接修改 prop,因为只要父组件重新渲染,该值就会被覆盖。相反,使用基于 prop 值的数据或计算属性。正在发生变化的 Prop :'$value'

这是创建该组件的正确方法吗?

最佳答案

如错误所述,您不能更改子项的 Prop 。这是因为 Vue 使用了这个父子流: enter image description here

通过这种结构,您可以确保 parent 的数据是唯一的真实来源。 为了更改数据,您需要将其发送给父级。你几乎在你的例子中有它。您需要为 v-model 发出 input 以同步更改,而不是发出 change 事件。

当您看到 docs 中的示例时,这一点会更清楚:

<input v-model="searchText">

确实是一样的:

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

但是,从 vue 2.3.0 开始,您现在可以通过 .sync modifier 更改 Prop 。

Vue.component('date-picker', {
    props: ['label'],
    data: () => ({
        date: null,
        dateFormatted: null,
        open: false
    }),
    created() {
        this.date = this.$value;
    },
    methods: {
        formatDate (date) {
            if (!date) return null
            const [year, month, day] = date.split('-')
            return `${day}/${month}/${year}`
        },
        parseDate (date) {
            if (!date) return null
            const [day, month, year] = date.split('/')
            return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`
        },
        update() {
            this.$emit('input', this.dateFormatted);
        }
    },
    watch: {
        date (val) {
            this.dateFormatted = this.formatDate(this.date)
        },
        dateFormatted(val) {
            this.update();
        }
    },
    template:`
        <v-menu
            ref="open"
            :close-on-content-click="false"
            v-model="open"
            :nudge-right="40"
            lazy
            transition="scale-transition"
            offset-y
            full-width
            >
            <v-text-field
                slot="activator"
                v-model="dateFormatted"
                :label="label"
                placeholder="dia/mês/ano"
                @blur="date = parseDate(dateFormatted)"
            ></v-text-field>
            <v-date-picker v-model="date" no-title @input="open = false"></v-date-picker>
        </v-menu>
    `
});

Vue.config.productionTip = false;
Vue.config.devtools=false

new Vue({
  el: '#app',
  data: () => ({
    myDate: '2018-09-01'
  })
});
<link href="https://cdn.jsdelivr.net/npm/vuetify@1.1.4/dist/vuetify.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.js"></script>


<div id="app">
  <v-app>
     <v-flex xs24>
       <date-picker label="Select a date" v-model="myDate"></date-picker>
       <br>
       Current date: {{myDate}}
    </v-flex>
  </v-app>
</div>

关于vue.js - 如何在 VueJS 组件中绑定(bind) v-model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52130350/

相关文章:

javascript - 将动态 bool 属性传递给 VueJS 组件

vue.js - 如何扩展从 npm 包导入的 vue 组件?

vue.js - 在 CI 管道中运行开发服务器

vue-component - 将默认值设置为选项选择菜单

javascript - 如何从webpack javascript中的文件夹,子文件夹及其子文件夹动态获取文件

vue.js - 视觉 : v-model and input event in custom component derived of a custom component

javascript - [Vue警告] : Error in beforeCreate hook: "ReferenceError: document is not defined"

vue.js - 如何在构建时替换图像和文件而不在应用程序中引用它们?

javascript - vue-router 重定向不适用于路由推送

html - vue 中的 <component> 总是渲染换行符