RealGrid2 튜토리얼
Vue Component 튜토리얼
Vue에서 커스텀렌더러 적용하기

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)