Vue.js 2+ Webpack, V-Model Связывает и загружает данные из router.params с необязательным значением по умолчанию - PullRequest
0 голосов
/ 14 января 2019

V-модель Связывает и загружает данные из router.params с необязательным значением по умолчанию, не работающим Vue.js 2

У меня есть 4 выбора и 1 ввод текста

в моем методе data () я возвращаю массив со значениями по умолчанию для элементов опции selects.

я хочу, чтобы компонент загружался, чтобы получить значения из URL (router.params), а затем выбрать правильное значение из select, а также отобразить текстовый ввод (передаваемый через параметры маршрутизатора) обратно в текстовое поле [ окно поиска]

Я пробовал двухстороннее связывание, одностороннее связывание, обновление jquery с использованием функции setTimeout, но положительных результатов по-прежнему нет

Я с нетерпением жду ваших ответов и советов, спасибо.

маршруты

import Vue from 'vue'
import Router from 'vue-router'
import HomeScreen from '@/components/HomeScreen'
import MangaSearch from '@/components/MangaSearch'
import MangaView from '@/components/MangaView'
import MangaHeaderMenuComponent from '@/components/reusable/MainMenuComponent'
import MangaSearchComponent from '@/components/reusable/MangaSearchComponent'
import MangaPopularComponent from '@/components/reusable/MangaPopularComponent'
import MangaResultsComponent from '@/components/reusable/MangaResultsComponent'

Vue.component('manga-header-menu', MangaHeaderMenuComponent)
Vue.component('manga-search', MangaSearchComponent)
Vue.component('manga-popular', MangaPopularComponent)
Vue.component('manga-results', MangaResultsComponent)

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HomeScreen',
      component: HomeScreen
    },
    {
      path: '/search',
      name: 'MangaSearch',
      component: MangaSearch
    },
    {
      path: '/manga/view',
      name: 'MangaView',
      component: MangaView
    },
  ]
})

код ниже:

    <template>
    <div class="search-container">
         <div class="search-form-container">
            <input type="text" v-on:keypress.enter="search" id="q" col="10" placeholder="Search Here" />
        </div>
        <div class="search-filter-container">
            <div><select id="search-genre" class="search-filter-field">
                    <option :disabled="true" :selected="true">Genre</option>
                    <option v-for="genre in genres" v-bind:value="genre"> {{ genre }}</option>
            </select></div>
            <div><select id="search-date" class="search-filter-field">
                    <option :disabled="true" :selected="true">Date</option>
                    <option v-for="date in dates" v-bind:value="date"> {{ date }}</option>
            </select></div>
            <div><select id="search-rating" class="search-filter-field">
                    <option :disabled="true" :selected="true">Rating</option>
                    <option v-for="rating in ratings" v-bind:value="rating"> {{ rating }}</option>
            </select></div>
            <div><select id="search-language" class="search-filter-field">
                    <option :disabled="true" :selected="true">Language</option>
                    <option v-for="language in languages" v-bind:value="language"> {{ language }}</option>
            </select></div>
    </div>
</div>
</template>

