Vue 2 pass props to child [old : “call child's

2019-08-26 01:07发布

问题:

ok so I've learned that I'm not supposed to call a child's method but pass it props instead.

I've got (parent) :

<template>
  <div id="main">
    <Header :title ="title"/>
    <router-view/>
    <LateralMenu/>
  </div>
</template>
<script>
  export default {
    name: 'app'
    data: function () {
      return {
        title: true
      }
    },
    methods: {
      hideTitle: function () {
        this.title = false
        console.log(this.title)
      },
      showTitle: function () {
        this.title = true
        console.log(this.title)
      }
    }
  }
</script>

and (child) :

<script>
  export default {
    name: 'Header',
    props: ['title'],
    created () {
      console.log(this.title)
    },
    methods: {
    }
  }
</script>

the first console logs (inside the parent) print correctly on each method but the second console log within the child stays true all the time. I got this from : Pass data from parent to child component in vue.js

inside what method does the console.log need to be to be printed everytime the methods in the parent are triggered?

(this is why I wanted to go for method-calling, originally, by going with variables instead, we're potentially omitting valuable parts of the process such as optimization and a "when" for the execution(s!!) of our code. pontetally being the key word here, don't blow up on me, keep in mind that I'm learning.)

OLD:

I've browsed the web and I know there a a million different answers and my point is with the latest version of vue none of those millions of answers work.

either everything is deprecated or it just doesn't apply but I need a solution.

How do you call a child method?

I have a 1 component = 1 file setup.

DOM is declared inside a <template> tag javascript is written inside a <script> tag. I'm going off of vue-cli scaffolding.

latest method I've tried is @emit (sometimes paired with an @on sometimes not) doesn't work :

child :

<script>
  export default {
    name: 'Header',
    created () {
      this.$on('hideTitlefinal', this.hideTitlefinal)
    },
    methods: {

      hideTitlefinal: function () {
        console.log('hideeeee')
      },
      showTitlefinal: function () {
        console.log('shwowwww')
      }
    }
  }
</script>

parent :

<template>
  <div id="main">
    <Header v-on:hideTitle="hideTitlefinal" v-on:showTitle="showTitlefinal"/>
    <router-view/>
    <LateralMenu/>
  </div>
</template>

<script>
  export default {
    methods: {
      hideTitle: function () {
        this.$emit('hideTitle')
      },
      showTitle: function () {
        this.$emit('showTitle')
      }
    }
  }
</script>

console :

Uncaught TypeError: this.$emit is not a function
    at Object.showTitle (Main.vue?1785:74)
    at VueComponent.showTitle (LateralMenu.vue?c2ae:113)
    at boundFn (vue.esm.js?efeb:186)
    at invoker (vue.esm.js?efeb:1943)
    at HTMLDivElement.fn._withTask.fn._withTask (vue.esm.js?efeb:1778)

回答1:

Please don't do this. You're thinking in terms of events. When x happens, do y. That's sooo jquery 2005 man. Vue still has all that stuff, but we're being invited to think in terms of a view model...

You want your state in a variable, in window scope, and you want reactive pipes linking your vue stuff to your state object. To toggle visibility, use a dynamic class binding, or v-if. Then think about how to represent your state. It could be as simple as having a property like store.titleVisible. But, you want to 'normalize' your store, and avoid relationships between items of state. So if title visibility really depends on something higher up, like an editMode or something, then just put the higher-up thing in the store, then create computed properties if you need them.

The goal is that you don't care when things happen. You just define the relationships between the markup and the store, then let Vue take care of it. The docs will tell you to use props for parent=>child and $emit for child=>parent communication. Truth is you don't need this until you have multiple instances of a component, or reusable components. Vue stuff talks to a store, not to other vue stuff. For single-use components, as for your root Vue, just use the data:.

Whenever you find yourself writing show/hide methods, you're doing it wrong. It's intuitive (because it's procedural), but you'll quickly appreciate how much better the MVVM approach is.