https://vuejs.org/examples/#cells > Vue_JS 뷰

Vue_JS 뷰

Examples https://vuejs.org/examples/#cells

페이지 정보

본문

https://vuejs.org/examples/#cells


-------------


<!--

https://eugenkiss.github.io/7guis/tasks/#cells

-->


<script>

import Cell from './CellKim.vue'

import { cells } from './store.js'


export default {

  components: {

    Cell

  },

  data() {

    return {

      cols: cells.map((_, i) => String.fromCharCode(65 + i)),

      cells

    }

  }

}

</script>


<template>

  <table>

    <thead>

      <tr>

        <th></th>

        <th v-for="c in cols" v-bind:key="c">{{ c }}</th>

      </tr>

    </thead>

    <tbody>

      <tr v-for="i in cells[0].length" v-bind:key="i">

        <th>{{ i - 1 }}</th>

        <td v-for="(c, j) in cols" v-bind:key="c">

          <Cell :r="i - 1" :c="j"></Cell>

        </td>

      </tr>

    </tbody>

  </table>

</template>


<style>

body {

  margin: 0;

}


table {

  border-collapse: collapse;

  table-layout: fixed;

  width: 100%;

}


th {

  background-color: #eee;

}


tr:first-of-type th {

  width: 100px;

}


tr:first-of-type th:first-of-type {

  width: 25px;

}


td {

  border: 1px solid #ccc;

  height: 1.5em;

  overflow: hidden;

}

</style>


--------------------


CellKim.vue


<script>

import { cells, evalCell } from './store.js'


export default {

  props: {

    c: Number,

    r: Number

  },

  data() {

    return {

      editing: false,

      cells

    }

  },

  methods: {

    evalCell,

    update(e) {

      this.editing = false

      cells[this.c][this.r] = e.target.value.trim()

    }

  }

}

</script>


<template>

  <div class="cell" :title="cells[c][r]" @click="editing = true">

    <input

      v-if="editing"

      :value="cells[c][r]"

      @change="update"

      @blur="update"

      @vnode-mounted="({ el }) => el.focus()"

    />

    <span v-else>{{ evalCell(cells[c][r]) }}</span>

  </div>

</template>


<style>

.cell, .cell input {

  height: 1.5em;

  line-height: 1.5;

  font-size: 15px;

}


.cell span {

  padding: 0 6px;

}


.cell input {

  width: 100%;

  box-sizing: border-box;

}

</style>


----------------


store.js 


import { reactive } from 'vue'


const COLS = 5

const ROWS = 20


export const cells = reactive(

  Array.from(Array(COLS).keys()).map((i) => // eslint-disable-line no-unused-vars

    Array.from(Array(ROWS).keys()).map((i) => '') // eslint-disable-line no-unused-vars

  )

)


// adapted from https://codesandbox.io/s/jotai-7guis-task7-cells-mzoit?file=/src/atoms.ts

// by @dai-shi

export function evalCell(exp) {

  if (!exp.startsWith('=')) {

    return exp

  }


  // = A1 + B2 ---> get(0,1) + get(1,2)

  exp = exp

    .slice(1)

    .replace(

      /\b([A-Z])(\d{1,2})\b/g,

      (_, c, r) => `get(${c.charCodeAt(0) - 65},${r})`

    )


  try {

    return new Function('get', `return ${exp}`)(getCellValue)

  } catch (e) {

    return `#ERROR ${e}`

  }

}


function getCellValue(c, r) {

  const val = evalCell(cells[c][r])

  const num = Number(val)

  return Number.isFinite(num) ? num : val

}