mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-29 21:28:52 +00:00
[Update] 添加select 异步分页加载
This commit is contained in:
168
src/components/Select2/index.vue
Normal file
168
src/components/Select2/index.vue
Normal file
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<el-select
|
||||
v-model="vaultOrDefault"
|
||||
v-loadmore="loadMore"
|
||||
:placeholder="placeholder"
|
||||
:options="options"
|
||||
:remote-method="filterOptions"
|
||||
:loading="loading"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
class="select2"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Select2',
|
||||
directives: {
|
||||
'loadmore': {
|
||||
bind(el, binding) {
|
||||
// 获取element-ui定义好的scroll盒子
|
||||
const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap');
|
||||
SELECTWRAP_DOM.addEventListener('scroll', function() {
|
||||
/**
|
||||
* scrollHeight 获取元素内容高度(只读)
|
||||
* scrollTop 获取或者设置元素的偏移值,常用于, 计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.
|
||||
* clientHeight 读取元素的可见高度(只读)
|
||||
* 如果元素滚动到底, 下面等式返回true, 没有则返回false:
|
||||
* ele.scrollHeight - ele.scrollTop === ele.clientHeight;
|
||||
*/
|
||||
const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
|
||||
if (condition) {
|
||||
binding.value()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
makeParams: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
processResults: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
value: {
|
||||
type: [Array, String, Number, Boolean],
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
params: {
|
||||
search: '',
|
||||
page: 1,
|
||||
hasMore: true
|
||||
},
|
||||
defaultMakeParams: params => {
|
||||
const page = params.page || 1;
|
||||
return {
|
||||
search: params.search,
|
||||
offset: (page - 1) * 10,
|
||||
limit: 10
|
||||
}
|
||||
},
|
||||
defaultProcessResults: data => {
|
||||
let results = data.results
|
||||
results = results.map((item) => {
|
||||
return { label: item.name, value: item.id }
|
||||
})
|
||||
const more = !!data.next
|
||||
return { results: results, pagination: more }
|
||||
},
|
||||
vaultOrDefault: this.value || []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
makeParamsOrDefault() {
|
||||
return this.makeParams || this.defaultMakeParams
|
||||
},
|
||||
processResultsOrDefault() {
|
||||
return this.processResults || this.defaultProcessResults
|
||||
},
|
||||
optionsOrDefault() {
|
||||
return this.options || []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.url) {
|
||||
this.getOptions()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadMore() {
|
||||
console.log('Load more ...', this.params.hasMore)
|
||||
if (!this.params.hasMore) {
|
||||
return
|
||||
}
|
||||
this.params.page = this.params.page ? this.params.page + 1 : 1
|
||||
this.getOptions()
|
||||
},
|
||||
resetParams() {
|
||||
this.params = {
|
||||
search: '',
|
||||
page: 1,
|
||||
hasMore: false
|
||||
}
|
||||
},
|
||||
filterOptions(query) {
|
||||
this.resetParams()
|
||||
this.options = []
|
||||
this.params.search = query
|
||||
this.getOptions()
|
||||
},
|
||||
getOptions() {
|
||||
this.loading = true
|
||||
const params = this.makeParamsOrDefault(this.params)
|
||||
console.log(params)
|
||||
this.$axios.get(this.url, { params: params }).then(resp => {
|
||||
this.loading = false
|
||||
const data = this.processResultsOrDefault(resp)
|
||||
if (!data.pagination) {
|
||||
this.params.hasMore = false
|
||||
}
|
||||
data.results.forEach((v) => {
|
||||
this.options.push(v)
|
||||
console.log(v)
|
||||
})
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
this.options = []
|
||||
}).then(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.select2 {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -16,6 +16,7 @@ const cn = {
|
||||
},
|
||||
common: {
|
||||
'name': '名称',
|
||||
'Name': '名称',
|
||||
'action': '动作',
|
||||
'role': '角色',
|
||||
'username': '用户名',
|
||||
@@ -28,7 +29,10 @@ const cn = {
|
||||
'delete': '删除',
|
||||
'Detail': '详情',
|
||||
'detail': '详情',
|
||||
'baseInfo': '基本信息'
|
||||
'baseInfo': '基本信息',
|
||||
'Created by': '创建人',
|
||||
'Date Created': '创建日期',
|
||||
'Comment': '备注'
|
||||
},
|
||||
route: {
|
||||
'dashboard': '仪表盘',
|
||||
|
||||
21
src/main.js
21
src/main.js
@@ -36,6 +36,10 @@ Vue.use(ElementUI, { locale })
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
// vue select
|
||||
import vSelect from 'vue-select'
|
||||
Vue.component('v-select', vSelect)
|
||||
|
||||
import ElDataTable from '@/components/el-data-table/el-data-table.vue'
|
||||
import ElFormRenderer from '@/components/el-form-renderer/el-form-renderer.vue'
|
||||
import {
|
||||
@@ -44,23 +48,6 @@ import {
|
||||
} from 'element-ui'
|
||||
import service from '@/utils/request'
|
||||
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
Form,
|
||||
FormItem,
|
||||
Pagination,
|
||||
Table,
|
||||
TableColumn
|
||||
} from 'element-ui'
|
||||
|
||||
Vue.use(Button)
|
||||
Vue.use(Dialog)
|
||||
Vue.use(Form)
|
||||
Vue.use(FormItem)
|
||||
Vue.use(Pagination)
|
||||
Vue.use(Table)
|
||||
Vue.use(TableColumn)
|
||||
Vue.component('el-data-table', ElDataTable)
|
||||
Vue.component('el-form-renderer', ElFormRenderer)
|
||||
Vue.prototype.$confirm = MessageBox.confirm
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
$--color-primary: red;
|
||||
$--color-primary: #1ab394;
|
||||
$--color-success: #1c84c6;
|
||||
$--color-info: #23c6c8;
|
||||
$--color-warning: #f8ac59;
|
||||
$--color-danger: #ed5565;
|
||||
|
||||
.el-upload {
|
||||
input[type="file"] {
|
||||
@@ -122,5 +126,72 @@ td .el-button.el-button--mini {
|
||||
|
||||
.el-card__header {
|
||||
padding: 10px 15px;
|
||||
font-size: 14px;
|
||||
line-height: 18.5px;
|
||||
font-weight: normal;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.el-card.primary > .el-card__header {
|
||||
background-color: $--color-primary;
|
||||
border-color: $--color-primary;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.el-card.success > .el-card__header {
|
||||
background-color: $--color-success;
|
||||
border-color: $--color-success;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.el-card.info > .el-card__header {
|
||||
background-color: $--color-info;
|
||||
border-color: $--color-info;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
background-color: #FFFFFF;
|
||||
background-image: none;
|
||||
border: 1px solid #e5e6e7;
|
||||
border-radius: 1px;
|
||||
color: inherit;
|
||||
display: block;
|
||||
padding: 6px 12px;
|
||||
transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.el-select-dropdown.is-multiple .el-select-dropdown__item.selected {
|
||||
color: #606266;
|
||||
background-color: #ddd;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after {
|
||||
color: $--color-primary;
|
||||
}
|
||||
|
||||
.el-tag.el-tag--info {
|
||||
background-color: #f1f1f1;
|
||||
border-color: #e5e6e7;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.el-tag.el-tag--info .el-tag__close {
|
||||
color: #333333;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.el-tag.el-tag--info.is-hit {
|
||||
border-color: #e5e6e7;
|
||||
}
|
||||
|
||||
.el-tag.el-tag--info .el-tag__close:hover {
|
||||
color: #000000;
|
||||
font-weight: 600;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
@import './sidebar.scss';
|
||||
@import './element-index.css';
|
||||
@import './menu.scss';
|
||||
@import 'vue-select/src/scss/vue-select.scss';
|
||||
@import "./font-awesome/font-awesome.min.css";
|
||||
|
||||
body {
|
||||
|
||||
@@ -2,8 +2,19 @@
|
||||
<BaseDetailPage :submenu="submenu" :active-menu="activeSubMenu" :title="title">
|
||||
<div slot="info">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<DetailCard :title="cardTitle" :items="detailItems"></DetailCard>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<DetailCard :title="cardTitle" :items="cardItems"></DetailCard>
|
||||
<el-card class="box-card primary">
|
||||
<div slot="header" class="clearfix">
|
||||
<i class="fa fa-user"></i>
|
||||
<span>组下用户</span>
|
||||
</div>
|
||||
<div>
|
||||
<Select2 v-model="value" :url="url"></Select2>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@@ -14,17 +25,18 @@
|
||||
import { getUserGroup } from '@/api/user'
|
||||
import { BaseDetailPage } from '@/layout/components'
|
||||
import DetailCard from '@/components/DetailCard'
|
||||
import Select2 from '@/components/Select2'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BaseDetailPage,
|
||||
DetailCard
|
||||
DetailCard,
|
||||
Select2
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeSubMenu: 'info',
|
||||
group: { name: '' },
|
||||
|
||||
submenu: [
|
||||
{
|
||||
title: this.$tc('baseInfo'),
|
||||
@@ -40,29 +52,48 @@ export default {
|
||||
}
|
||||
],
|
||||
cardTitle: '基本信息',
|
||||
cardItems: [
|
||||
placeholder: '请选择',
|
||||
url: '/api/v1/users/users/',
|
||||
value: [
|
||||
{
|
||||
key: '名称',
|
||||
value: '我是中国人的美好一天是从什么时候开始的'
|
||||
label: 'hello',
|
||||
value: '1a775bbf-6861-4acb-8ae4-2f684794c8cc'
|
||||
},
|
||||
{
|
||||
key: '创建者',
|
||||
value: '广宏伟'
|
||||
label: 'test',
|
||||
value: '4dccdf84-7728-4de0-a507-67c905b3091b'
|
||||
},
|
||||
{
|
||||
key: '创建日期',
|
||||
value: '2019年10月17日 15:54'
|
||||
},
|
||||
{
|
||||
key: '备注',
|
||||
value: '这个是滴滴'
|
||||
label: 'whold',
|
||||
value: 'c5ec4b91-1fb2-478e-89bc-5a4abc0f9c6c'
|
||||
}
|
||||
]
|
||||
],
|
||||
options: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return this.$t('users.userGroup') + ': ' + this.group.name
|
||||
},
|
||||
detailItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$tc('Name'),
|
||||
value: this.group.name
|
||||
},
|
||||
{
|
||||
key: this.$tc('Created by'),
|
||||
value: this.group.created_by
|
||||
},
|
||||
{
|
||||
key: this.$tc('Date Created'),
|
||||
value: this.group.date_created
|
||||
},
|
||||
{
|
||||
key: this.$tc('Comment'),
|
||||
value: this.group.comment
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
11
yarn.lock
11
yarn.lock
@@ -5706,7 +5706,6 @@ locate-path@^3.0.0:
|
||||
lodash.clonedeep@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
|
||||
|
||||
lodash.defaultsdeep@^4.6.0:
|
||||
version "4.6.1"
|
||||
@@ -5715,37 +5714,30 @@ lodash.defaultsdeep@^4.6.0:
|
||||
lodash.frompairs@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.frompairs/-/lodash.frompairs-4.0.1.tgz#bc4e5207fa2757c136e573614e9664506b2b1bd2"
|
||||
integrity sha1-vE5SB/onV8E25XNhTpZkUGsrG9I=
|
||||
|
||||
lodash.get@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
|
||||
|
||||
lodash.has@^4.5.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862"
|
||||
integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=
|
||||
|
||||
lodash.includes@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
|
||||
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
|
||||
|
||||
lodash.isempty@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
|
||||
integrity sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=
|
||||
|
||||
lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||
|
||||
lodash.isplainobject@^4.0.6:
|
||||
version "4.0.6"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
||||
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
|
||||
|
||||
lodash.kebabcase@^4.1.1:
|
||||
version "4.1.1"
|
||||
@@ -5766,7 +5758,6 @@ lodash.padend@4.6.1:
|
||||
lodash.set@^4.3.2:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
|
||||
integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
|
||||
|
||||
lodash.sortby@^4.7.0:
|
||||
version "4.7.0"
|
||||
@@ -5775,7 +5766,6 @@ lodash.sortby@^4.7.0:
|
||||
lodash.topairs@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.topairs/-/lodash.topairs-4.3.0.tgz#3b6deaa37d60fb116713c46c5f17ea190ec48d64"
|
||||
integrity sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=
|
||||
|
||||
lodash.transform@^4.6.0:
|
||||
version "4.6.0"
|
||||
@@ -5788,7 +5778,6 @@ lodash.uniq@^4.5.0:
|
||||
lodash.values@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-4.3.0.tgz#a3a6c2b0ebecc5c2cba1c17e6e620fe81b53d347"
|
||||
integrity sha1-o6bCsOvsxcLLocF+bmIP6BtT00c=
|
||||
|
||||
lodash@4.17.11:
|
||||
version "4.17.11"
|
||||
|
||||
Reference in New Issue
Block a user