首页 > 解决方案 > vuejs中组件之间的通信。(搜索字段)

问题描述

好吧,我是 vue js 的新手,并且正在开发具有搜索功能的应用程序。

这是我将呈现搜索结果的组件。

<script>
import RecipeItem from "../recipe/RecipeItem";
import { baseApiUrl } from "@/global";
import axios from "axios";
import PageTitle from "../template/PageTitle";

export default {
  name: "Search",
  components: { PageTitle, RecipeItem },
  data() {
    return {
      recipes: [],
      recipe: {},
      search: '', 
    }
  },
  methods: {
    getRecipes() {
      const url = `${baseApiUrl}/search?search=${this.search}`;
      axios(url).then((res) => {
        this.recipes = res.data;
      });
    }
  },
  watch: {
    search() {
      const route = {
        name: 'searchRecipes'
      }
      if(this.search !== '') {
        route.query = {
          search: this.search
        }
      }
    },
    '$route.query.search': {
      immediate: true,
      handler(value) {
        this.search = value
      }
    }
  },
};
</script>
<template>
  <div class="recipes-by-category">
    <form class="search">
      <router-link :to="{ path: '/search', query: { search: search }}">
      <input  v-model="search" @keyup.enter="getRecipes()" placeholder="Search recipe" />
      <button type="submit">
        <font-icon class="icon" :icon="['fas', 'search']"></font-icon>
      </button>
      </router-link>
    </form>
    <div class="result-search">  
      <ul>
        <li v-for="(recipe, i) in recipes" :key="i">
          <RecipeItem :recipe="recipe" />
        </li>
      </ul>
    </div>
  </div>
</template>

好的,到目前为止它做了它应该做的,搜索并在屏幕上打印结果。但正如您所看到的,我在其中创建了搜索字段,我想将其从搜索结果组件中取出并将其插入到我的标题组件中,这样更有意义。但我无法使用标题组件中的搜索字段在搜索结果组件中呈现结果。

但我无法使用标题组件中的搜索字段在搜索结果组件中呈现结果。

标头组件

<template>
  <header class="header">
    
    <form class="search">
      <input  v-model="search" @keyup.enter="getRecipes()" placeholder="Search recipe" />
      <router-link :to="{ path: '/search', query: { search: this.search }}">
      <button type="submit">
        <font-icon class="icon" :icon="['fas', 'search']"></font-icon>
      </button>
      </router-link>
    </form>
    
    <div class="menu">
      <ul class="menu-links">
        <div class="item-home">
          <li><router-link to="/">Home</router-link></li>
        </div>
        <div class="item-recipe">
          <li>
            <router-link to="/"
              >Recipes
              <font-icon class="icon" :icon="['fa', 'chevron-down']"></font-icon>
            </router-link>
            <Dropdown class="mega-menu" title="Recipes" />
          </li>
        </div>
        <div class="item-login">
          <li>
            <router-link to="/auth" v-if="hideUserDropdown">Login</router-link>
            <Userdropdown class="user" v-if="!hideUserDropdown" />
          </li>
        </div>
      </ul>
    </div>
  </header>
</template>

结果组件

<template>
  <div class="recipes-by-category">
    <div class="result-search">  
      <ul>
        <li v-for="(recipe, i) in recipes" :key="i">
          <RecipeItem :recipe="recipe" />
        </li>
      </ul>
    </div>
  </div>
</template>

标签: javascriptvue.jsaxios

解决方案


将状态变量保存在标题组件和结果组件共有的任何父组件中。例如,如果您有一个Layout类似这样的组件:

<!-- this is the layout component -->
<template>
  <HeaderWithSearch v-on:newResults="someFuncToUpdateState" />
  <ResultsComponent v-bind:results="resultsState" />
</template>
<!-- state and function to update state are in a script here... -->

当搜索栏返回结果时,您需要通过$emit调用将该数据“向上”传递给父组件,然后父组件可以使用 normal 将该状态向下传递回结果组件props

查看此文档:https ://vuejs.org/v2/guide/components-custom-events.html

请务必特别注意.sync文档的部分内容,并确定您是否也需要实施这些内容。

除非您想使用像 vuex 这样更复杂的状态管理库(在这种情况下不需要),否则您可以将状态保留在一个共同的父级中并用于$emit传递和props传递。


推荐阅读