Javascript 如何通过单击主实例中的按钮来显示来自2级子组件的数据?

Javascript 如何通过单击主实例中的按钮来显示来自2级子组件的数据?,javascript,arrays,vue.js,Javascript,Arrays,Vue.js,假设我有一个主实例,一个名为“电影卡”的子组件和另一个名为“链接btn”的“电影卡”子组件。问题是我想构建一个选择器,用v-for循环“link btn”组件,并且我想在主实例中有一个按钮,显示每个“link btn”组件所选的数据。代码如下: HTML: 试验 按钮以显示所选评论 JS: Vue.component('movie-card'{ 道具:[“电影”、“标题”、“描述”、“评论”], 模板:` {{title}} {{description}} {{$data}} `, 数据()

假设我有一个主实例,一个名为“电影卡”的子组件和另一个名为“链接btn”的“电影卡”子组件。问题是我想构建一个选择器,用v-for循环“link btn”组件,并且我想在主实例中有一个按钮,显示每个“link btn”组件所选的数据。代码如下:

HTML:


试验
按钮以显示所选评论
JS:

Vue.component('movie-card'{
道具:[“电影”、“标题”、“描述”、“评论”],
模板:`
{{title}}
{{description}}

{{$data}} `, 数据(){ 返回{ 已选择索引:“”, selectedReview:' } }, 方法:{ 更新i(e){ 如果(e+1==此.selectedIndex){ this.selectedIndex='' }否则{ 此参数。选择的索引=e+1 } }, 更新程序(e){ if(e.id==this.selectedReview.id){ this.selectedReview='' }否则{ this.selectedReview=e } } } }) Vue.组件('link-btn'{ 道具:['index','review'], 模板:` {{review.content} `, 方法:{ 更改(){ this.$emit('updateIndex',this.index) this.$emit('updateReview',this.review) } } }) 新Vue({ el:“#应用程序”, 数据:{ 增加:[], 电影:[ { 标题:“未来的遗憾”, 描述:“这是对未来的描述”, 审查:[ {id:1,内容:'Blabla…',星号:2,活动:false}, {id:2,内容:'Blabla…',星号:3,活动:false}, {id:3,内容:'Blabla…',星号:1,活动:false} ] }, { 标题:“泰坦尼克号”, 描述:“描述泰坦尼克号”, 审查:[ {id:1,内容:'Blabla…',星号:2,活动:false}, {id:2,内容:'Blabla…',星号:3,活动:false}, {id:3,内容:'Blabla…',星号:1,活动:false} ] }, { 标题:“叶片转轮”, 描述:“关于叶片转轮的描述”, 审查:[ {id:1,内容:'Blabla…',星号:2,活动:false}, {id:2,内容:'Blabla…',星号:3,活动:false}, {id:3,内容:'Blabla…',星号:1,活动:false} ] } ] } })
您将希望将所选评论提升到最高层。我在
更新程序
方法中添加了
$emit
,并在
电影卡
标记上添加了一个处理程序,该处理程序调用了一个新方法
更新视图
,该方法填充了
添加的
的相应元素

我只是让它显示添加的
,但您可以让您的按钮显示/隐藏包含添加的
的div

Vue.component('movie-card'{
道具:[“电影”、“标题”、“描述”、“评论”],
模板:`
{{title}}
{{description}}

{{$data}} `, 数据(){ 返回{ 已选择索引:“”, selectedReview:' } }, 方法:{ 更新i(e){ 如果(e+1==此.selectedIndex){ this.selectedIndex='' }否则{ 此参数。选择的索引=e+1 } }, 更新程序(e){ if(e.id==this.selectedReview.id){ this.selectedReview='' }否则{ this.selectedReview=e } 此.emit('update-review',此.selectedReview); } } }) Vue.组件('link-btn'{ 道具:['index','review'], 模板:` {{review.content} `, 方法:{ 更改(){ this.$emit('updateIndex',this.index) this.$emit('updateReview',this.review) } } }) 新Vue({ el:“#应用程序”, 数据:{ 增加:[], 电影:[{ 标题:“未来的遗憾”, 描述:“这是对未来的描述”, 审查:[{ id:1, 内容:“布拉布拉……”, 星星:2, 活动:错误 }, { id:2, 内容:“布拉布拉……”, 星星:3, 活动:错误 }, { id:3, 内容:“布拉布拉……”, 星星:1, 活动:错误 } ] }, { 标题:“泰坦尼克号”, 描述:“描述泰坦尼克号”, 审查:[{ id:1, 内容:“布拉布拉……”, 星星:2, 活动:错误 }, { id:2, 内容:“布拉布拉……”, 星星:3, 活动:错误 }, { id:3, 内容:“布拉布拉……”, 星星:1, 活动:错误 } ] }, { 标题:“叶片转轮”, 描述:“关于叶片转轮的描述”, 审查:[{ id:1, 内容:“布拉布拉……”, 星星:2, 活动:错误 }, { id:2, 内容:“布拉布拉……”, 星星:3, 活动:错误 }, { id:3, 内容:“布拉布拉……”, 星星:1, 活动:错误 } ] } ] }, 方法
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
        <title>Test</title>
    </head>
    <body>
        <div id="app">
            <movie-card
                v-for="(movie, index) in movies"
                key="index"
                :movie="movie"
                :title="movie.title"
                :description="movie.desc"
                :review="movie.review">
            </movie-card>
            <a>BUTTON TO SHOW REVIEWS SELECTED</a>
        </div>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
        <script src="https://unpkg.com/vuex@2.4.0/dist/vuex.js"></script>
        <script src="app.js"></script>
    </body>
</html>
Vue.component('movie-card', {
    props: ['movie', 'title', 'description', 'review'],
    template: `
        <div>
            <h2>{{ title }}</h2>
            <p>{{ description }}</p>
            <link-btn
                v-for="(review, index) in movie.reviews"
                :index="index"
                :review="review"
                key="review"
                @updateIndex="updateI($event)"
                @updateReview="updateR($event)">
            </link-btn>
            <pre>{{ $data }}</pre>
        </div>
    `,
    data() {
        return {
            selectedIndex: '',
            selectedReview: ''
        }
    },
    methods: {
        updateI(e) {
            if(e + 1 === this.selectedIndex) {
                this.selectedIndex = ''
            } else {
                this.selectedIndex = e + 1
            }
        },
        updateR(e) {
            if(e.id === this.selectedReview.id) {
                this.selectedReview = ''
            } else {
                this.selectedReview = e
            }
        }
    }
})

Vue.component('link-btn', {
    props: ['index', 'review'],
    template: `
        <a @click="change">{{ review.content }}</a>
    `,
    methods: {
        change() {
            this.$emit('updateIndex', this.index)
            this.$emit('updateReview', this.review)
        }
    }
})

new Vue({
    el: '#app',
    data: {
        added: [],
        movies: [
            {
                title: 'Regreso al futuro',
                desc: 'Esto es la descripción de Regreso al futuro',
                reviews: [
                    { id: 1, content: 'Blabla...', stars: 2, active: false },
                    { id: 2, content: 'Blabla...', stars: 3, active: false },
                    { id: 3, content: 'Blabla...', stars: 1, active: false }
                ]
            },
            {
                title: 'Titanic',
                desc: 'Esto es la descripción de Titanic',
                reviews: [
                    { id: 1, content: 'Blabla...', stars: 2, active: false },
                    { id: 2, content: 'Blabla...', stars: 3, active: false },
                    { id: 3, content: 'Blabla...', stars: 1, active: false }
                ]
            },
            {
                title: 'Blade Runner',
                desc: 'Esto es la descripción de Blade Runner',
                reviews: [
                    { id: 1, content: 'Blabla...', stars: 2, active: false },
                    { id: 2, content: 'Blabla...', stars: 3, active: false },
                    { id: 3, content: 'Blabla...', stars: 1, active: false }
                ]
            }
        ]
    }
})