<script>
export default {
    data (){
        return {
            /* Filter Options */
            /* - Genre List*/
            genres: [ 'All', 'Action', '' ],
            /* - Date/Time Frame List*/
            dates: [ 'All', 'Last Month', 'Last Year'],
            /* - Ratings List*/
            ratings: [ 'All','0', '1', '2', '3', '4', '5' ],
            /* - Language List*/
            languages: [ 'All', 'Afrikaans','Albanian','Amharic','Arabic','Bahasa','Bengali','Bosnian','Bravanese','Bulgarian','Catalan','Chinese (Simplified)','Chinese (Trad–HK)','Chinese (Traditional)','Croatian','Czech','Danish','Dutch','Estonian','Euro English','Farsi','Finnish','French (Belgian)','French (Canadian)','French (Euro)','German','Greek','Gujarati','Haitian Creole','Hebrew','Hindi','Hmong','Hungarian','Icelandic','Italian','Japanese','Javanese','Kashmiri','Kazakh','Khmer','Korean','Laotian','Latvian','Lithuanian','Macedonian','Malay','Malayalam','Mandinka','Marathi','Norwegian','Oromo','Polish','Portuguese','Punjabi','Romanian','Russian','Serbian','Sinhalese','Slovak','Somali','Spanish (Iberian)','Spanish (Latin)','Sudanese Arabic','Swedish','Tagalog','Tamil','Telegu','Thai','Turkish','Ukrainian','Urdu','Vietnamese' ],

            /* Local Storage For Filter Values */
            name: (this.$route.params.name ? this.$route.params.name : ''),
            genre: (this.$route.params.genre ? this.$route.params.genre : 'Genre'),
            date: (this.$route.params.date ? this.$route.params.date : 'Date'),
            rating: (this.$route.params.rating ? this.$route.params.rating : 'Rating'),
            language: (this.$route.params.language ? this.$route.params.language : 'Language')
        };
        return data;
    },
    methods: {
        search (){
            this.$router.push({
                path: 'search',
                query: {
                    name: $('#q').val(),
                    genre: $('#search-genre').val(),
                    date: $('#search-date').val(),
                    rating: $('#search-rating').val(),
                    language: $('#search-language').val()
                }
            });
        }
    },
}
</script>

Ответы [ 4 ]

0 голосов
/ 14 января 2019

рабочий скрипт, спасибо ребята !!!

<template>
    <div class="search-container">
        <div class="search-form-container">
            <input v-model="filter.name" type="text" @change="search" id="q" col="10" placeholder="Search Here" />
       </div>
    <div class="search-filter-container">
            <div><select @change="search" v-model="filter.genre" id="search-genre" class="search-filter-field">
                    <option :disabled="true" :selected="true">Genre</option>
                    <option v-for="genre in genres" v-bind:value="genre"> {{ genre }}</option>
            </select></div>
            <div><select @change="search" v-model="filter.date" id="search-date" class="search-filter-field">
                    <option :disabled="true" :selected="true">Date</option>
                    <option v-for="date in dates" v-bind:value="date"> {{ date }}</option>
            </select></div>
            <div><select @change="search" v-model="filter.rating" id="search-rating" class="search-filter-field">
                    <option :disabled="true" :selected="true">Rating</option>
                    <option v-for="rating in ratings" v-bind:value="rating"> {{ rating }}</option>
            </select></div>
            <div><select @change="search" v-model="filter.language" id="search-language" class="search-filter-field">
                    <option :disabled="true" :selected="true">Language</option>
                    <option v-for="language in languages" v-bind:value="language"> {{ language }}</option>
            </select></div>
    </div>
</div>
</template>

<script>
export default {
    data (){
        return {
            genres: [ 'All', 'Action', '' ],
            dates: [ 'All', 'Last Month', 'Last Year'],
            ratings: [ 'All','0', '1', '2', '3', '4', '5' ],
            languages: [ 'All', 'Afrikaans','Albanian','Amharic','Arabic','Bahasa','Bengali','Bosnian','Bravanese','Bulgarian','Catalan','Chinese (Simplified)','Chinese (Trad–HK)','Chinese (Traditional)','Croatian','Czech','Danish','Dutch','Estonian','Euro English','Farsi','Finnish','French (Belgian)','French (Canadian)','French (Euro)','German','Greek','Gujarati','Haitian Creole','Hebrew','Hindi','Hmong','Hungarian','Icelandic','Italian','Japanese','Javanese','Kashmiri','Kazakh','Khmer','Korean','Laotian','Latvian','Lithuanian','Macedonian','Malay','Malayalam','Mandinka','Marathi','Norwegian','Oromo','Polish','Portuguese','Punjabi','Romanian','Russian','Serbian','Sinhalese','Slovak','Somali','Spanish (Iberian)','Spanish (Latin)','Sudanese Arabic','Swedish','Tagalog','Tamil','Telegu','Thai','Turkish','Ukrainian','Urdu','Vietnamese' ],


            /* Local Storage For Filter Values */
            filter: {
                    name: this.$route.query.name ? this.$route.query.name : "",
              genre: this.$route.query.genre ? this.$route.query.genre : "Genre",
              date: this.$route.query.date ? this.$route.query.date : "Date",
              rating: this.$route.query.rating ? this.$route.query.rating : "Rating",
              language: this.$route.query.language ? this.$route.query.language : "Language"
            }
        };
        return data;
    },
    watch: {
      '$route'(to) {
        if (to.name === 'MangaSearch') {
                    filter.name = to.query.name ? to.query.name : "",
                    filter.genre = to.query.genre ? to.query.genre : "Genre",
                    filter.date = to.query.date ? to.query.date : "Date",
                    filter.rating = to.query.rating ? to.query.rating : "Rating",
                    filter.language = to.query.language  ? to.query.language : "Language"
        }
      },
    },
    created() {
                filter.name = this.$route.query.name ? this.$route.query.name : "",
                filter.genre = this.$route.query.genre ? this.$route.query.genre : "Genre",
                filter.date = this.$route.query.date ? this.$route.query.date : "Date",
                filter.rating = this.$route.query.rating ? this.$route.query.rating : "Rating",
                filter.language = this.$route.query.language ? this.$route.query.language : "Language"
    },
    methods: {
    search() {
      this.$router.replace({
        path: "/search",
        query: this.filter
      });
    }
  }
}
</script>
0 голосов
/ 14 января 2019

