vuejs2 - 是否可以同步在同一页面上多次显示的Vuejs组件?

标签 vuejs2 vue-component laravel-blade

我有一个显示项目的网页。对于每个项目,都有一个按钮(vuejs组件),该按钮使用户可以将该项目切换(添加/删除)到他的收藏中。

这是组件:

<template lang="html">
        <button type="button" @click="toggle" name="button" class="btn" :class="{'btn-danger': dAdded, 'btn-primary': !dAdded}">{{ dText }}</button>
    </template>

<script>
export default {
    props: {
        added: Boolean,
        text: String,
        id: Number,
    },
    data() {
        return {
            dAdded: this.added,
            dText: this.text,
            dId: this.id
        }
    },
    watch: {
        added: function(newVal, oldVal) { // watch it
            this.dAdded = this.added
        },
        text: function(newVal, oldVal) { // watch it
            this.dText = this.text
        },
        id: function(newVal, oldVal) { // watch it
            this.dId = this.id
        }
    },
    methods: {
        toggle: function(event) {
            axios.post(route('frontend.user.profile.pop.toggle', {
                    pop_id: this.dId
                }))
                .then(response => {
                    this.dText = response.data.message
                    let success = response.data.success
                    this.dText = response.data.new_text
                    if (success) {
                        this.dAdded = success.attached.length
                        let cardPop = document.getElementById('card-pop-'+this.dId);
                        if(cardPop)
                            cardPop.classList.toggle('owned')
                    }
                })
                .catch(e => {
                    console.log(e)
                })
        }
    }
}
</script>

对于每个项目,用户还可以打开一个模式,通过单击此链接来加载该模式:
<a href="#" data-toggle="modal" data-target="#popModal" @click="id = {{$pop->id}}">
    <figure>
        <img class="card-img-top" src="{{ URL::asset($pop->img_path) }}" alt="Card image cap">
    </figure>
</a>

模态也是Vuejs组件:
<template>
    <section id="pop" class="h-100">
        <div class="card">
            <div class="container-fluid">
                <div class="row">

                    <div class="col-12 col-lg-1 flex-column others d-none d-xl-block">
                        <div class="row flex-column h-100">

                            <div v-for="other_pop in pop.other_pops" class="col">
                                <a :href="route('frontend.pop.collection.detail', {collection: pop.collection.slug, pop: other_pop.slug})">
                                        <img :src="other_pop.img_path" :alt="'{{ other_pop.name }}'" class="img-fluid">
                                    </a>
                            </div>

                            <div class="col active order-3">
                                <img :src="pop.img_path" :alt="pop.name" class="img-fluid">
                            </div>

                        </div>
                    </div>

                    <div class="col-12 col-lg-6 content text-center">
                        <div class="row">
                            <div class="col-12">
                                <img :src="pop.img_path" :alt="pop.name" class="img-fluid">
                            </div>

                            <div class="col-6 text-right">
                                <toggle-pop :id="pop.id" :added="pop.in_user_collection" :text="pop.in_user_collection ? 'Supprimer' : 'Ajouter'"></toggle-pop>
                            </div>
                            <div class="col-6 text-left">
                                <!-- <btnaddpopwhishlist :pop_id="propid" :added="pop.in_user_whishlist" :text="pop.in_user_whishlist ? 'Supprimer' : 'Ajouter'"></btnaddpopwhishlist> -->
                            </div>
                        </div>


                    </div>
                    <div class="col-12 col-lg-5 infos">
                        <div class="header">
                            <h1 class="h-100">{{ pop.name }}</h1>
                        </div>
                        <div class="card yellow">
                            <div class="card p-0">
                                <div class="container-fluid">
                                    <div class="row">
                                        <div class="col-3 py-2">

                                        </div>
                                        <div class="col-6 py-2 bg-lightgray">
                                            <h4>Collection:</h4>
                                            <h3>{{ pop.collection ? pop.collection.name : '' }}</h3>
                                        </div>
                                        <div class="col-3 py-2 bg-lightgray text-center">
                                            <a :href="route('frontend.index') + 'collections/' + pop.collection.slug" class="btn-round right white"></a>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
</template>

<script>
export default {
    props: {
        id: Number
    },
    data() {
        return {
            pop: {
                collection: {

                }
            }
        }
    },
    ready: function() {
        if (this.propid != -1)
            this.fetchData()
    },
    watch: {
        id: function(newVal, oldVal) { // watch it
            // console.log('Prop changed: ', newVal, ' | was: ', oldVal)
            this.fetchData()
        }
    },
    computed: {
        imgSrc: function() {
            if (this.pop.img_path)
                return 'storage/images/pops/' + this.pop.img_path
            else
                return ''
        }
    },
    methods: {
        fetchData() {
            axios.get(route('frontend.api.v1.pops.show', this.id))
                .then(response => {
                    // JSON responses are automatically parsed.
                    // console.log(response.data.data.collection)
                    this.pop = response.data.data
                })
                .catch(e => {
                    this.errors.push(e)
                })
            // console.log('fetchData')
        }
    }
}
</script>

这是我的app.js脚本:
window.Vue = require('vue');

Vue.component('pop-modal', require('./components/PopModal.vue'));
Vue.component('toggle-pop', require('./components/TogglePop.vue'));

const app = new Vue({
    el: '#app',
    props: {
        id: Number
    }
});

我想同步名为toggle-pop的组件的状态,如何实现呢?一个是由Blade模板(laravel)呈现的,另一个是由pop-modal组件呈现的。但是它们是相同的,显示在不同的位置。

谢谢。

最佳答案

您可以将状态对象作为属性传递给toggle-pop组件。他们可以使用此属性来存储/修改其状态。这样,您可以使多组组件共享状态。

您的组件可能变为:

<template lang="html">
  <button type="button" @click="toggle" name="button" class="btn" :class="{'btn-danger': sstate.added, 'btn-primary': !sstate.added}">{{ sstate.text }}</button>
</template>

<script>
export default {
  props: {
    sstate: {
      type: Object,
      default: function() {
        return { added: false, text: "", id: -1 };
      }
    }
  },
  data() {
    return {};
  },
  methods: {
    toggle: function(event) {
      axios.post(route('frontend.user.profile.pop.toggle', {
        pop_id: this.sstate.id
      }))
        .then(response => {
            this.sstate.text = response.data.message
            let success = response.data.success
            this.sstate.text = response.data.new_text
            if (success) {
                this.sstate.ddded = success.attached.length
                let cardPop = document.getElementById('card-pop-'+this.sstate.id);
                if(cardPop)
                    cardPop.classList.toggle('owned')
            }
        })
        .catch(e => {
          console.log(e)
        })
  }
};
</script>

现场演示

https://codesandbox.io/s/vq8r33o1w7

关于vuejs2 - 是否可以同步在同一页面上多次显示的Vuejs组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49740422/

相关文章:

php - 可能的?将 Blade 模板分配给变量

vue.js - 使用 Jest 测试时未定义全局节点配置变量

javascript - Vue.js 转换 : animate height while using slide out animation

vue.js - 带有选择选项的 V-IF 和 V-for 循环条件似乎永远不会进入 v-else 语句

vue.js - Vue 循环 Blade Laravel 内的多个 if 条件

css - 如何将样式表仅应用于 laravel 表单中的特定选择框?

javascript - 单击时激活 v-for 循环内的项目

vuejs2 - Vuex 过滤状态

vuejs2 - 为什么 v-bind 是单向数据绑定(bind),而 v-for 可以更新 vue.js 中子组件的数据?

javascript - vuetify v-select 具有多个选项 - 获取选择/取消选择选项