Vue: Как вы привязываете значение к входу через компонент оболочки? - PullRequest
0 голосов
/ 04 ноября 2019

Я знаю, что вы можете использовать v-model для привязки значения к входу в том же компоненте. Как создать компонент-оболочку для ввода и привязать к нему значение?

Login.vue

<template>
  <div id="Login">
    <Input v-bind:value="email"/>    
    <Input v-bind:value="password"/>

  </div>
</template>
<script>
  import Input from './Input.vue'
  import Button from './Button'

  export default {
    name: 'Login',
    components: {
        Input,
        Button,
    },
    data: () => ({
        email:'test',
        password:'test',
    }),
    methods: {
        login: () => { debugger; }, //this.email and this.password are still set to test
    }
  }
</script>

Input.vue

<template>
  <div class="input>
   <input v-model="value"/>
  </div>
</template>
<script>
  export default {
    name: 'Input',
    props: {
        value: String,
    },
  }
</script>

Текущая настройкаприводит к

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"

Это единственный способ сделать это, отправив событие?

Ответы [ 3 ]

1 голос
/ 04 ноября 2019

Лучший способ - использовать v-модель для обертки и on / emit для ввода

<div id="Login">
    <Input v-model="email"/>    
    <Input v-model="password"/>    
</div>

...

<div class="input>       
   <input        
     v-bind:value="value"
     v-on:input="$emit('input', $event.target.value)"
   >
</div>
1 голос
/ 04 ноября 2019

Вы можете реализовать v-model непосредственно в компоненте input, выполнив это.

<template>
  <div class="input>
   <input :value="value" @input="$emit('input', $event.target.value)"/>
  </div>
</template>
<script>
  export default {
    name: 'Input',
    props: ["value"]
  }
</script>

И затем использовать его в своем родительском компоненте так:

<template>
  <div id="Login">
    <Input v-model="email"/>    
    <Input v-model="password"/>
  </div>
</template>
<script>
  import Input from './Input.vue'
  import Button from './Button'

  export default {
    name: 'Login',
    components: {
        Input,
        Button,
    },
    data: () => ({
        email:'test',
        password:'test',
    }),
    methods: {
        login: () => { debugger; }, //this.email and this.password are still set to test
    }
  }
</script>

Смотрите здесь

1 голос
/ 04 ноября 2019

Если я правильно понял, вы можете попробовать создать прозрачную оболочку (в моем случае AppInput)

SomeParent.vue

<div>
  <AppInput v-model="parentModel" />
</div>

AppInput.vue

<template>
  <input
    class="app-input"
    v-bind="$attrs"
    :value="value"
    v-on="{
      ...$listeners,
      input: event => $emit('input', event.target.value)
    }">
</template>
<script>
export default {
  name: "AppInput",
  inheritAttrs: false,
  props: ["value"]
};
</script>

одна из статей

...