Vue.js prop sync модификатор не обновляет родительский компонент - PullRequest
0 голосов
/ 07 октября 2019

У меня есть свойство, которое мне нужно передать дочернему компоненту, но дочерний компонент должен иметь возможность изменять переданное значение. Кажется, что модификатор .sync построен для этого, но я не могу заставить его работать. Вот мой код (упрощенно для этого вопроса):

Profile.vue

<template>
  <div>
    <Avatar :editing.sync="editing"></Avatar>
    <a href="" @click.prevent="changeAvatar">click to change</a>
    ...
  </div>
</template>

<script>
import Avatar from './profile/Avatar'

export default {
  components: { Avatar },
  data() {
    return {
      ...,
      editing: false,
    }
  },
  methods: {
    editAvatar() {
      this.editing = true;
    }
  }
}
</script>

Avatar.vue

<template>
  <div>
    <template v-if="!editing">
      <img class="avatar-preview" :src="avatar">
    </template>
    <template v-else>
      <label v-for="image in avatars>
        <img class="avatar-thumb" :src="image">
        <input type="radio" name="avatar" :checked="avatar === image">
      </label>
      <button class="btn btn-primary">Save</button>
    </template>
  </div>
</template>

<script>
export default {
  props: ['editing'],
  data() {
    return {
      avatar: '../../images/three.jpg',
      avatars: [
        '../../images/avatars/one.jpg',
        '../../images/avatars/two.jpg',
        '../../images/avatars/three.jpg',
        ...
      ]
    }
  },
  methods: {
    save() {
      axios.put(`/api/user/${ user.id }/avatar`, { avatar: this.avatar }
        .then(() => { console.log('avatar saved successfully'); })
        .catch(() => { console.log('error saving avatar'); })
        .then(() => { this.editing = false; }); //  ← this triggers a Vue warning
    }
  }
}
</script>

1 Ответ

1 голос
/ 07 октября 2019

Вы правы - модификатор .sync построен для случаев, подобных этому. Однако вы не совсем правильно его используете. Вместо того, чтобы напрямую изменять пропущенную подпорку, вам вместо этого нужно создать событие и позволить родительскому компоненту внести изменения.

Эту проблему можно решить, изменив метод save() в Avatar.vueкак это:

...
save() {
  axios.put(`/api/user/${ user.id }/avatar`, { avatar: this.avatar }
    .then(() => { console.log('avatar saved successfully'); })
    .catch(() => { console.log('error saving avatar'); })
    .then(() => { this.$emit('update:editing', false); });
  }
}
...
...