동일한 페이지에 여러 번 표시된 Vuejs 구성 요소를 동기화할 수 있는가?
나는 항목을 표시하는 웹 페이지를 가지고 있다.각 항목에 대해 버튼(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
, 내가 어떻게 이것을 성취할 수 있는가?하나는 블레이드 템플릿(래블)으로 렌더링되고 다른 하나는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
모든 성분의 상태가 항상 동일해야 한다고 100% 확신할 경우 정의하지 않도록 선택할 수 있다.data
함수로서그냥 물건이라고 선언해.
data: {
dAdded: this.added,
dText: this.text,
dId: this.id
}
https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function,에서 언급한다.
구성 요소의 데이터 옵션은 각 인스턴스가 반환된 데이터 개체의 독립 복사본을 유지할 수 있도록 함수가 되어야 함
Vue에 이 규칙이 없는 경우 버튼 하나를 클릭하면 다른 모든 인스턴스의 데이터에 영향을 미침
모든 데이터를 동기화하려면toggle-pop
구성 요소 인스턴스(instance)를 따를 필요 없음data option must be a function
통치를 하다
'Programing' 카테고리의 다른 글
기본 외부 스타일시트 반응 (0) | 2022.03.12 |
---|---|
Vue Js - v-for X time(범위 내)을 통한 루프 (0) | 2022.03.12 |
여러 키를 구별할 때까지 KeyChanged와 비교하는 방법? (0) | 2022.03.11 |
React.createElement: 유형이 잘못됨 - 문자열 필요 (0) | 2022.03.11 |
Vue 구성 요소: 라우터 링크 또는 href 속성을 동적으로 사용 (0) | 2022.03.11 |