728x90
피치 못할 사정으로 NuxtJS에서 jQuery 기반의 슬릭그리드를 대체할 플러그인을 찾지 못해서 jQuery를 적용시킨 후
슬릭그리드를 적용해보려고 했었다.
먼저 jQuery 적용은 https://minu0807.tistory.com/90 여기처럼 적용했고,
슬릭그리드 적용은 해당 vue파일에 할까 하다가 그냥 nuxt.config.js에다 적용했다.
head: {
title: 'AF_Manager',
htmlAttrs: {
lang: 'en'
},
meta: [{ charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: '' }],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },{ rel: 'stylesheet', href: '/lib/slick/slick.css' }],
script: [
{ type: 'text/javascript', src: '/lib/jquery.js' },
{ type: 'text/javascript', src: '/lib/slick/slick.core.js' },
{ type: 'text/javascript', src: '/lib/slick/slick.grid.js' },
{ type: 'text/javascript', src: '/lib/slick/plugins/slick.checkboxselectcolumn.js' },
]
},
nuxt.config.js에서 head에 추가한 스크립트 파일 읽는 순서와 렌더링 순서의 문제도 있어서 다양한 방법을 써봤지만 일단 내가 한 방법은 이거다.
<template>
<v-card>
<v-card-title>
<v-row>
<v-col cols="12" lg="2">
<v-menu
ref="menu1"
v-model="menu1"
:close-on-content-click="false"
:return-value.sync="s_date"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on, attrs }">
<v-text-field
v-model="s_date"
prepend-icon="mdi-calendar"
readonly
v-bind="attrs"
v-on="on"
id="test"
></v-text-field>
</template>
<v-date-picker v-model="s_date" no-title scrollable :max="e_date">
<v-spacer></v-spacer>
<v-btn text color="primary" @click="menu1 = false">Cancel</v-btn>
<v-btn text color="primary" @click="s_date_search(s_date)">OK</v-btn>
</v-date-picker>
</v-menu>
</v-col>
</v-row>
</v-card-title>
<v-card-text>
<div id="slickgrid" style="height: 650px"></div>
</v-card-text>
</v-card>
</template>
<script>
export default {
data() {
return {
totCount: 0,
searchSize: 0,
grid: null,
rows: [],
columns: [],
selectRows: [],
sort: `{"test_mk_dt": "desc"}`,
checkboxSelector: null,
options: {
editable: true,
enableCellNavigation: true,
asyncEditorLoading: false,
enableAsyncPostRender: true,
autoEdit: false,
threat_pressing: true,
enableTextSelectionOnCells: true,
enableColumnReorder: false
},
date: new Date().toISOString().substr(0, 10),
s_date: new Date().toISOString().substr(0, 10),
e_date: new Date().toISOString().substr(0, 10),
menu1: false,
menu2: false
}
},
mounted() {
this.totCount = 0;
this.searchSize = 200;
this.setColumns();
this.grid = new Slick.Grid("#slickgrid", this.rows, this.columns, this.options);
this.grid.setSelectionModel(new Slick.RowSelectionModel({selectActiveRow: false}));
this.grid.registerPlugin(this.checkboxSelector);
this.getData();
//checkbox
this.grid.onSelectedRowsChanged.subscribe((e, args) => {
this.selectRows = [];
for (var i in args.rows) {
this.selectRows.push(args.rows[i]);
}
});
//contextMenu
this.grid.onContextMenu.subscribe((e) => {
e.preventDefault();
const cell = this.grid.getCellFromEvent(e);
const obj = this.grid.getColumns()[cell.cell];
const data = this.grid.getDataItem(cell.row);
const val = data[obj.id];
console.log(cell, obj, data, val);
});
//sort 기능
this.grid.onSort.subscribe((e, args) => {
if (args.sortAsc) {
this.sort = `{"${args.sortCol.id}":"asc"}`;
} else {
this.sort = `{"${args.sortCol.id}":"desc"}`;
}
this.searchSize = 200;
this.getData();
});
//scroll 기능
this.grid.onScroll.subscribe((e, o) => {
if (o.scrollTop >= $("#slickgrid .grid-canvas").height() - $("#slickgrid .slick-viewport").height()) {
if (this.totCount !== 0) {
if (this.totCount >= this.searchSize) {
this.searchSize += 100;
this.getData()
}
}
}
});
},
methods: {
setColumns() {
this.checkboxSelector = new Slick.CheckboxSelectColumn({
cssClass: "slick-cell-checkboxsel"
});
this.columns.push(this.checkboxSelector.getColumnDefinition());
this.columns.push(
{ name: "생성일", field: "test_mk_dt", id: "test_mk_dt", cssClass:'text-center', width:150, sortable: true },
{ name: "이름", field: "name", id: "name", cssClass:'text-center',sortable: true },
{ name: "나이", field: "age", id: "age", cssClass:'text-center',sortable: true },
{ name: "아이피", field: "test_ip", id: "test_ip", cssClass:'text-center',sortable: true },
{ name: "포트", field: "test_port", id: "test_port", cssClass:'text-center',sortable: true },
{ name: "사용여부", field: "is_use", id: "is_use", cssClass:'text-center',sortable: false, formatter: this.fmt_is_use },
)
},
async getData() {
try {
const params = {
size: this.searchSize,
s_date: this.s_date,
e_date: this.e_date,
sort: this.sort
}
const rs = await this.$store.dispatch('initList', params);
this.rows = rs.data.data;
this.totCount = rs.data.data.length;
this.grid.setData(this.rows);
this.grid.render();
} catch (err) {
console.error('monitoring getData err : ', err);
}
},
s_date_search(v) {
this.s_date = v;
this.menu1 = false;
this.$refs.menu1.save(v);
},
e_date_search(v) {
this.e_date = v;
this.menu2 = false;
this.$refs.menu2.save(v);
},
//slick.grid formatter
fmt_is_use(row, cell, value, def, data) {
if (data.is_use) {
return '사용';
} else {
return '사용안함'
}
}
}
}
</script>
<style>
.slick-cell {
color: black;
}
</style>
적용 시킨 vue파일 소스이다.
순서 때문에 우선 mounted() 훅에서 슬릭그리드를 적용시켜야 하고,
슬릭그리드의 내장 함수도 사용하려면 위 소스 처럼 mounted 훅에 작성해줘야 한다.
그 외에는 다른 부분에 작성해도 사용가능하다.
이걸 만들면서 생각보다 오래걸린 부분이 있다.
scope 개념을 생각못하고 문제를 해결 못해서 오래걸렸었다.
mounted 훅에 작성된 슬릭그리드 내장 함수 안에서 data() 안에 만들어 둔 값들을 가져오거나
methods 훅에 만든 함수를 실행을 시켜야하는데
this.grid.onSort.subscribe(function(e, args) {
if (args.sortAsc) {
this.sort = `{"${args.sortCol.id}":"asc"}`;
} else {
this.sort = `{"${args.sortCol.id}":"desc"}`;
}
this.searchSize = 200;
this.getData();
});
처음에 이렇게 작성을 해서 왜 methods에 선언된 함수랑 data에 선언된 값을 못가져오는 건지 빨리 파악을 못해서 삽질을 엄청 했다.
애로우펑션을 쓰면 된다.
this.grid.onSort.subscribe((e, args) => {
if (args.sortAsc) {
this.sort = `{"${args.sortCol.id}":"asc"}`;
} else {
this.sort = `{"${args.sortCol.id}":"desc"}`;
}
this.searchSize = 200;
this.getData();
});
이 부분에 대한 이해가 안된다면 Arrow function에 대해 찾아보길 바란다.
반응형
'VueJS > Nuxt' 카테고리의 다른 글
[VueJS] NuxtJS+Vuetify alert 컴포넌트 만들어보기 (0) | 2021.07.13 |
---|---|
[VueJS] NuxtJS에서 url(page) 변경할 때마다 route 체크 방법 (0) | 2021.06.15 |
[VueJS] NuxtJS에 jQuery 적용하기 (0) | 2021.05.26 |
[VueJS] NuxtJS + VuetifyJS 프로젝트 설치 (Nuxt 설치) (0) | 2021.05.12 |
[VueJS] NuxtJS 아주 간단하게 로딩화면 만들기 (0) | 2021.05.07 |