首页 > 解决方案 > Vuejs 搜索列表使用箭头键在列表中导航

问题描述

const app = new Vue({
    el: '#app',
    data: {
        searchText: '',
        listShow: true,
        newDiv:false,
        searcList:[],
        list: {}
    },
   
    methods: {
        handleBlur(e) {
        console.log("inputOutClick");
          if (this.listShow == false) {
            console.log("mousedown was fired first");
          }
          this.listShow = false
        },
        selecteds(list) {
        console.log("selecteds");
            this.listShow = false;
            this.searchText = list.name;
        },
        
        async search() {
            this.listShow = true;
            this.searcList = ['aeaeg', 'tdthtdht', 'srgsr'];
            this.list.name = "TEST"
        }

    }

});
.dropdown-toggle-none::after {
    content: none;
}

.select {
    width: 100%;
    max-height: 420px;
    overflow-y: auto;
    background: linear-gradient(#fdfdfd 30%, rgba(253, 253, 253, 0)), linear-gradient(rgba(253, 253, 253, 0), #fdfdfd 70%) 0 100%, linear-gradient(rgba(64, 54, 55, .1) 0, rgba(64, 54, 55, 0)) 100% 0, linear-gradient(rgba(64, 54, 55, 0) 0, rgba(64, 54, 55, .1)) 0 100%;
    background-repeat: no-repeat;
    background-size: 100% 50px, 100% 50px, 100% 6px, 100% 6px;
    background-attachment: local, local, scroll, scroll;
    border-top: 1px solid #e8e7e7;
    border-bottom: 1px solid #e8e7e7;
    background-color: #fdfdfd;
}

.select {
    z-index: 1;
    top: 50px;
    padding: 3px 0;
    border: 1px solid #c5c4c2;
    background-color: #fdfdfd;
    -webkit-box-shadow: 0 3px 6px #c5c4c2;
    -moz-box-shadow: 0 3px 6px #c5c4c2;

}

.select {
    position: absolute;
    border-radius: .357rem !important;
    box-shadow: 0 3px 6px #c5c4c2;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    line-height: 1.45;
}

.select ul {
    padding: 0;
    margin: 0;
}

.select li {
    display: block;
    cursor: pointer;
    line-height: 20px;
    color: #403637;
}

.select li a {
    display: block;
    padding: 5px 15px;
    -webkit-transition-property: color, background-color;
    -webkit-transition-duration: .66s;
    -webkit-transition-timing-function: cubic-bezier(.25, 1, .25, 1);
    -moz-transition-duration: .66s;
    -ms-transition-duration: .66s;
    -ms-transition-timing-function: cubic-bezier(.25, 1, .25, 1);
    -o-transition-property: color, background-color;
    -o-transition-timing-function: cubic-bezier(.25, 1, .25, 1);
    transition-property: color, background-color;
    transition-duration: .66s;
    transition-timing-function: cubic-bezier(.25, 1, .25, 1);
}

.select li a:hover {
    color: #22c39e;
    background-color: #e8e7e7;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
    <div id="app">
        <div>
            <input
                type="text"
                class="form-control"
                v-model="searchText"
                @keyup="search"
                @blur="handleBlur"
                />
            <div v-if="listShow" style="background:red">
                <ul>
                    <li v-for="(list, index) in searcList">
                        <a @mousedown.prevent @click="selecteds(list)">{{ list}}</a>
                    </li>
                </ul>
            </div>
           <div v-if="newDiv">
           <p>hello</p>
           </div>
        </div>
    </div>

我正在尝试用 vuejs 打电话,有一个我只是坚持的话题。例如; 我想使用箭头符号“使用 alt 键或向上键”在从获取数据返回的数据中导航,但我还没有完全弄清楚如何去做。

如果是第二个问题,我希望列表中选择的颜色清晰。

new Vue({
  el: '#app',
  data: {
   type: "sales_invoices",
            SearcListed: {
                searchText: '',
                listShow: false,
                searcList: [],
            },
  },
  methods: {
  selecteds(list) {
            this.SearcListed.listShow = false;
            this.SearcListed.searchText = list.name;
        },
        async search() {
            if (this.SearcListed.searchText !== '') {
                const res = await this.callApi('get', 'getir' + '?filter=' + this.SearcListed.searchText)
                if (res.status === 200) {
                    this.SearcListed.searcList = res.data;
                    if (res.data.length > 0) {
                        this.SearcListed.listShow = true;
                    } else {
                        this.SearcListed.listShow = false;
                    }
                }
            } else {
                this.SearcListed.listShow = false;
            }
        },
  }
});
.dropdown-toggle-none::after {
    content: none;
}

.select {
    width: 100%;
    max-height: 420px;
    overflow-y: auto;
    background: linear-gradient(#fdfdfd 30%, rgba(253, 253, 253, 0)), linear-gradient(rgba(253, 253, 253, 0), #fdfdfd 70%) 0 100%, linear-gradient(rgba(64, 54, 55, .1) 0, rgba(64, 54, 55, 0)) 100% 0, linear-gradient(rgba(64, 54, 55, 0) 0, rgba(64, 54, 55, .1)) 0 100%;
    background-repeat: no-repeat;
    background-size: 100% 50px, 100% 50px, 100% 6px, 100% 6px;
    background-attachment: local, local, scroll, scroll;
    border-top: 1px solid #e8e7e7;
    border-bottom: 1px solid #e8e7e7;
    background-color: #fdfdfd;
}

.select {
    z-index: 1;
    top: 50px;
    padding: 3px 0;
    border: 1px solid #c5c4c2;
    background-color: #fdfdfd;
    -webkit-box-shadow: 0 3px 6px #c5c4c2;
    -moz-box-shadow: 0 3px 6px #c5c4c2;

}

.select {
    position: absolute;
    border-radius: .357rem !important;
    box-shadow: 0 3px 6px #c5c4c2;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    line-height: 1.45;
}

.select ul {
    padding: 0;
    margin: 0;
}

.select li {
    display: block;
    cursor: pointer;
    line-height: 20px;
    color: #403637;
}

.select li a {
    display: block;
    padding: 5px 15px;
    -webkit-transition-property: color, background-color;
    -webkit-transition-duration: .66s;
    -webkit-transition-timing-function: cubic-bezier(.25, 1, .25, 1);
    -moz-transition-duration: .66s;
    -ms-transition-duration: .66s;
    -ms-transition-timing-function: cubic-bezier(.25, 1, .25, 1);
    -o-transition-property: color, background-color;
    -o-transition-timing-function: cubic-bezier(.25, 1, .25, 1);
    transition-property: color, background-color;
    transition-duration: .66s;
    transition-timing-function: cubic-bezier(.25, 1, .25, 1);
}

.select li a:hover {
    color: #22c39e;
    background-color: #e8e7e7;
}
<div id="app">
  <div class="container">
    <div class="col-sm-6">
      <div class="input-group input-group-merge mb-1">
        <input type="text" class="form-control" placeholder="Search..." aria-label="Search..." aria-describedby="basic-addon-search2" v-model.trim="SearcListed.searchText" @keyup="search" autocomplete="off" />
        <span class="input-group-text">
          <i class="fas fa-search"></i>
        </span>
        <div class="select" v-if="SearcListed.listShow">
          <ul>
            <li v-for="(list, index) in SearcListed.searcList" :key="list.id">
              <a @mousedown.prevent @click="selecteds(list)">{{ list.name }}</a>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</div>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

标签: vue.js

解决方案


要使用箭头键事件,您可以使用以下内容:

@keyup.up="nextListItem"
@keyup.down="previousListItem"

您可能会将其应用于以下 div:

<div @keyup.up="nextSearchList" @keyup.down="previousSearchList" class="input-group input-group-merge mb-1">...</div>

(请注意,只有当 div 处于焦点时才会收到按键。)

您必须在您的列表中添加一个索引或对象data()以跟踪列表中选定的项目是什么,然后使用 and 转到下一个或上nextListItem一个previousListItem

您可以在:class="{ active: index == selectedItemIndex}"每个li中添加一个以v-for提供当前选择liactive类,然后您可以根据需要设置它的样式,例如:

.active {
 background-color: grey;
}

此外,这里有更多关于 vue2 和 vue3 键事件修饰符的信息:


推荐阅读