当前位置: 首页 > 知识库问答 >
问题:

Vue.js 2 Webpack,V-Model绑定并从router.params加载数据,可选默认值不工作

卫子平
2023-03-14

V-Model绑定并从router.params加载数据,可选默认不工作Vue.js 2

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

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

我想要的是当组件加载以从url(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>

共有3个答案

熊嘉茂
2023-03-14

你的问题是没有使用Vue的反应性。这里有一些东西需要更新:

  • 将jQuery替换为Vue数据属性。
  • v-model添加到表单字段中。
  • 使用<code>路由器。替换而不是路由器。推送(避免浏览器对搜索更改做出后向/前向反应)
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>
解浩渺
2023-03-14

问题是您试图从< code>params属性访问查询参数。查询参数在< code>query属性中,而不在< code>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,
栾和玉
2023-03-14

您对此代码有许多问题:

  1. 你不用Vue的反应性
  2. 您读取路由参数,但使用查询重定向(它可以工作,但在将来更改路由参数时可能会导致问题)
  3. 您不会将从路由获取的参数分配给表单字段

首先,将过滤器:{}添加到数据中(它将存储当前的过滤器字段),然后让我们通过路由更改来更新它:

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

 类似资料:
  • 使用 v-model 指令,可以建立数据到模板的双向绑定。本质上它是如下写法的语法糖: <input v-model="value" /> => <input value={{ self.value }} ev-input={function(e) { self.value = e.target.value; this.update(); }.bind(this)} /

  • 问题内容: 考虑程序的三个不同的运行: 是否可以在第一种情况下,第二种情况下,第三种情况下使用? 问题答案: 带有参数的参数可以很好地处理此三向输入。 我也可以给它一个参数。 如何使用argparse在python中添加多个参数选项?

  • 我试图通过数据绑定来设置布局可见性。从数据库加载数据时,我在XML中设置的默认可见性不起作用。这是布局文件 视图模型是这样的 我有什么遗漏吗?默认情况下,我希望将错误布局的可见性设置为不可见。但默认情况下会显示它。

  • 问题内容: 我刚刚安装了CentOS,Apache和PHP。当我访问我的网站http://example.com/myapp/时,它显示为“禁止访问”。默认情况下,它不会加载index.php文件。 当我访问http://example.com/myapp/index.php时,它可以正常工作。 任何想法如何解决该问题? 问题答案: Apache需要配置为将index.php识别为索引文件。 实现

  • 本文向大家介绍vue中v-model对select的绑定操作,包括了vue中v-model对select的绑定操作的使用技巧和注意事项,需要的朋友参考一下 1、单选时 如果 v-model表达式的value初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这

  • 问题内容: 假设您有一个具有从数据库加载的值的表单。您如何初始化ng-model? 例: 在我的控制器中,$ scope.card最初是未定义的。除了做这样的事情,还有别的办法吗? 问题答案: 这是新的Angular应用程序中的常见错误。如果可以避免,您不想将值写入服务器上的HTML。如果确实如此,那么如果您可以摆脱让服务器完全呈现HTML的局面,那就更好了。 理想情况下,您要发送Angular