2

Demo: https://codesandbox.io/s/23959y5wnp

So I'm passing down a function and would like to rebind the this so I used .bind(this) on the function, yet the data returned is still based on the original component. What am I missing?

Expected: Test2 should print out Test2 on button click

Code:

App.vue

<template>
  <div id="app">
    <img width="25%" src="./assets/logo.png" /><br />
    <Test1 :aFunction="passThis" /> <Test2 :aFunction="dontPassThis" />
  </div>
</template>

<script>
import Test1 from "./components/Test1";
import Test2 from "./components/Test2";

export default {
  name: "App",
  components: {
    Test1,
    Test2
  },
  data() {
    return {
      value: "original"
    };
  },
  methods: {
    dontPassThis($_) {
      console.log(this.value);
    },
    passThis($_) {
      console.log($_.value);
    }
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Test1.vue

<template>
  <div>Test1 <button @click="() => aFunction(this)">click me</button></div>
</template>

<script>
export default {
  data() {
    return {
      value: "Test1"
    };
  },
  mounted() {
    this.aFunction(this);
  },
  props: {
    aFunction: {
      required: true,
      type: Function
    }
  }
};
</script>

Test2.vue

<template>
  <div>
    Test2

    <button @click="testFunction">click me</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      testFunction: null,
      value: "Test2"
    };
  },
  created() {
    this.testFunction = this.aFunction.bind(this);
  },
  props: {
    aFunction: {
      required: true,
      type: Function
    }
  }
};
</script>
tony19
  • 125,647
  • 18
  • 229
  • 307
A. L
  • 11,695
  • 23
  • 85
  • 163
  • `testFunction` is not a property of the exported object. `testFunction` is an object returned from the `data` function within the exported object.. – guest271314 Feb 24 '19 at 17:37
  • @guest271314 for `Test2.vue` I've also tried changing the `@click` to `() => aFunction.bind(this)()`. But it still prints out "original" – A. L Feb 24 '19 at 17:40
  • Have not tried vue.js. Where is the `data` function called? – guest271314 Feb 24 '19 at 17:42
  • @guest271314 that data function just sets up the component so that the variables inside the returned object are accessible via the `this.X` – A. L Feb 24 '19 at 17:44
  • Why are there two different exported objects that have a property with the same name `"data"`? – guest271314 Feb 24 '19 at 17:47
  • @guest271314 what do you mean there are two different exported objects? They're different components. – A. L Feb 24 '19 at 17:58
  • As previously mentioned, have not tried vue.js. Where is `data() { return { testFunction: null, value: "Test2" }; }` executed in the code at the question? – guest271314 Feb 24 '19 at 18:00
  • @guest271314 well I don't really think you can help me then. Just too much to explain on the fundamentals. Thanks for trying though. – A. L Feb 24 '19 at 18:09

1 Answers1

6

Vue already binds the component's methods during initialization, and functions cannot be bound more than once (subsequent binds have no effect).

So when App is initialized, Vue binds the App instance as the context of its dontPassThis method. App "passes" dontPassThis to Test2 via a prop, which Test2 subsequently tries to bind, which actually does nothing.

tony19
  • 125,647
  • 18
  • 229
  • 307