Vue обратный вызов через реквизит и «это» - PullRequest
0 голосов
/ 20 января 2020

Обычно, когда вы регистрируете прослушиватель событий на кнопке в vanilla JS, если вы передаете функцию обратного вызова, которая использует ключевое слово "this", а не функцию стрелки, когда эта функция выполняется, "this" будет ссылаться на элемент кнопки, и вы должны использовать метод .bind (), чтобы преодолеть это. Но когда вы передаете функцию обратного вызова, например «props», из родительского компонента в дочерний компонент и используете его там, и эта функция также использует ключевое слово «this», почему «this» в дочернем компоненте имеет ссылку на родительский vue экземпляр, а не дочерний vue экземпляр? vue использует какую-то привязку за сценой? Кто-нибудь может объяснить? У меня есть этот учебник, где у меня есть родительский и дочерний компонент, а также сценарий использования prop, который является функцией обратного вызова, которая использует «this»:

// Parent component
    <template>
      <div class="component">
        <h1>The User Component</h1>
        <p>I'm an awesome User!</p>
        <button @click="changeName">Change my Name</button>
        <p>Name is {{ name }}</p>
        <p>Age is {{ age }}</p>
        <hr />
        <div class="row">
          <div class="col-xs-12 col-sm-6">
            <app-user-detail
              :myName="name"
              @nameWasReset="name = $event"
              :resetFn="resetName"
              :userAge="age"
            ></app-user-detail>
          </div>
          <button id="buton">Buton</button>
          <div class="col-xs-12 col-sm-6">
            <app-user-edit :userAge="age" @ageWasEdited="age = $event"></app-user-edit>
          </div>
        </div>
      </div>
    </template>

    <script>
    import UserDetail from "./UserDetail.vue";
    import UserEdit from "./UserEdit.vue";

    export default {
      data: function() {
        return {
          name: "Max",
          age: 27
        };
      },
      methods: {
        changeName() {
          this.name = "Anna";
        },
        resetName() {
          console.log(this);
          this.name = "Max";
        }
      },
      components: {
        appUserDetail: UserDetail,
        appUserEdit: UserEdit
      },
      mounted() {
        document.getElementById("buton").addEventListener("click", this.resetName);
      }
    };
    </script>

    <style scoped>
    div {
      background-color: lightblue;
    }
    </style>

// Child component
<template>
  <div class="component">
    <h3>You may view the User Details here</h3>
    <p>Many Details</p>
    <p>User Name: {{ switchName() }}</p>
    <p>User Age: {{ userAge }}</p>
    <button @click="resetName">Reset Name</button>
    <button @click="resetFn()">Reset Name</button>
  </div>
</template>

<script>
import { eventBus } from "../main";

export default {
  props: {
    myName: {
      type: String
    },
    resetFn: Function,
    userAge: Number
  },
  methods: {
    switchName() {
      return this.myName
        .split("")
        .reverse()
        .join("");
    },
    resetName() {
      this.myName = "Max";
      this.$emit("nameWasReset", this.myName);
    }
  },
  created() {
    eventBus.$on("ageWasEdited", age => {
      this.userAge = age;
    });
  }
};
</script>

1 Ответ

1 голос
/ 20 января 2020

Все, что сделано для props в Vue, - это передать их и присоединить к экземпляру дочернего компонента.

Никакой другой вид привязки не выполняется , поэтому контекст (this) по-прежнему будет родительским

Я предлагаю использовать события вместо передачи реквизитов функций, как в React.

События являются более Vue -подобный (в значительной степени это соглашение, так как именно это Vue разработчик будет искать в первую очередь при общении между родителями и детьми), их будет легче отслеживать, и контекст события будет понятен с нуля. до.

...