使用Vuex存储中的参数在启动时获取组件中的数据

时间:2018-02-11 14:24:03

标签: vue.js vuejs2 vue-component vuex

我是Vue的新手,正在尝试构建一个简单的电影应用,从API获取数据并呈现结果。我想要一个增量搜索功能。我的导航栏中有一个输入字段,当用户输入时,我想从仪表板视图重定向到搜索结果视图。我不确定如何将查询参数从导航栏传递到搜索结果视图。

这是我的App.vue组件



<template>
  <div id="app">
    <Navbar></Navbar>
    <router-view/>
  </div>
</template>

<script>
import Navbar from './components/Navbar.vue'
export default {
  name: 'App',
  components: {
    Navbar
  },
}
</script>
&#13;
&#13;
&#13;

这是我的导航栏组件,我有输入字段

&#13;
&#13;
<template>
  <nav class="navbar">
    <h1 class="logo" v-on:click="goToHome">Movie App</h1>
    <input class="search-input" v-on:keyup="showResults" v-model="query" type="text" placeholder="Search..."/>
  </nav>
</template>

<script>
import router from '../router/index'
export default {
  data: function () {
    return {
      query: this.query
    }
  },
  methods: {
    goToHome () {
      router.push({name: 'Dashboard'})
    },
    showResults () {
      //here on each key press I want to narrow my results in the SearchedMovies component
    }
  }
}
</script>
&#13;
&#13;
&#13;

如果我将router.push用于SearchedMovies组件,那么我只能将查询作为参数传递一次。我想过使用Vuex来存储查询,然后从SearchedMovies组件访问它,但是肯定有更好的方法吗?

我还阅读了有关使用$emit的内容,但由于我的父母包含了所有路线,因此我不确定该怎么做。

1 个答案:

答案 0 :(得分:1)

您无需在任何地方重定向用户。我做了一个小型演示,展示了如何做到这一点。我按照你的描述使用了这个导航栏组件并从中发出了一个事件:

&#13;
&#13;
const movies = {
  data: [
    {
      id: 0,
      title: 'Eraserhead',
    },
    {
      id: 1,
      title: 'Erazerhead',
    },
    {
      id: 2,
      title: 'Videodrome',
    },
    {
      id: 3,
      title: 'Videobrome',
    },
    {
      id: 4,
      title: 'Cube',
    },
  ]
};

Vue.component('navbar', {
  template: '<input v-model="filter" @input="onInput" placeholder="search">',
  data() {
    return {
      filter: '',
    };
  },
  methods: {
    onInput() {
      this.$emit('filter', this.filter);
    }
  }
});

// this is just a request imitation. 
// just waiting for a second until we get a response
// from the datasample
function request(title) {
  return new Promise((fulfill) => {
    toReturn = movies.data.filter(movie => movie.title.toLowerCase().indexOf(title.toLowerCase()) !== -1)
    setTimeout(() => fulfill(toReturn), 1000);
  });
}


new Vue({
  el: '#app',
  data: {
    movies: undefined,
    loading: false,
    filter: '',
    lastValue: '',
  },
  methods: {
    filterList(payload) {
      // a timeout to prevent 
      // instant request on every input interaction
      this.lastValue = payload;
      setTimeout(() => this.makeRequest(), 1000);
    },
    makeRequest() {
      if (this.loading) {
        return;
      }
      this.loading = true;
      request(this.lastValue).then((response) => {
        this.movies = response;
        this.loading = false;
      });
    }
  },
  mounted() {
    this.makeRequest('');
  }
})
&#13;
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <navbar v-on:filter="filterList"></navbar>
  <ul v-if="!loading">
    <li v-for="movie in movies" :key="movie.id">{{ movie.title }}</li>
  </ul>
  <p v-else>Loading...</p>
</div>
&#13;
&#13;
&#13;

还有jsfiddle:https://jsfiddle.net/oniondomes/rsyys3rp/

如果您有任何问题需要了解上述代码,请告诉我。

编辑:修正了一些错误并添加了几条评论

EDIT2(在下面的评论之后):

这是你可以做的。每当用户在导航栏中输入内容时,您都会调用一个函数:

// template
<navbar v-on:input-inside-nav-bar="atInputInsideNavBar"></navbar>

// script
methods: {
    atInputInsideNavBar(userInput) {
        this.$router.push({
            path: '/filtred-items',
            params: {
                value: userInput
            }
        })
    }
}

然后在你里面搜索电影&#39;页面组件,您可以访问此值:

this.$route.params.value // returns userInput from root component