带有路由器的 Vue 模态
Posted
技术标签:
【中文标题】带有路由器的 Vue 模态【英文标题】:Vue modal with a router 【发布时间】:2020-12-03 10:10:09 【问题描述】:我是 Vue 的新手。我正在构建一个简单的应用程序,它将列出所有国家/地区,当您单击特定国家/地区时,它会向您显示有关该国家/地区的更多详细信息。想法是在模态中打开country details
。
我坚持显示该模式。模式打开,但在后台。它还会打开一个详细信息页面。
CountryDetail.vue
:
<script>
import axios from 'axios';
export default
name: 'country-detail',
props: [ 'isDarkTheme' ],
data ()
return
pending: false,
error: null,
countryInfo: null,
alpha3Code: [],
alpha3CodetoString: [],
,
mounted ()
this.pending = true;
axios
.get(`https://restcountries.eu/rest/v2/name/$this.$route.params.country?fullText=true`)
.then((response) =>
(this.countryInfo = response.data)
this.alpha3CodetoString = this.alpha3Code.join(';');
)
.catch(error => (this.error = error ))
.finally( () => this.pending = false );
,
filters:
formatNumbers (value)
return `$value.toLocaleString()`
</script>
<template>
<modal v-model="show">
<div class="modal-mask" :class=" darkTheme : isDarkTheme " name="modal">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
<h1 v-if="error !== null">Sorry, an error has occurred error</h1>
<div class="loaderFlex"><div v-if="pending" class="loader"></div></div>
</slot>
</div>
<div v-for="country in countryInfo" class="countryTile modal-body" v-bind:key="country.id">
<slot name="body">
<img v-bind:src="country.flag" class="flag">
<div class="country-details">
<h1>country.name</h1>
<div class="listDiv">
<ul>
<li><span>Population:</span> country.population | formatNumbers </li>
<li><span>Capital:</span> country.capital</li>
<li><span>Iso:</span> country.alpha3Code</li>
</ul>
<ul>
<li><span>Currencies:</span> country.currencies['0'].name</li>
<li><span>Languages:</span>
<span
v-for="(language, index) in country.languages"
v-bind:key="index"
class="languages">
language.name<span v-if="index + 1 < country.languages.length">, </span>
</span>
</li>
</ul>
</div>
</div>
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
<a @click="$router.go(-1)" class="backBtn"><i class="fas fa-arrow-left" />Go Back</a>
</slot>
</div>
</div>
</div>
</div>
</modal>
</template>
Home.vue
:
<script>
import axios from 'axios';
export default
name: 'home',
props: [ 'isDarkTheme' ],
data ()
return
pending: false,
error: null,
countryInfo: null,
search: '',
darkMode: false,
,
mounted ()
this.pending = true;
axios
.get('https://restcountries.eu/rest/v2/all')
.then(response => (this.countryInfo = response.data))
.catch(error => (this.error = error ))
.finally( () => this.pending = false );
,
filters:
formatNumbers (value)
return `$value.toLocaleString()`
,
computed:
filteredCountries: function ()
return this.countryInfo.filter((country) =>
if (this.region === '' )
return country.name.toLowerCase().match(this.search.toLowerCase());
else if (this.search !== '')
return country.name.toLowerCase().match(this.search.toLowerCase());
else
return ('blbla');
)
,
</script>
<template>
<div class="home" :class=" darkTheme : isDarkTheme ">
<div class="searchBar">
<div class="searchContainer">
<i class="fas fa-search searchIcon"></i>
<input
class="searchInput"
type="text"
v-model="search"
aria-label="Search for a country..."
placeholder="Search for a country..."
/>
<ul class="searchResults"></ul>
</div>
</div>
<h1 v-if="error !== null">Sorry, an error has occurred error</h1>
<div class="loaderFlex"><div v-if="pending" class="loader"></div></div>
<div v-if="countryInfo" class="tileGrid" @click="showModal = true">
<div v-for="country in filteredCountries" class="countryTile" v-bind:key="country.id">
<router-link
:to=" name: 'country-detail', params: country: country.name "
class="linkTile"
>
<img v-bind:src="country.flag" class="flag">
<div class="text">
<h1> country.name </h1>
</div>
</router-link>
</div>
</div>
</div>
</template>
【问题讨论】:
【参考方案1】:路由器链接将始终将您重定向到另一个页面,因为它基本上是<a href="...">
see here。如果您只想在模态上显示细节,则不需要路由器,您只需在 Home.vue 组件中添加模态组件,然后将模态和countryName
与道具绑定,然后在单击按钮时传递它们。
Home.vue
:
<template>
<div>
<button @click="showDetail">
Show Detail
</button>
<CountryDetail :countryName="countryName" :showModal="showModal"/>
<div>
</template>
<script>
import CountryDetail from './CountryDetail.vue'
export default
name: 'Home',
components: CountryDetail ,
data: () => (
countryName: '',
showModal: false,
),
methods:
showDetail()
this.showModal = true;
,
,
</script>
而不是在mounted
上发出请求,您可以使用watch
来做一些事情,比如监视showModal
属性,并在每次它具有真实值时发出请求。像这样:
CountryDetail.vue
:
<template>
<modal v-model="showModal">
<!-- modal content -->
</modal>
</template>
<script>
export default
name: 'CountryDetail',
props: ['countryName', 'showModal'],
watch:
'showModal':
deep: true,
handler(val)
if (val && this.countryName !== '')
// Make request
</script>
【讨论】:
以上是关于带有路由器的 Vue 模态的主要内容,如果未能解决你的问题,请参考以下文章
带有 vue 2 组件的 vue 路由器不适用于 laravel 5.8