使用 Vue 访问嵌套的 JSON
Posted
技术标签:
【中文标题】使用 Vue 访问嵌套的 JSON【英文标题】:Accessing nested JSON with Vue 【发布时间】:2019-01-24 16:51:26 【问题描述】:我正在尝试使用 Vue 访问数组中的嵌套 JSON 进行基本搜索。每所学校都包装在一个“命中”数组中,因此它认为只有一个“命中”结果,而不是返回每所学校的数据。我确定我只需要为每个学校实例添加命中,但我不确定如何。感谢您的帮助。
我的主应用文件:
<template>
<div class="app search">
<!-- Search header -->
<header id="searchHeader" class="search--header py-2 py-md-4">
<div class="container">
<div class="input-group">
<!-- Type filter -->
<TypeFilter v-model="type"/>
<!-- Location filter -->
<!--<LocationFilter />-->
<!-- Search box -->
<SearchBox v-model="searchTerm"/>
<!-- More filters -->
<!--<div class="dropdown checkbox-dropdown mx-2">
<button class="btn btn-lg btn-white py-3 px-4 dropdown-toggle" type="button" id="dropdownMenuButtonFilters" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">More Filters</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButtonFilters">
</div>
</div>-->
<!-- Search button -->
<button v-on:click="searchSubmit(searchTerm)" class="btn btn-lg btn-white ml-2 px-4 search-submit">Search</button>
</div>
<!-- Active filters (hidden for v0) -->
<!--<div class="search--header--filters mt-3">
<span class="badge">Filter</span>
<span class="badge">Filter</span>
<span class="badge">Filter</span>
</div>-->
</div>
</header>
<!-- Main results -->
<div class="container">
message
<!-- Result count and show/sort -->
<ResultCount v-model="page" :items="schools.length" :perPage="10"/>
<!-- Results -->
<SchoolList :schools="pageOfSchools"/>
<!-- Pagination -->
<Pagination v-model="page" :items="schools.length" :perPage="10"/>
</div>
</div>
</template>
<script>
import SchoolList from './SchoolList'
import ResultCount from './ResultCount'
import Pagination from './Pagination'
import SearchBox from './SearchBox'
import TypeFilter from "./TypeFilter";
import LocationFilter from "./LocationFilter";
import getArraySection from '../utilities/get-array-section'
//import schools as schoolData from '../data'
export default
name: 'app',
components: SchoolList, ResultCount, Pagination, SearchBox, TypeFilter, LocationFilter,
data: () => (
searchTerm: '',
type: '',
//schools: [],
schools: [
"hit": [
"title": "State Peter Pan Institute",
,
"title": "State Flatland University",
,
"title": "State Applewood Halls of Ivy",
]
],
page: 1,
message: ''
),
computed:
pageOfSchools: function ()
return getArraySection(this.schools, this.page, 10)
,
watch:
/*searchTerm: function ()
this.filterSchools()
,
type: function ()
this.filterSchools()
*/
,
methods:
filterSchools: function ()
const searchTerm = this.searchTerm.toLowerCase()
const type = this.type
let result = schoolData
if (searchTerm)
result = result.filter(school =>
return (
school.title.toLowerCase().search(searchTerm) >= 0 ||
school.location.toLowerCase().search(searchTerm) >= 0
)
)
if (type)
result = result.filter(school => school.type.indexOf(type) >= 0)
this.schools = result
this.page = 1
,
created: function ()
this.filterSchools()
</script>
我的 SchoolList 组件:
<template>
<Transition name="swap" mode="out-in">
<div class="school-list" :key="schools">
<div class="row">
<div class="col-md-8 search--results">
<School class="school row justify-content-between search--results--card my-2 pt-2 pb-3 border-bottom" v-for="school in schools" :item="school" :key="school"/>
</div>
<div class="col-md-4 mt-4 pl-md-6 search--results--featured">
<FeaturedList />
</div>
</div>
</div>
</Transition>
</template>
<script>
import School from './School'
import FeaturedList from './FeaturedList'
export default
name: 'school-list',
components: School, FeaturedList,
props: ['schools']
</script>
<style scoped>
.swap-enter-active, .swap-leave-active
transition: opacity 0.2s ease-in-out;
.swap-enter, .swap-leave-active
opacity: 0;
.swap-enter
opacity: 1;
.swap-leave-to
opacity: 0;
</style>
我的学校组件:
<template>
<div>
<div class="col-9 col-md-auto d-flex align-items-center card-body">
<img v-bind:src="item.logo" class="logo mr-2 mr-md-4 p-2 bg-white rounded-circle">
<div>
<h5 class="mb-0"><a :href="item.url" class="text-dark"> item.title </a></h5>
<p class="mb-0"> item.location </p>
<TypeLabel class="badge type-label mt-2" v-for="type in item.type" :type="type" :key="type"/>
<span class="badge badge-yellow mt-2">Featured</span>
</div>
</div>
<div class="col-3 col-md-auto text-right">
<button type="button" class="btn btn-link d-inline-flex px-2 save"><i></i></button>
<button type="button" class="btn btn-link d-inline-flex px-2 share"><i></i></button>
<a data-placement="top" data-toggle="popoverMoreInfo" data-title="Get More Info" data-container="body" data-html="true" href="#" id="login" class="btn btn-outline-light d-none d-md-inline-block ml-3">Get More Info</a>
<!-- Get More Info Popover -->
<div id="popover-content" class="d-none more-info">
<form>
<div class="form-group mb-2 has-float-label">
<input class="form-control" id="your-name" type="text" placeholder="Your name"
aria-label="Your name" aria-describedby="your-name"/>
<label for="your-name">Your name</label>
</div>
<div class="form-group mb-2 has-float-label">
<input class="form-control" id="your-email" type="email" placeholder="Your email"
aria-label="Your email" aria-describedby="your-email"/>
<label for="your-email">Your email</label>
</div>
<div class="form-group mb-2 has-float-label">
<input class="form-control" id="your-phone" type="tel" placeholder="Your phone"
aria-label="Your phone" aria-describedby="your-phone"/>
<label for="your-phone">Your phone</label>
</div>
<button type="submit" class="btn btn-primary w-100">Request More Info</button>
</form>
</div>
</div>
</div>
</template>
<script>
import TypeLabel from './TypeLabel'
let parser = document.createElement('a')
export default
name: 'school',
props: ['item'],
components: TypeLabel,
methods:
domainOf: url => ((parser.href = url), parser.hostname.replace(/^www\./, ''))
</script>
【问题讨论】:
【参考方案1】:要访问每所学校的名称,您应该像这样访问它:
const hit = this.schools[0].hit;
然后你迭代属性命中
hit.forEach(function(el)
console.log(el.title);
);
为此,您可能应该将计算属性中的属性学校展平,以便以后更容易访问。
要声明扁平化变量,可以在计算属性中声明它:
computed:
// other properties ...
flattenedSchools: function ()
const schools = [];
if (this.schools && this.schools.length)
// up to you to check if hit exist and has values
this.schools[0].hit.forEach(function(el)
schools.push((el.title);
);
return schools;
,
,
要访问 flattenedSchools,只需使用 this.flattenedSchools 并对其进行迭代。
【讨论】:
感谢您的帮助。我在哪里定义常量?抱歉,我是 Vue.js 的新手。以上是关于使用 Vue 访问嵌套的 JSON的主要内容,如果未能解决你的问题,请参考以下文章