Проблема в том, что вы пытаетесь получить доступ к параметрам запроса из атрибута params. Параметры запроса находятся в атрибуте query, а не в params. Вы можете использовать двухстороннее связывание и предварительно выбрать правильное значение следующим образом.

    <select :v-model="genre" id="search-genre" class="search-filter-field">
      <option :disabled="true" :selected="true">Genre</option>
      <option v-for="g in genres" v-bind:value="g"> {{ g }}</option>
    </select>

А в данных

genre: this.$route.query.genre,
0 голосов
/ 14 января 2019

У вас есть многочисленные проблемы с этим кодом:

  1. Вы не используете реактивность Вью.
  2. Вы прочитали маршрут params, но перенаправили с помощью query (это работает, но может вызвать проблемы в будущем, если вы измените маршрут params )
  3. Вы не назначаете параметры, выбранные из маршрута, для полей формы.

Сначала добавьте filter: {} к data (в нем будут храниться текущие поля фильтра) и обновим его при изменении маршрута:

  export default {
    data() {
      return {
        // filter options omitted for better readability
        // ...
        filter: {},
      };
    },
    watch: {
      '$route'(to) {
        if (to.name === 'MangaSearch') {
          this.filter = Object.assign({}, to.query);
        }
      },
    },
    created() {
      this.filter = Object.assign({}, this.$route.query);
    },
    methods: {
      search() {
        this.$router.push({
          path: '/search',
          query: this.filter
        });
      }
    },
  }

Далее, давайте свяжем поля формы с этим фильтром, используя v-model:

<div class="search-form-container">
    <input type="text" v-model="filter.name" @keypress.enter="search" id="q" col="10" placeholder="Search Here" />
</div>
<div class="search-filter-container">
    <div><select v-model="filter.genre" id="search-genre" class="search-filter-field">
        <option disabled>Genre</option>
        <option v-for="genre in genres" :value="genre">{{ genre }}</option>
    </select></div>
    <div><select v-model="filter.date" id="search-date" class="search-filter-field">
        <option disabled>Date</option>
        <option v-for="date in dates" :value="date">{{ date }}</option>
    </select></div>
    <div><select v-model="filter.rating" id="search-rating" class="search-filter-field">
        <option disabled>Rating</option>
        <option v-for="rating in ratings" :value="rating">{{ rating }}</option>
    </select></div>
    <div><select v-model="filter.language" id="search-language" class="search-filter-field">
        <option disabled>Language</option>
        <option v-for="language in languages" :value="language">{{ language }}</option>
    </select></div>
</div>

Вот и все. Вам даже больше не нужен jQuery.

0 голосов
/ 14 января 2019

Ваша проблема не в использовании реактивности Vue. Здесь есть несколько вещей, которые нужно обновить:

  • Заменить jQuery на свойства данных Vue
  • Добавьте v-model в поля формы
  • Используйте router.replace вместо router.push (избегает реакции браузера вперед / назад на изменения поиска)

const Search = {
  template: "#search",
  data() {
    return {
      /* Filter Options */
      /* - Genre List*/
      genres: ["All", "Action", ""],
      /* - Date/Time Frame List*/
      dates: ["All", "Last Month", "Last Year"],
      /* - Ratings List*/
      ratings: ["All", "0", "1", "2", "3", "4", "5"],
      /* - Language List*/
      languages: [
        "All",
        "Afrikaans",
        "Albanian",
        "Amharic",
        "Arabic",
        "Bahasa",
        "Bengali",
        "Bosnian",
        "Bravanese",
        "Bulgarian",
        "Catalan",
        "Chinese (Simplified)",
        "Chinese (Trad–HK)",
        "Chinese (Traditional)",
        "Croatian",
        "Czech",
        "Danish",
        "Dutch",
        "Estonian",
        "Euro English",
        "Farsi",
        "Finnish",
        "French (Belgian)",
        "French (Canadian)",
        "French (Euro)",
        "German",
        "Greek",
        "Gujarati",
        "Haitian Creole",
        "Hebrew",
        "Hindi",
        "Hmong",
        "Hungarian",
        "Icelandic",
        "Italian",
        "Japanese",
        "Javanese",
        "Kashmiri",
        "Kazakh",
        "Khmer",
        "Korean",
        "Laotian",
        "Latvian",
        "Lithuanian",
        "Macedonian",
        "Malay",
        "Malayalam",
        "Mandinka",
        "Marathi",
        "Norwegian",
        "Oromo",
        "Polish",
        "Portuguese",
        "Punjabi",
        "Romanian",
        "Russian",
        "Serbian",
        "Sinhalese",
        "Slovak",
        "Somali",
        "Spanish (Iberian)",
        "Spanish (Latin)",
        "Sudanese Arabic",
        "Swedish",
        "Tagalog",
        "Tamil",
        "Telegu",
        "Thai",
        "Turkish",
        "Ukrainian",
        "Urdu",
        "Vietnamese"
      ],

      /* Local Storage For Filter Values */
      name: this.$route.params.name ? this.$route.params.name : "",
      genre: this.$route.params.genre ? this.$route.params.genre : "Genre",
      date: this.$route.params.date ? this.$route.params.date : "Date",
      rating: this.$route.params.rating ? this.$route.params.rating : "Rating",
      language: this.$route.params.language
        ? this.$route.params.language
        : "Language"
    };
  },
  methods: {
    search() {
      this.$router.replace({
        path: "/search",
        query: {
          name: this.name,
          genre: this.genre,
          date: this.date,
          rating: this.rating,
          language: this.language
        }
      });
    }
  }
};

const router = new VueRouter({
  routes: [
  	{
    	path: '/',
      redirect: '/search'
    },
    {
      path: "/search",
      component: Search
    }
  ]
});

new Vue({
  el: "#app",
  router
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.2/vue-router.js"></script>

<div id="app">
  #App
  <router-view />
</div>

<template id="search">
  <div class="search-container">
    <div class="search-form-container">
      <input v-model="name" type="text" v-on:keypress.enter="search" id="q" col="10" placeholder="Search Here" />
    </div>
    <div class="search-filter-container">
      <div>
        <select @change="search" id="search-genre" class="search-filter-field">
          <option :disabled="true" :selected="true">Genre</option>
          <option v-for="genre in genres" v-bind:value="genre"> {{ genre }}</option>
      </select>
    </div>
      <div>
        <select @change="search" id="search-date" class="search-filter-field">
          <option :disabled="true" :selected="true">Date</option>
          <option v-for="date in dates" v-bind:value="date"> {{ date }}</option>
        </select>
      </div>
      <div>
        <select @change="search" id="search-rating" class="search-filter-field">
          <option :disabled="true" :selected="true">Rating</option>
          <option v-for="rating in ratings" v-bind:value="rating"> {{ rating }}</option>
        </select>
      </div>
      <div>
        <select @change="search" id="search-language" class="search-filter-field">
          <option :disabled="true" :selected="true">Language</option>
          <option v-for="language in languages" v-bind:value="language"> {{ language }}</option>
        </select>
      </div>
    </div>
  </div>
</template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...