首页 > 解决方案 > 在不同路由上使用具有不同值的相同类型数据时的 Vuex 状态结构和获取

问题描述

我正在创建一个带有 vue、vuex 和 vue-router 的作品集,它将显示图像。

在主页上,我将显示带有“show_home:true”的图像。

然后是“标签”页面(portfolio/:tagSlug),它将显示基于 slug 的图像,例如。带有无限滚动的“婚礼”(自动填充分页)。

图像对象看起来像:

{
   id: 1,
   title: 'Lorem..',
   path: '..',
   show_home: true
   tags: [ {id: 1, slug: 'weddings'} ]

},
{
   id: 2,
   title: 'Lorem2..',
   path: '..',
   show_home: false
   tags: [ {id: 1, slug: 'weddings'}, {id: 2, slug: 'water'} ]

}

端点示例:

Homepage: GET: ../images/homepage?p=1 
Tag page: GET: ../images/:slug?p=1

我不知道我应该如何在 vuex 中构造它并处理获取..

我应该只创建一个“图像:[]”状态并在从每个路由中的 api 获取它们之后用所有图像填充它,然后用 getter 过滤它们吗?在那种情况下,我怎样才能在那里获得分页?或者你有更好的解决方案吗?

提前致谢

标签: vue.jsvuexvue-router

解决方案


我首选的方法是“扁平化”关系并根据需要拉动它们。这也允许您仅从服务器或相关模块中提取您需要的内容。

标签 vuex 模块:

all: {
  1: {  <-- indexed by tag id
    name: "weddings"
    images: [1,2,3,4] <-- image ids
   }
  }
active: false  <-- When there is an active tag, this becomes the id of the tag.

vuex 图像模块将遵循相同的模式:

 all: {
  1: {  <-- indexed by image id
    title: 'Lorem..',
    path: '..',
    show_home: true
    tags: [1,2,3,4] <-- tag ids
   }
  }
active: false  <-- When there is an active image, this becomes the id of the image.

然后使用 getter 对来自各个 vuex 模块的图像或标签进行水合。
在这个博客上有一篇关于这种方法的精彩文章:https ://medium.com/js-dojo/structuring-vuex-modules-for-relationships-speed-and-durability-de25f7403643

使用这种方法,您将有越来越少的 api 调用,分页是可管理的,您无需担心关系中的陈旧数据。

已编辑——API 信息:

我想到了两种方法。1)始终加载带有标签的图像。

标签索引请求不会加载任何图像,只是每个标签的基本信息。

当用户点击一个标签时,这会启动一个 API 调用来获取标签的详细信息:

标签显示请求(tags/1 或 tags/weddings)将返回带有加载关系的标签:

public function show($id)
{
    $tag = Tag::where('id', $id)->with('images')->firstOrFail();
    return new TagResource($tag);  <-- will have all related images loaded. 
}

2) 如果需要,设置一个嵌套的 REST 端点

您可以使用资源控制器来简化样板,如下所示:

api.php

Route::apiResource('tags.images', 'tags\TagImageController');

此路由将监视您的 api 调用并确定它是否为 index/store/show/delete。从您的前端,您可以拨打https://backendsite.com/tags/1/images之类的电话 (如果婚礼标签的 id 为 1)

然后在 TagImageController 你会有这样的东西:

public function index(Request $request, $id)
{
    $tag = MemTag::find($id);
    $images = $tag->images()->get();
    $images->load(Image::allowedIncludes); <- or you can manually list relationships you want to load

    return ImageResource::collection($images);
}

推荐阅读