代码之家  ›  专栏  ›  技术社区  ›  X3R0

vue.js 2+webpack,v-model绑定并从router.params加载数据,可选默认不工作

  •  1
  • X3R0  · 技术社区  · 6 年前

    v-model使用可选的默认值not working vue.js 2绑定并从router.params加载数据

    我有4个选择和1个文本输入

    在data()方法中,我返回一个数组,其中包含selects选项元素的默认值。

    我想要的是当组件加载以从URL(router.params)获取值,然后从select中选择正确的值,并在文本框[搜索框]中显示文本输入(通过router params传递)

    我尝试过使用setTimeout函数进行双向绑定、单向绑定和jQuery更新,但仍然没有得到积极的结果。

    我期待你的回应和建议,谢谢。

    路线

    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 回复  |  直到 6 年前
        1
  •  1
  •   Styx    6 年前

    您对该代码有许多问题:

    1. 你不使用Vue的反应性。
    2. 你读路线 params ,但使用重定向 query (它起作用,但如果你改变路线,将来可能会引起问题 帕拉姆 )
    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了。

        2
  •  1
  •   Nafees Anwar    6 年前

    问题是您正试图从中访问查询参数 params 属性。查询参数在 query 属性不在 帕拉姆 . 您可以使用双向绑定并像这样预先选择正确的值。

        <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,
    
        3
  •  0
  •   Kordonme    6 年前

    你的问题不是使用Vue的反应性。这里有几点需要更新:

    • 用Vue数据属性替换jquery
    • 添加 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>
        4
  •  0
  •   X3R0    6 年前

    工作脚本,谢谢你们!!!!

    <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>