Vue CustomRenderer로 뷰 컴포넌트 버튼 적용하기
Vue에서 CustomRenderer로 뷰 컴포넌트 버튼(스위치)을 적용하는 예제입니다.
//switch.vue
<template>
<label class="switch">
<input type="checkbox" :checked="$props.checked">
<div class="slider round"></div>
</label>
</template>
<script setup lang="ts">
defineProps({
checked: {
type: Boolean,
default: true
}
})
</script>
//RealGrid.vue
<template>
<div style="height: 500px; width: 100%">
<RealGridVue ref="grid" :rows="gridData" :onCellItemClicked="onCellItemClicked">
<RGDataField fieldName="boolean1" :dataType="RealGrid.ValueType.BOOLEAN"/>
<RGDataField fieldName="Name" :dataType="RealGrid.ValueType.TEXT"/>
<RGDataField fieldName="FullName" :dataType="RealGrid.ValueType.TEXT"/>
<RGDataField fieldName="Age" :dataType="RealGrid.ValueType.NUMBER"/>
<RGDataField fieldName="Company" :dataType="RealGrid.ValueType.TEXT"/>
<RGDataField fieldName="Email" :dataType="RealGrid.ValueType.TEXT"/>
<RGDataColumn name="boolean1" fieldName="boolean1" :renderer="{
type: 'toggle',
}"/>
<RGDataColumn name="Name" fieldName="Name"/>
<RGDataColumn name="FullName" fieldName="FullName"/>
<RGDataColumn name="Age" fieldName="Age"/>
<RGDataColumn name="Company" fieldName="Company"/>
<RGDataColumn name="Email" fieldName="Email"/>
</RealGridVue>
</div>
</template>
<script setup lang="ts">
import * as RealGrid from 'realgrid'
import { rows } from "./realgrid-data";
import { h, onMounted, ref, render, type VNode } from 'vue';
import ToggleButton from '../components/Switch.vue'
import { RealGridVue, RGDataColumn, RGDataField } from "realgrid-vue";
const grid = ref<RealGridVue | null>()
const gridData = ref(rows)
onMounted(() => {
if (grid.value) {
grid.value.gridView.registerCustomRenderer("toggle", toggle);
}
})
const toggle: RealGrid.CustomCellRenderer = {
initContent(dom) {
const dataRow = this.index!.dataRow;
const dataField = "boolean1";
this.tags = {};
this.tags.vNode = h(ToggleButton, {dataRow, dataField, checked: false, key: Symbol(dataRow)});
this.tags.div = dom;
},
clearContent(dom) {
const vNode: VNode = this.tags!.vNode;
vNode && vNode.el && vNode.el.parentElement === dom && dom.removeChild(vNode.el as HTMLElement)
delete this.tags!.vNode;
},
render(grid, model, w, h, info) {
const vNode: VNode = this.tags!.vNode;
// console.log(vNode.props);
if (vNode.component) {
const component = vNode.component;
component.props.checked = !!model.item!.getData!("boolean1");
component.update();
} else {
vNode.props!.checked = !!model.item!.getData!("boolean1");
render(vNode, this.tags!.div)
}
},
canClick(event) {
return true;
},
click(event) {
if (event.target instanceof HTMLElement) {
if (event.target.classList.contains('slider')) {
return {
vueComponent: event.target
}
}
}
},
preventClick(event) {
event.preventDefault();
event.stopPropagation();
return true;
},
}
function onCellItemClicked(grid: RealGrid.GridBase, index: RealGrid.CellIndex): boolean {
if (!grid.isEditing() && (index.column as RealGrid.DataColumn).name === "boolean1") {
grid.setValue(index.itemIndex!, "boolean1", !grid.getValue(index.itemIndex!, "boolean1"));
return false;
}
return true;
}
</script>.switch {
position: relative;
display: inline-block;
width: 40px;
height: 20px;
}
.switch input {
display: none;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 2px;
bottom: 2px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked + .slider {
background-color: #101010;
}
input:focus + .slider {
box-shadow: 0 0 1px #c0a5a5;
}
input:checked + .slider:before {
transform: translateX(20px);
}
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}해당 예제는 아래 링크에서 전체 소스코드르 확인하실 수 있습니다.
https://github.com/realgrid/realgrid2-examples/tree/master/vue3-customRenderer (opens in a new tab)