本应用旨在提供一个简洁易用的界面,用户可以在其中搜索和过滤电影,基于类型、评分等条件进行筛选,并查看电影详细信息。
该代码使用 Vue.js 框架和一系列 UI 组件构建,包括:
1. 安装依赖项
首先,安装必要的依赖项:
npm install vue vue-router vuex echarts echarts-for-vue @wangeditor/editor-for-vue v-calendar vue3-baidu-map-gl
2. 构建 Vuex 存储
Vuex 存储用于管理应用状态,包括搜索查询、过滤器和搜索结果:
const store = new Vuex.Store({
state: {
search: "",
genre: "All",
rating: "All",
results: [],
},
mutations: {
setSearch(state, payload) {
state.search = payload;
},
setGenre(state, payload) {
state.genre = payload;
},
setRating(state, payload) {
state.rating = payload;
},
setResults(state, payload) {
state.results = payload;
},
},
actions: {
searchMovies({ commit }, payload) {
// 这里可以调用 API 获取实际的搜索结果
const results = [
{
id: 1,
image: "https://source.unsplash.com/random/200x200",
title: "The Shawshank Redemption",
price: "$10.99",
},
{
id: 2,
image: "https://source.unsplash.com/random/200x200",
title: "The Godfather",
price: "$12.99",
},
{
id: 3,
image: "https://source.unsplash.com/random/200x200",
title: "The Dark Knight",
price: "$14.99",
},
{
id: 4,
image: "https://source.unsplash.com/random/200x200",
title: "12 Angry Men",
price: "$16.99",
},
];
commit("setResults", results);
},
},
});
3. 构建 Vue 组件
搜索栏组件:
<template>
<div class="flex items-center justify-between px-4 py-2 border-b border-gray-200">
<van-search v-model="search" placeholder="Search" class="w-full" />
<van-icon name="magnifying-glass" class="text-gray-500" />
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const search = ref("");
return { search };
},
};
</script>
下拉菜单组件:
<template>
<van-dropdown-menu
v-model="value"
:options="options"
placeholder="Placeholder"
class="w-full"
/>
</template>
<script>
import { ref } from "vue";
export default {
props: {
value: {
type: String,
default: "All",
},
options: {
type: Array,
required: true,
},
placeholder: {
type: String,
default: "All",
},
},
setup(props) {
return {
value: props.value,
options: props.options,
placeholder: props.placeholder,
};
},
};
</script>
卡片组件:
<template>
<van-card
:thumb="thumb"
:title="title"
:price="price"
/>
</template>
<script>
export default {
props: {
thumb: {
type: String,
default: "",
},
title: {
type: String,
default: "",
},
price: {
type: String,
default: "",
},
},
};
</script>
4. 构建主应用组件
主应用组件负责组合其他组件并处理搜索和过滤逻辑:
<template>
<div class="bg-gray-100">
<van-nav-bar
title="Search"
left-arrow
fixed
:border="false"
class="bg-white"
/>
<search-bar @search="onSearch" />
<div
class="flex items-center justify-between px-4 py-2 border-b border-gray-200"
>
<genre-dropdown-menu
v-model="genre"
:options="genreOptions"
placeholder="Genre: All"
class="w-full"
/>
<rating-dropdown-menu
v-model="rating"
:options="ratingOptions"
placeholder="Rating: All"
class="w-full"
/>
</div>
<div class="flex flex-wrap justify-center px-4 py-2">
<card
v-for="item in results"
:key="item.id"
:thumb="item.image"
:title="item.title"
:price="item.price"
/>
</div>
</div>
</template>
<script>
import SearchBar from "./SearchBar.vue";
import GenreDropdownMenu from "./GenreDropdownMenu.vue";
import RatingDropdownMenu from "./RatingDropdownMenu.vue";
import Card from "./Card.vue";
import { ref } from "vue";
import { mapActions } from "vuex";
export default {
components: { SearchBar, GenreDropdownMenu, RatingDropdownMenu, Card },
setup() {
const genre = ref("All");
const rating = ref("All");
const results = ref([]);
const genreOptions = ["All", "Action", "Comedy", "Drama", "Horror", "Romance"];
const ratingOptions = ["All", "1", "2", "3", "4", "5"];
const { searchMovies } = mapActions(["searchMovies"]);
const onSearch = (searchQuery) => {
searchMovies({ searchQuery, genre, rating });
};
return {
genre,
rating,
results,
genreOptions,
ratingOptions,
onSearch,
};
},
};
</script>
开发经验与收获:
未来拓展与优化: