AIに古いDOM操作のhtmlコードをVue.js版のコードにリファクタリングしてもらいました。

　久しぶりの投稿です。
　AIとのコーディングの威力を実感しました。
　18年ほど前にJavaScriptでDOM操作する習作プログラムを作りました。
背景の変更や選択した品物と個数の金額を計算・表示するhtmlファイルです。

　これをGoogleの生成AI Gemini1.5Pro に、Vue.js を使う方式に改良するように依頼すると、ほんの数秒で完成させました。あまりの呆気なさに何という時代だろうと呆然とするしかありませんでした。動作を確かめるとすぐに動きました。

　10年一昔といいますから、変化するのは当然ですが、新技術を追いかけるばかりではなく、新技術を知ったらそれをAI活用やAPI採用などで取り込むのが当たり前の時代だと痛感します。

 　ただ、インタプリタ型のjavascriptが形を変えつつも20年近く生き残っていることも示しているので、その点も諸行無常の中の不易流行、色即是空、諸法空相を顕わしていて、考えるところがあります。
　おもむろに私はあとからフロントエンドフレームワークのコード解析をするわけです。

 # 1 元のインタラクティブWebページ
 ```html:kotaerupage1.html
<html>
<head>
<title>
反応するホームページ
</title>
<meta http-equiv="Content-Type" content="text/html: charset=Shift_JIS">
<script language="JavaScript">
<!--

iroban=new Array();
iroban[0]="#ccffff"; //  水　色
iroban[1]="#ffccff"; //  桃　色
iroban[2]="#99ff99"; //  黄緑色
iroban[3]="#ffffcc"; //  クリーム色

function rdoiro_changed(){
  var flag = 1; 
  var i; 
  for(i = 0; i < 4; i ++){ 
    if(document.f1.rdoiro[i].checked){ 
      flag = 0; break; 
    }
  }
//  alert(document.f1.rdoiro[i].value);
  document.bgColor=iroban[i];
}


function btnJikkou_onClick(){
  var kotae = 5000;
  kotae = document.f1.slctChuumon.value * document.f1.txtKosuu.value;
  if(document.f1.chkZei.checked)  kotae=kotae*1.05;
  document.getElementById("divKotae").innerHTML = 
     "<font size=8 color=&ldquo#9999ff&ldquo><center>" + "ご注文金額は " 
     + kotae + " 円です。</center></font>";
}

//-->
</script>
</head>
<body bgcolor="#ffffcc">
  <center>
  <h1>
  双方向（インタラクティブ）のホームページ<br>
  </h1>
  </center>
  <br>
  <form name="f1" id="f1">
　　背&nbsp景&nbsp色&nbsp選&nbsp択：
  <input name="rdoiro" id="rdoiro" type="radio" value="0" checked onClick="rdoiro_changed();" >
水　色　　
  <input name="rdoiro" id="rdoiro" type="radio" value="1" onClick="rdoiro_changed();" >桃　色　　
  <input name="rdoiro" id="rdoiro" type="radio" value="2" onClick="rdoiro_changed();" >黄緑色　　
  <input name="rdoiro" id="rdoiro" type="radio" value="3" onClick="rdoiro_changed();" >クリーム色<br>
  <br>
  <div name="divKotae" id="divKotae"></div>
  <br>
　　注&nbsp文&nbsp選&nbsp択&nbsp&nbsp：
  <select id="slctChuumon">
    <option value="500">オムライス</option>
    <option value="800">ハンバーグランチ</option>
    <option value="600">スパゲッティー</option>
    <option value="700" >カツ丼</option>
  </select>
  <br>
  <br>
　　　個　　数　　：&nbsp&nbsp&nbsp<input id="txtKosuu" type="text" size="5" value="1" >&nbsp個<br>
  <br>
　　税込みチェック：<input name="chkZei" type="checkbox" value="bumbougu"><br>
  <br>
　　　　<input id="btnJikkou" type="button" value="合図ボタン" onClick="btnJikkou_onClick();" >　　　　
  <input type="reset" value="元通りボタン" onClick="location.reload();">
  <br>
  <br>
　　<input type="button" value="前のページへ戻る" onclick="history.back()">
</form>

</body>
</html>
```
# 2 今風のVue.js活用のインタラクティブWebページ
```html:kotaerupage_Vuejs.html
 <!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>反応するホームページ</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
  <div id="app">
    <center>
      <h1>双方向（インタラクティブ）のホームページ</h1>
    </center>
    <br>
    背景色選択：
    <div v-for="(color, index) in colors" :key="index">
      <label>
        <input type="radio" v-model="backgroundColorIndex" :value="index">
        {{ color.name }}
      </label>
    </div>
    <br>
    <div v-html="orderMessage"></div>
    <br>
    注文選択：
    <select v-model.number="selectedOrder">
      <option v-for="item in menuItems" :key="item.value" :value="item.value">
        {{ item.name }}
      </option>
    </select>
    <br><br>
    個数： <input type="number" v-model.number="quantity" min="1"> 個
    <br><br>
    税込みチェック： <input type="checkbox" v-model="includeTax">
    <br><br>
    <button @click="calculateOrder">合図ボタン</button>
    <button @click="resetForm">元通りボタン</button>
    <br><br>
    <button @click="goBack">前のページへ戻る</button>
  </div>

  <script>
    new Vue({
      el: '#app',
      data: {
        colors: [
          { name: '水色', value: '#ccffff' },
          { name: '桃色', value: '#ffccff' },
          { name: '黄緑色', value: '#99ff99' },
          { name: 'クリーム色', value: '#ffffcc' }
        ],
        backgroundColorIndex: 3, // 初期値はクリーム色
        menuItems: [
          { name: 'オムライス', value: 500 },
          { name: 'ハンバーグランチ', value: 800 },
          { name: 'スパゲッティー', value: 600 },
          { name: 'カツ丼', value: 700 }
        ],
        selectedOrder: 500, // 初期値はオムライス
        quantity: 1,
        includeTax: false,
        orderMessage: ''
      },
      watch: {
        backgroundColorIndex: function(newIndex) {
          document.body.style.backgroundColor = this.colors[newIndex].value;
        }
      },
      mounted() {
        document.body.style.backgroundColor = this.colors[this.backgroundColorIndex].value;
      },
      methods: {
        calculateOrder: function() {
          let total = this.selectedOrder * this.quantity;
          if (this.includeTax) {
            total *= 1.05;
          }
          this.orderMessage = `<font size="8" color="#9999ff"><center>ご注文金額は ${total} 円です。</center></font>`;
        },
        resetForm: function() {
          this.selectedOrder = 500;
          this.quantity = 1;
          this.includeTax = false;
          this.orderMessage = '';
          this.backgroundColorIndex = 3; // 背景色もリセット
        },
        goBack: function() {
          history.back();
        }
      }
    });
  </script>
</body>
</html>
```

 # 3 ReacT活用のインタラクティブページ
 ```jsx:App.js
import React, { useState, useEffect } from 'react';

function App() {
  const colors = [
    { name: '水色', value: '#ccffff' },
    { name: '桃色', value: '#ffccff' },
    { name: '黄緑色', value: '#99ff99' },
    { name: 'クリーム色', value: '#ffffcc' }
  ];
  const menuItems = [
    { name: 'オムライス', value: 500 },
    { name: 'ハンバーグランチ', value: 800 },
    { name: 'スパゲッティー', value: 600 },
    { name: 'カツ丼', value: 700 }
  ];

  const [backgroundColorIndex, setBackgroundColorIndex] = useState(3);
  const [selectedOrder, setSelectedOrder] = useState(500);
  const [quantity, setQuantity] = useState(1);
  const [includeTax, setIncludeTax] = useState(false);
  const [orderMessage, setOrderMessage] = useState('');

  useEffect(() => {
    document.body.style.backgroundColor = colors[backgroundColorIndex].value;
  }, [backgroundColorIndex]);

  const calculateOrder = () => {
    let total = selectedOrder * quantity;
    if (includeTax) {
      total *= 1.05;
    }
    setOrderMessage(
      <font size="8" color="#9999ff">
        <center>ご注文金額は {total} 円です。</center>
      </font>
    );
  };

  const resetForm = () => {
    setSelectedOrder(500);
    setQuantity(1);
    setIncludeTax(false);
    setOrderMessage('');
    setBackgroundColorIndex(3);
  };

  const goBack = () => {
    window.history.back();
  };

  return (
    <div>
      <center>
        <h1>双方向（インタラクティブ）のホームページ</h1>
      </center>
      <br />
      背景色選択：
      {colors.map((color, index) => (
        <label key={index}>
          <input
            type="radio"
            value={index}
            checked={backgroundColorIndex === index}
            onChange={() => setBackgroundColorIndex(index)}
          />
          {color.name}
        </label>
      ))}
      <br />
      <div>{orderMessage}</div>
      <br />
      注文選択：
      <select value={selectedOrder} onChange={e => setSelectedOrder(Number(e.target.value))}>
        {menuItems.map(item => (
          <option key={item.value} value={item.value}>
            {item.name}
          </option>
        ))}
      </select>
      <br /><br />
      個数： <input type="number" value={quantity} onChange={e => setQuantity(Number(e.target.value))} min="1" /> 個
      <br /><br />
      税込みチェック： <input type="checkbox" checked={includeTax} onChange={e => setIncludeTax(e.target.checked)} />
      <br /><br />
      <button onClick={calculateOrder}>合図ボタン</button>
      <button onClick={resetForm}>元通りボタン</button>
      <br /><br />
      <button onClick={goBack}>前のページへ戻る</button>
    </div>
  );
}

export default App;
```