Vue.js 道具同步修饰符未更新父组件

Vue.js prop sync modifier not updating parent component

我有一个 属性 需要传递给子组件,但子组件需要能够修改传递的值。 .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>

你是对的 - .sync 修饰符就是为这种情况而构建的。但是,您并没有完全正确地使用它。您无需直接修改传递的 prop,而是需要发出一个事件,并允许父组件进行更改。

您可以通过像这样更改 Avatar.vue 中的 save() 方法来解决此问题:

...
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); });
  }
}
...