Глубокая копия объекта Javascript не работает должным образом в Vue.js - PullRequest
5 голосов
/ 24 мая 2019

Я передаю клон объекта из родительского компонента в дочерний компонент, используя props, но когда я изменяю значение свойства status в объекте родительского компонента, дочерний компонент получает уведомление и изменениязначение свойства status в "клонированном" объекте.

Я читал о методе Object.assign() и о том, что он выполняет только поверхностное копирование, но странно то, что мои свойства объекта имеют примитивный тип String означает, что они должны быть скопированы по значению, а не по ссылке, я даже попытался присвоить значения вручную и попробовал способ JSON, как показано ниже, но ничего не работает, как я ожидал.

Родительский компонент: AppServers

<template>
  <div>
    <AppServerStatus v-for="server in servers"   :serverObj="JSON.parse(JSON.stringify(server))">
    </AppServerStatus>
    <hr>
    <button @click="changeStatus()">Change server 2</button>
  </div>
</template>

<script>
  import AppServerStatus from './AppServerStatus';

  export default {
    name: "AppServers",
    components: {
      AppServerStatus
    },
    data() {
      return {
        servers: [
          {
            name: 'server1',
            status: 'Critical'
          },
          {
            name: 'server2',
            status: 'Normal'
          },
          {
            name: 'server3',
            status: 'abnormal'
          },
          {
            name: 'server4',
            status: 'idle'
          },
          {
            name: 'server5',
            status: 'Good'
          },
        ],
        serverTmp: {}
      }
    },
    methods: {
      changeStatus(){
        this.servers[1].status = 'Active';
      }
    }
  }
</script>

Дочерний компонент: AppServerStatus

<template>
  <div>
    <h3>Server Name: {{ serverObj.name }}</h3>
    <p>Server Status: {{ serverObj.status }}</p>
    <hr>
  </div>
</template>

<script>
  export default {
    name: "AppServerStatus",
    data() {
      return {
        status: 'Critical'
      }
    },
    props: [
      'serverObj'
    ]
  }
</script>

Я ожидаю, что значение свойства status в объекте дочернего компонента останется Нормальным когда я выполняю changeStatus() в родительском компоненте, но он также изменяется.

1 Ответ

4 голосов
/ 24 мая 2019

Создайте новый объект из serverObj реквизита created или mounted для предотвращения нежелательной реактивности.

<template>
  <div>
    <h3>Server Name: {{ server.name }}</h3>
    <p>Server Status: {{ server.status }}</p>
    <hr>
  </div>
</template>

<script>
  export default {
    name: 'AppServerStatus',
    data() {
      return {
        status: 'Critical',
        server: {
          name: '',
          status: ''
        }
      }
    },

    props: [
      'serverObj'
    ],

    mounted() {
       this.server = {
         name: this.serverObj.name,
         status: this.serverObj.status
       };
    }
  }
</script>

...