1、场景
鲁迅曾经说过,任何没有使用场景的需求都是无用的需求。 在前端项目开发中,我们经常会遇到前端比后端开发快的时候,或者自己写了一个简单的项目demo ,但是需要数据,这时候就出现了技术瓶颈。
2、示例
在element 文档中,select 有这样一个功能组件 => 远程搜索 这里的组件描述就是 => 从服务器搜索数据,输入关键字进行查找。
3、本地测试组件
我们直接复制官方文档的例子,很轻松就能够在我们本地将组件跑起来,但是我们看到例子中的请求,是模拟的后端请求,数据都是从states 中取的,通过filter 筛选来实现的这个功能。
<template>
<el-select
v-model="value"
multiple
filterable
remote
reserve-keyword
placeholder="请输入关键词"
:remote-method="remoteMethod"
:loading="loading">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</template>
<script>
export default {
data() {
return {
options: [],
value: [],
list: [],
loading: false,
states: ["Alabama", "Alaska", "Arizona",
"Arkansas", "California", "Colorado",
"Connecticut", "Delaware", "Florida",
"Georgia", "Hawaii", "Idaho", "Illinois",
"Indiana", "Iowa", "Kansas", "Kentucky",
"Louisiana", "Maine", "Maryland",
"Massachusetts", "Michigan", "Minnesota",
"Mississippi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire",
"New Jersey", "New Mexico", "New York",
"North Carolina", "North Dakota", "Ohio",
"Oklahoma", "Oregon", "Pennsylvania",
"Rhode Island", "South Carolina",
"South Dakota", "Tennessee", "Texas",
"Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin",
"Wyoming"]
}
},
mounted() {
this.list = this.states.map(item => {
return { value: `value:${item}`, label: `label:${item}` };
});
},
methods: {
remoteMethod(query) {
if (query !== '') {
this.loading = true;
setTimeout(() => {
this.loading = false;
this.options = this.list.filter(item => {
return item.label.toLowerCase()
.indexOf(query.toLowerCase()) > -1;
});
}, 200);
} else {
this.options = [];
}
}
}
}
</script>
4、改进
这里为了方便一些,就直接引用了cdn 进行vue 的引入,同时根据element 文档对element 引入,因为还要模拟请求,这里就直接本地引入了axios (通过cdn 引入同样可以,cdn 引入方式在下图)。
<!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>VueDemo</title>
<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="./lib/axios.js"></script>
</head>
<body>
<div class="main" style="text-align: center; margin-top: 380px;">
<el-select v-model="name" placeholder="请输入名称" filterable remote :remote-method="nameRemoteMethod" :loading="nameLoading">
<el-option v-for="v in nameList" :key="v.id" :label="v.name" :value="v.name"></el-option>
</el-select>
</div>
<script>
var vm = new Vue({
el: '.main',
data() {
return {
name: '',
nameLoading: false,
nameList: []
}
},
watch: {
'name': {
deep: true,
handler(newVal, oldVal) {
this.inputNameMethod()
}
}
},
methods: {
nameRemoteMethod(query) {
this.name = query;
},
inputNameMethod(query = '') {
this.nameLoading = true;
let params = { name: this.name };
axios.get('http://127.0.0.1:3000/namelist', params).then(res => {
const { code, data } = res.data;
if(code == 1) {
this.nameLoading = false;
this.nameList = data || [];
}
})
}
},
mounted() {
this.inputNameMethod();
}
})
</script>
</body>
</html>
5、服务端代码
1.目录结构
- http_server
- node_modules
- express_router.js
- package-lock.json
- package.json
- start_server.js
2.express_router.js
const express = require('express')
let router = express.Router()
const nameList = [
{ id: 1, name: '111' },
{ id: 2, name: '222' },
{ id: 3, name: '333' },
{ id: 4, name: '444' },
{ id: 5, name: '555' },
{ id: 6, name: '666' }
]
router.get('/namelist', (req, res) => {
res.send({ code: 1, data: nameList, msg: 'success' })
})
router.post('/list', (req, res) => {
res.send({ code: 1, data: nameList, msg: 'success' })
})
module.exports = router
3.start_server.js
const express = require('express')
const router = require('./express_router')
const app = express()
var allowCrossDomain = function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
app.use(allowCrossDomain);
app.use('/', router)
app.listen(3000, () => {
console.log('running at 127.0.0.1:3000')
})
6、效果
因为服务端没有做数据过滤,所以每次都是请求的全部数据。
|