javascript - 如何将数据(书籍数组长度)从一个组件传递到 vue.js 中的另一个组件?
问题描述
我正在开发一个页面,该页面负责在 Dashboard(Parent-component) 上显示 Books(child component)。
在 DisplayBooks 组件中,数据来自后端并存储在 books 数组中,基于我正在使用 for 循环进行迭代并显示在我的 UI 页面中,现在我想将 books[] 数组长度传输到 Dashboard 组件并绑定到模板中部分,请帮助我如何实现这件事....
Dashboard.vue
<template>
<div class="main">
<div class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header">
<img src="../assets/education.png" alt="notFound" class="education-image" />
</div>
<ul class="nav navbar-nav">
<li>
<p class="brand">Bookstore</p>
</li>
</ul>
<div class="input-group">
<i @click="handlesubmit();" class="fas fa-search"></i>
<div class="form-outline">
<input type="search" v-model="name" class="form-control" placeholder='search...' />
</div>
</div>
<ul class="nav navbar-nav navbar-right" id="right-bar">
<li><a> <i class="far fa-user"></i></a></li>
<p class="profile-content">profile</p>
<li @click="shownComponent='Cart'"><a><i class="fas fa-cart-plus"></i></a></li>
<p class="cart-content" >cart <span class="length" v-if="booksCount">{{booksCount}}</span></p>
</ul>
</div>
<div class="mid-body">
<!-- here i want to display books array length -->
<h6>Books<span class="items">({{books.lengthh}})</span></h6>
<select class="options" @change="applyOption">
<option disabled value="">Sort by relevance</option>
<option value="HighToLow">price:High to Low</option>
<option value="LowToHigh">price:Low to High</option>
</select>
</div>
<div v-if="flam==false">
<h2>Hello</h2>
</div>
<DisplayBooks v-show="flag==='noOrder' && shownComponent==='DisplayBooks'" @update-books-count="(n)=>booksCount=n"/>
<Cart v-show=" shownComponent==='Cart'" />
<sortBooksLowtoHigh v-show="flag==='lowToHigh'" @update-books-count="(n)=>booksCount=n" />
<sortBooksHightoLow v-show="flag==='highToLow'" @update-books-count="(n)=>booksCount=n" />
</div>
</template>
<script>
import sortBooksLowtoHigh from './sortBooksLowtoHigh.vue'
import sortBooksHightoLow from './sortBooksHightoLow.vue'
import DisplayBooks from './DisplayBooks.vue'
import Cart from './Cart.vue'
export default {
components: {
DisplayBooks,
sortBooksLowtoHigh,
sortBooksHightoLow,
Cart
},
data() {
return {
shownComponent:'DisplayBooks',
booksCount:0,
flag: 'noOrder',
brand: 'Bookstore',
name: '',
flam: true,
visible: true,
}
},
methods: {
flip() {
this.flam = !this.flam;
},
applyOption(evt) {
if (evt.target.value === "HighToLow") {
this.flag = 'highToLow';
} else this.flag = 'lowToHigh';
},
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/Dashboard.scss";
</style>
DisplayBooks.vue
<template>
<div class="carddisplay-section">
<div v-for="book in books" :key="book.id" class="card book" @mouseover="book.hover = true"
@mouseleave="book.hover = false">
<div class="image-section">
<div class="image-container">
<img v-bind:src="book.file" />
</div>
</div>
<div class="title-section">
{{book.name}}
</div>
<div class="author-section">
by {{book.author}}
</div>
<div class="price-section">
Rs. {{book.price}}<label class="default">(2000)</label>
</div>
<div class="buttons">
<div class="button-groups" v-if="!addedBooks.includes(book.id)">
<button type="submit" @click="handleCart(book.id);toggle(book.id);addedBooks.push(book.id)" class="AddBag">Add to Bag</button>
<button class="wishlist">wishlist</button>
</div>
<div class="AddedBag" v-else>
<button class="big-btn" @click="removeFromCart(book.id);addedBooks=addedBooks.filter(id=>id!==book.id)">Added to Bag</button>
</div>
</div>
<div class="description" v-if="book.hover">
<p class="hovered-heading">BookDetails</p>
{{book.description}}
</div>
</div>
</div>
</template>
<script>
import service from '../service/User'
export default {
mounted() {
service.userDisplayBooks().then(response => {
let data = response.data;
data.map(function(obj) {
obj.hover = false;
return obj;
});
this.books.push(...data);
return response;
})
},
data() {
return {
isActive:true,
result: 0,
authorPrefix: 'by',
pricePrefix: 'Rs.',
defaultStrikePrice: '(2000)',
buttonValue: 'Add to Bag',
buttonWishlist:'wishlist',
buttonAddedBag:'Added to Bag',
flag: true,
state: true,
addedBooks:[],
clickedCard: '',
books: [] //this length i want to transfer
}
},
watch:{
addedBooks:{
handler(val){
this.$emit('update-books-count',val.length)
},
deep:true
}
},
methods: {
toggleClass: function(event){
this.isActive = !this.isActive;
return event;
},
toggle(id) {
this.clickedCard = id;
console.log(this.clickedCard);
},
flip() {
this.state = !this.state;
},
Togglebtn() {
this.flag = !this.flag;
},
handleCart(bookId){
let userData={
id: bookId,
}
service.userUpdateCart(userData).then(response=>{
return response;
}).catch(error=>{
alert("error while displaying Books");
return error;
})
},
removeFromCart(bookId){
let userData={
id:bookId,
}
service.userRemoveFromCart(userData).then(response=>{
return response;
}).catch(error=>{
alert("error while removing from cart");
return error;
})
}
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/DisplayBooks.scss";
</style>
解决方案
可以使用双向绑定来解决从子节点到父节点的数据绑定问题。
如果您使用 Vue 2,请使用“.sync”。我推荐下面的链接。
https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier
例子:
家长
...
<DisplayBooks v-show="flag==='noOrder' && shownComponent==='DisplayBooks'" @update-books-count="(n)=>booksCount=n" :count.sync="booksCount"/>
...
...
watch:{
booksCount(newCount){
console.log(this.booksCount)
}
...
孩子
...
props: ['count']
...
...
mounted() {
service.userDisplayBooks().then(response => {
let data = response.data;
data.map(function(obj) {
obj.hover = false;
return obj;
});
this.books.push(...data);
this.$emit('update:count', this.books.length)
return response;
})
},
...
推荐阅读
- node.js - Nodejs - 在多个文件之间异步创建的共享变量
- reactjs - next-images 和 next-videos 无法正常工作
- kubernetes - skaffold 是否尊重滚动更新?
- database - 从 SQl 开发人员连接 DBaaS 时出错。能够从腻子连接
- angular - 当文本区域的值为空字符串时将其设置为空?
- javascript - 在 WeakMap 中设置项目是否会修改密钥本身?
- javascript - React Native:为什么组件引用未定义?
- python - 总 .npz 文件的大小比单个元素大得多
- javascript - Javascript检测窗口内的点击区域并关闭元素
- java - 从 for(Particle p:particle) 循环中的 ArrayList 中删除元素