简体   繁体   中英

Linking a text field in a child component to a parent component's props in VueJS

I have a child component sending data via an event to a parent component in VueJS. From the parent component, I am routing the data (or trying to route the data...) to a sibling of the child and create new components with the data sent from the child.

I use a dictionary to group the data for various reasons, then push the dictionary into an array. A v-for loop loops thru the array and populates the previously mentioned new components with data found in that array. I probably don't need to do it this way, but that's how I'm doing it. I am open to alternatives.

Anyway, it doesn't work great. So far I'm only able to get one of the three strings I need to show up where I want it to. I'll explain more after I post the code.

Already tried:

A dozen different versions of the code, including creating a simple v-for in a list to do the job, and various versions with/without a dictionary or array.

In my research for the problem I've gone through the VueJS docs, Googled a few things, and found nothing.

In App.vue (I tried to remove all the irrelevant stuff):

<template>
    <div id="app">
        <img alt="Vue logo" src="./assets/logo.png">

        <TweetDeck v-on:messageFromTweetDeck="msgReceived($event)"/>

        <!-- <ul>
            <li v-for="(tweet, index) in tweets" :key="index">{{ tweet }}</li>
        </ul>-->

        <TwitterMsg v-for="(tweet, index) in tweets" :key="index" 
        :name="tweet.name" :handle="tweet.handle" tsp=3 :msg="tweet.tweet" />

        <TwitterMsg name="aaa" handle='aaa'
        tsp=50 msg="hey this is a message on twitter"/>


        <input type="text" v-model="placeholderText"/>

    </div>
</template>

<script>
import TwitterMsg from './components/TwitterMsg.vue'
import TweetDeck from './components/TweetDeck.vue'

export default {
    name: 'app',
    components: {
        TwitterMsg,
        TweetDeck

    },

    data: function() {
        return {
            tweets: [],
            message: "",
            placeholderText: ""
        }
    },

    methods: {
        msgReceived(theTweet, name, handle) {
            this.tweets.push({tweet: theTweet, name: name, handle: handle})
        }
    }
}
</script>

And in TweetDeck.vue:

<template>
    <div>
        <input type='text' v-model="yourName">
        <input type='text' v-model="yourHandle">
        <input type='text' v-model="yourTweet"/>
        <button type='button' @click="sendTweet()">Tweet</button>
    </div>
</template>

<script>
    export default {
        name: "TweetDeck",

    data: function() {
        return {
            yourName: "Your name here",
            yourHandle: "Your twitter handle",
            yourTweet: "What's going on?"
        }
    },

    methods: {
        sendTweet() {
            this.$emit('messageFromTweetDeck', this.yourTweet, this.yourName, this.yourHandle);

        }
    }
}

</script>

You can also see the mostly unimportant TwitterMsg.vue here (I am trying to copy Twitter for learning purposes:

<template>
    <div>
        <h4>{{ name }}</h4>
        <span>@{{ handle }}</span>
        <span> {{ tsp }}</span> <!-- Time Since Posting = tsp -->
        <span>{{ msg }}</span>
        <img src='../assets/twit_reply.png'/><span>1</span>
        <img src="../assets/twit_retweet.png"/><span>2</span>
        <img src="../assets/twit_fave.png"/><span>3</span>

    </div>
</template>

<script>
    export default {
        name: "TwitterMsg",
        props: {
            name: String,
            handle: String,
            tsp: String,
            msg: String
        }
    }
</script>

<style>
    img {
        width: 30px;
        height: 30px;
    }
</style>

Expected result: The code populates a new TwitterMsg component with appropriate name, handle and message data each time I click the "Tweet" button.

Actual results: My code fails to help the name and handle strings make it from the input text box in TweetDeck.vue all the way to their home in TwitterMsg.vue.

I will say that this.yourTweet in TweetDeck.vue DOES manage to make it all the way to its destination, which is good -- though it makes me wonder why the other two pieces of data didn't follow suite.

Totally lost. Also just in my first month of VueJS so it's pretty good that I can even make one string appear where I want it to. \o/

First, you need to remove the $event parameter

<TweetDeck v-on:messageFromTweetDeck="msgReceived"/>

Second, you can optimize the data format passed to the parent component:

sendTweet() {
  this.$emit("messageFromTweetDeck",
    { tweet: this.yourTweet, name: this.yourName, handle: this.yourHandle }
  );
}

And then modify your msgReceived method:

msgReceived(childData) {
  this.tweets.push(childData);
}

Link: codesandbox

Hope to help you:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM