Javascript 两个子组件使用vue.js将数据传递给同一父组件
我现在使用的是一个api旅行数据,我想用分页来显示它,同时用首选的排序方法来显示数据。我试图将所有内容分为三个部分:Javascript 两个子组件使用vue.js将数据传递给同一父组件,javascript,vue.js,parent-child,emit,Javascript,Vue.js,Parent Child,Emit,我现在使用的是一个api旅行数据,我想用分页来显示它,同时用首选的排序方法来显示数据。我试图将所有内容分为三个部分: 分页--用于页面的按钮 sortbar——用于对移动数据进行排序 视图——根据上面的两个组件显示相应的数据。例如第10页,按降价排序 我要做的是将1和2组件放在第三个组件中,这意味着1和2都是3的子组件,一旦子组件中的道具发生了变化(pageNumber和sort),将它们传递给父组件,并使用$watch执行函数,一旦检测到数据pageNumber和sort的变化,就请求API
{{index+1}}
导出默认值{
名称:“分页”,
道具:{
页码:{
类型:数字,
}
},
方法:{
重置页面(索引){
this.pageNumber=索引+1;
console.log(this.pageNumber)
//使用“update:“props name””发出更新事件,并传递更改值。
this.emit('update:pageNumber',this.pageNumber')//子元件與父元件雙向綁定
},
下一页(){
this.pageNumber=this.pageNumber+1;
this.emit('update:pageNumber',this.pageNumber');
},
上一页(){
this.pageNumber=this.pageNumber-1;
this.emit('update:pageNumber',this.pageNumber');
},
}
};
-
-
导出默认值{
名称:“sortbar”,
道具:{
排序:{
类型:字符串,
}
},
数据(){
返回{
价格排序:“低->高”,
分级排序:“”
}
},
方法:{
价格说明{
this.sort='price_desc';
this.pricesort='high->low'
this.ratingsort=“”
//使用“update:“props name””发出更新事件,并传递更改值。
this.emit('update:sort',this.sort');
},
价格(asc){
this.sort='price_asc';
this.pricesort='high->low'
this.ratingsort=“”
this.emit('update:sort',this.sort');
},
评级描述(){
this.sort='rating_desc';
this.ratingsort='high->low'
this.pricesort=''
this.emit('update:sort',this.sort');
},
评级(asc){
this.sort='rating\u asc'
this.ratingsort='low->high'
this.pricesort=''
this.emit('update:sort',this.sort');
},
}
};
{{pageNumber}}
{{sort}}
{{item.agency}{{item.rating | rating}}
{{item.title}
{{tag}}
{{option.date | date}}({{option.date | day})
可售{{option.quantity}}位
{{item.tour\u days}
天
{{item.min_price}currency}
元起
从“axios”导入axios;
从“/Pagination”导入分页
从“/Sortbar”导入Sortbar
导出默认值{
名称:“groupdata”,
组成部分:{
分页
},
数据(){
返回{
孤岛加载:false,
数据:[],
排序:'price_desc',
页码:1
}
},
//?
<template>
<div class="pagination">
<div class="pagination-row">
<!-- previous page button -->
<button class="btn btn-light" @click = "previouspage"> < </button>
<!-- pagination button -->
<span v-for= "(item, index) in new Array(10)" :key="index">
<button class="btn btn-light" @click = "resetpage(index)">{{ index+1 }}</button>
</span>
<!-- next page button -->
<button class="btn btn-light" @click = "nextpage"> > </button>
</div>
</div>
</template>
<script>
export default {
name: "pagination",
props: {
pageNumber:{
type: Number,
}
},
methods: {
resetpage(index) {
this.pageNumber = index + 1;
console.log(this.pageNumber)
//use 'update:"props-name"' to emit a update event, and pass the change value.
this.$emit('update:pageNumber', this.pageNumber); //子元件與父元件雙向綁定
},
nextpage() {
this.pageNumber = this.pageNumber + 1;
this.$emit('update:pageNumber', this.pageNumber);
},
previouspage() {
this.pageNumber = this.pageNumber - 1;
this.$emit('update:pageNumber', this.pageNumber);
},
}
};
</script>
<template>
<div class="sortbar">
<nav class="navbar navbar-expand navbar-light bg-light" style="width:100%; margin: auto;">
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
price:{{ pricesort }}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item btn" @click="price_desc" href="#">low->high</a>
<a class="dropdown-item btn" @click="price_asc" href="#">high->low</a>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
評分:{{ratingsort}}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item btn" @click="rating_desc" href="#">high->low</a>
<a class="dropdown-item btn" @click="rating_asc" href="#">low->high</a>
</div>
</li>
</ul>
</div>
</nav>
</div>
</template>
<script>
export default {
name: "sortbar",
props: {
sort: {
type: String,
}
},
data() {
return{
pricesort: 'low->high',
ratingsort: ''
}
},
methods: {
price_desc(){
this.sort = 'price_desc';
this.pricesort = 'high->low'
this.ratingsort = ''
//use 'update:"props-name"' to emit a update event, and pass the change value.
this.$emit('update:sort', this.sort);
},
price_asc(){
this.sort = 'price_asc';
this.pricesort = 'high->low'
this.ratingsort = ''
this.$emit('update:sort', this.sort);
},
rating_desc(){
this.sort = 'rating_desc';
this.ratingsort = 'high->low'
this.pricesort = ''
this.$emit('update:sort', this.sort);
},
rating_asc(){
this.sort = 'rating_asc'
this.ratingsort = 'low->high'
this.pricesort = ''
this.$emit('update:sort', this.sort);
},
}
};
</script>
<template>
<div class="groupdata">
<!-- use `.sync` decorator to declare the counter is a two way binding props. -->
<Sortbar :sort.sync="sort"></Sortbar>
<Pagination :pageNumber.sync="pageNumber"></Pagination>
{{ pageNumber }}
{{ sort }}
<div class="container">
<div v-for = "(item, index) in data" :key="index">
<div class = "cards">
<div class = 'img' style="width: 25%; height: 100%">
<img :src="item.image_url" style="width:100%;
height:100%;
object-fit:cover; ">
</div>
<div class='info' style="width: 75%; margin: auto;">
<h5 class = 'agency'>
{{ item.agency }} {{ item.rating | rating }}
</h5>
<h5 class = 'title'>
{{ item.title }}
</h5>
<div style="display: flex; padding-left: 20px;">
<div v-for = "(tag, index) in item.tags" :key="index">
<button class='tags'>{{ tag }}</button>
</div>
</div>
<hr style="margin: 5px 0px;">
<div class='timeandnum'>
<div style="width: 75%; display: flex; align-items: center;">
<div v-for = "(option, index) in item.group" :key="index" style="margin-right: 10px;">
<p class='date'>{{ option.date | date }} ( {{ option.date | day}} )</p>
<button class='num'> 可售{{ option.quantity }}位</button>
</div>
</div>
<div style="width: 25%; margin-left: 20px;">
<p style="color:rgb(253, 163, 60); font-size: 1.8em; display: inline; font-weight: bold;">{{ item.tour_days }}</p>
<p style="font-size: 1em; display: inline;">天</p>
<p style="color:rgb(253, 163, 60); font-size: 1.8em; display: inline; font-weight: bold;">{{ item.min_price | currency }}</p>
<p style="font-size: 1em; display: inline;">元起</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<loading :active.sync="isloading"></loading>
</div>
</div>
</template>
<script>
import axios from "axios";
import Pagination from "./Pagination"
import Sortbar from "./Sortbar"
export default {
name: "groupdata",
components: {
Pagination, Sortbar
},
data() {
return {
isloading: false,
data: [],
sort: 'price_desc',
pageNumber: 1
}
},
//用watch監聽pageNumber這個data被更新的時候執行function
watch: {
pageNumber: function(){
this.getdata(this.pageNumber,10, this.sort)
},
sort: function(){
this.getdata(1,10, this.sort)
}
},
created() {
this.getdata(this.pageNumber,10, this.sort);
},
methods: {
async getdata(page,rpp,sort) {
try{
this.data = [];
this.isloading = true;
let tourdata = await axios
.get(`http://interview.tripresso.com/tour/search?page=${page}&row_per_page=${rpp}&sort=${sort}`)
this.data = tourdata.data.data.tour_list;
} catch (error) {
console.log(error);
} finally {
setTimeout(() => {
this.isloading = false
},500)
};
},
updateSort(val) {
this.sort = val;
}
}
};
</script>