知识点:
在向下选择再向上选择光标返回头部问题的处理方式
@keydown.up.prevent=“choosePrevLi”
webpack.config.js
// 模式
module.exports = {
// 模式
mode: "development",
// 处理文件后缀
resolve: {
// vue 文件的入口
alias: {
"vue$": "vue/dist/vue.js",
},
// 处理文件的后缀
extensions: ['.js', '.css'],
},
// 文件入口
entry: {
"01": "./modules/01.js",
"02": "./modules/02.js",
"03": "./modules/03.js",
"04": "./modules/04.js",
"05": "./modules/05.js"
},
// 文件发布
output: {
filename: "./[name].js"
},
// 模块的编译
module: {
// 加载机
rules: [
// css
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
// less
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"]
},
// scss
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"]
}
]
}
}
./modules/01.js
import Vue from 'vue';
import "../style.scss";
new Vue({
el: "#app",
data: {
msg: "",
email: ['qq', '163', '126', '189', 'sina', 'hotmail', 'gmail', 'sohu', '21cn'],
// 绑定的 类
cls: [],
// 默认显示第几个
num: -1,
// 是否选中
hasChoose: false,
},
// 计算属性数据
computed: {
// 对输入的数据进行过滤
dealMsg() {
// 获取用户输入的 @
let index = this.msg.indexOf("@");
if (index >= 0) {
return this.msg.slice(0, index);
}
return this.msg
},
// 对输入的后缀进行过滤
dealEmail() {
// 获取用户输入的 @
let index = this.msg.indexOf("@");
if (index >= 0) {
// 对数组进行过滤
// 获取@后面的内容
// 过滤数组:是否以截取的内容开头
let str = this.msg.slice(index + 1);
return this.email.filter(item => {
item += item === '189' ? '.c' : '.co';
return item.indexOf(str) === 0
})
}
return this.email
},
},
// 定义方法
methods: {
// 鼠标的点击事件
clickChooseLi(e) {
// 将li 的内容 放在 msg 中
this.msg = e.target.innerHTML.trim();
},
// 数据 num 获取对应的索引值
getIndex() {
// 输入 num 会 -Infinity ~ Infinity => 0~10
// 对 10 取余: -10 ~ 0 ~ 10
// 加上 10 0~20
// 对 10 取余 0 ~ 10
// 对应几个邮箱,就有几个 li
// 1 对 len 取余 -len ~ len
let len = this.dealEmail.length;
// 1 对 len 取余 -len ~ len
// let num = this.num % len
// // 2 加上 len 0 ~ 2 * len
// num = num + len
// // 3 对 len 取余 0 ~ len
// num = num % len;
// return num;
// 合并一步
return (this.num % len + len) % len
},
// 更新 li 的样式
updateLi() {
// 数据驱动视图,数组中对应的成员添加 choose
// 新数组
let cls = [];
// 修改
cls[this.getIndex()] = 'choose';
// 赋值
this.cls = cls;
},
// 键盘的按下事件
chooseNextLi() {
this.num++;
this.updateLi()
// 选中过
this.hasChoose = true;
},
// 键盘的上箭头
choosePrevLi() {
// 如果选中
if (this.hasChoose) {
this.num--;
}
// 更新 li 的样式
this.updateLi();
// 选中过
this.hasChoose = true;
},
// 键盘的回车事件
chooseEmterLi() {
// 获取索引值
let index = this.getIndex();
// 获取邮箱
let email = this.dealEmail[index];
// 更新内容
this.msg = `${this.dealMsg}@${email}${email === '189' ? '.cn' : '.com'}`
}
}
})
01 支付宝注册的案例.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div class="content">
<label>用户名:</label>
<input
type="text"
v-model="msg"
placeholder="请输入电子邮箱"
@keydown.up.prevent="choosePrevLi"
@keyup.down="chooseNextLi"
@keyup.enter="chooseEnterLi"
>
<ul v-show="msg && dealEmail.length">
<li
v-for="(item,index) in dealEmail"
::key="index"
:class="cls[index]"
@click="clickChooseLi"
>
{{dealMsg}}@{{item}}.<template v-if="item === '189'">cn</template><template v-else>com</template>
</li>
</ul>
</div>
</div>
<script src="./dist/01.js"></script>
</body>
</html>
style.css
* {
margin: 0;
padding: 0;
}
.content {
width: 500px;
height: 250px;
margin: 50px auto;
background-color: #e3e3e3;
position: relative;
}
ul {
list-style: none;
width: 165px;
position: absolute;
top: 23px;
left: 56px;
height: 187px;
background-color: #fff;
}
li {
line-height: 20px;
font-size: 14px;
&.choose,
&:hover {
background-color: yellowgreen;
}
}
效果图