spring boot + spring security + mybatis + vue 로
로그인과 허접해 보이지 않는 화면을 만들(포팅)었으니 이제 실제 데이터를 가지고 와서 뿌려주는 작업을 해 보자.
Vue.js - Ajax 에서 이미 데이터 가지고 오는 것은 해 보았으니 프로젝트에 반영만 하면 된다.
User.vue 에 사용자 목록을 불러와 그려보자.
우선 Grid.vue 를 하나 만든다.
데이터를 가져와 grid 를 만들고 sorting 과 filtering 기능을 제공하는 간단한 grid 이다.
예전에 만들었던 10만건 이상 처리 가능한 grid 는 나중에 포팅해 보도록 하고.... 일단은 simple 한 data grid 를 만들어 본다.
<template> <div id="yhkimgrid"> <table> <thead> <tr> <th v-for="key in columns" @click="sortBy(key)" :class="{ active: sortKey == key }"> {{ key | capitalize }} <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"> </span> </th> </tr> </thead> <tbody> <tr v-for="entry in filteredData"> <td v-for="key in columns"> {{entry[key]}} </td> </tr> </tbody> </table> </div> </template> <script> export default { name: 'Grid', props: { data: Array, columns: Array, filterKey: String }, data () { const sortOrders = {} this.columns.forEach(key => { sortOrders[key] = 1 }) return { sortKey:'', sortOrders: sortOrders } }, computed: { filteredData() { const sortKey = this.sortKey const filterKey = this.filterKey && this.filterKey.toLowerCase() const order = this.sortOrders[sortKey] || 1 let data = this.data if (filterKey) { data = data.filter( row => { return Object.keys(row).some( key => { return String(row[key]).toLowerCase().indexOf(filterKey) > -1 }) }) } if (sortKey) { data = data.slice().sort( (a, b) => { a = a[sortKey] b = b[sortKey] return (a === b ? 0 : a > b ? 1 : -1) * order }) } return data } }, filters: { capitalize: function (str) { return str.charAt(0).toUpperCase() + str.slice(1) } }, methods:{ sortBy: function (key) { this.sortKey = key this.sortOrders[key] = this.sortOrders[key] * -1 } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped=""> #yhkimgrid {padding-top:10px} table { border: 2px solid #42b983; border-radius: 3px; background-color: #fff; } th { background-color: #42b983; color: rgba(255,255,255,0.66); cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } td { background-color: #f9f9f9; } th, td { min-width: 120px; padding: 10px 20px; } th.active { color: #fff; } th.active .arrow { opacity: 1; } .arrow { display: inline-block; vertical-align: middle; width: 0; height: 0; margin-left: 5px; opacity: 0.66; } .arrow.asc { border-left: 4px solid transparent; border-right: 4px solid transparent; border-bottom: 4px solid #fff; } .arrow.dsc { border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 4px solid #fff; } </style> |
<div id="User"> <form id="search"> Search <input id="queryinput" name="query" v-model="searchQuery"> </form> <yhgrid :data="gridData" :columns="gridColumns" :filter-key="searchQuery"></yhgrid> </div> </template> <script> import axios from 'axios' import yhgrid from '@/components/Grid' export default { name: 'User', components: { pnpgrid }, data () { return { searchQuery: '', gridColumns: ['idx', 'name', 'id', 'email', 'cellphone'], gridData:[] } }, created(){ this.load() }, methods:{ load(){ axios.get('http://testip/firstproject/api/userlist') .then(res => { this.gridData = res.data; }).catch(e => { console.error(e) }) } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped=""> #queryinput {width:310px; margin-left: 10px} </style> |
@RestController public class APIController { @Autowired MemberService service; @RequestMapping(value="/api/userlist", method=RequestMethod.GET) public ListgetUserList() { return service.getMemberList(); } }