見出し画像

レンサバで php+Vue3(ローカル開発編)#01

Chat Gptさんのお力を借りて、CDNではない方法でvueを導入しました。
cli、vite、dev 、build  など不明だったことが少しづつ解ってきました。
導入から開発中の現在までの流れを記録し公開します。

開発環境は、Windows11 で VSCode を使用しています。


node.js のインストール

Node.js公式サイトから「Installer」をダウンロードし、実行する。
2. コマンドプロンプトでコマンドを実行してバージョンを確認する。 

node -v
npm -v

VUEのプロジェクト作成

 npm create vite@latest myapp --template vue

npm 依存パッケージをインストール

cd myapp  //プロジェクト内に移動する
npm install   //依存パッケージをインストール
npm run dev  //開発サーバーを起動する
http://localhost:5173/ (開発サーバー)の表示結果

PrimeVue のインストール

npm install primevue primeicons
npm install primevue @primevue/themes

main.js の設定

import { createApp } from 'vue';
import './style.css'
import App from './App.vue'; // App コンポーネントをインポート
import PrimeVue from 'primevue/config';
import Aura from '@primevue/themes/aura';
const app = createApp(App);
app.use(PrimeVue, {
theme: {
preset: Aura
}
})
.mount('#app');

PrimeVue の DataTable を試す

src/App.vue を以下のように編集する。

<template>
 <div>
  <h3>PrimeVue DataTable Example</h3>
  <DataTable :value="products" style="width: 50rem">
   <Column field="name" header="Name"></Column>
   <Column field="price" header="Price"></Column>
   <Column field="category" header="Category"></Column>
  </DataTable>
 </div>
</template>

<script>
 import DataTable from 'primevue/datatable';
 import Column from 'primevue/column';
 
 export default {
  components: {
   DataTable,Column,
  },

  data() {
   return {
    products: [
     { name: 'Apple', price: '$1', category: 'Fruit' },
     { name: 'Carrot', price: '$0.5', category: 'Vegetable' },
     { name: 'Milk', price: '$2', category: 'Dairy' },
    ],
   };
  },
 };
</script>

<style scoped>
 body{
  display: block;
 }
</style>
DataTable の表示結果

DataTable にソートを追加

<Column>の中に sortable を追記する。

<DataTable :value="products" style="width: 50rem">
 <Column field="name" header="Name" sortable></Column>
 <Column field="price" header="Price" sortable></Column>
 <Column field="category" header="Category" sortable></Column> 
</DataTable>l
sortable の表示結果

DataTable にフィルターを追加

<template>
 <div>
 <h1>PrimeVue DataTable with Filters</h1>
 <DataTable
  v-model:filters="filters"
  :value="filteredProducts"
  dataKey="name"
  filterDisplay="row"
  :globalFilterFields="['name', 'price', 'category']"
 >
<template #header>
 <div class="flex justify-end">
  <span class="p-input-icon-left">
   <i class="pi pi-search" />
   <InputText v-model="filters['global'].value" placeholder="Keyword Search" />
  </span>
 </div>
</template>
<template #empty>No products found.</template>

<!-- Name Column -->
<Column field="name" header="Name" style="min-width: 12rem">
<template #body="{ data }">{{ data.name }}</template>
<template #filter="{ filterModel, filterCallback }">
 <InputText v-model="filterModel.value" type="text" @input="filterCallback()" placeholder="Search by name" />
</template>
</Column>

<!-- Price Column -->
<Column field="price" header="Price" style="min-width: 12rem">
<template #body="{ data }">{{ data.price }}</template>
<template #filter="{ filterModel, filterCallback }">
 <InputText v-model="filterModel.value" type="text" @input="filterCallback()" placeholder="Search by price" />
</template>
</Column>

<!-- Category Column -->
<Column field="category" header="Category" style="min-width: 12rem">
<template #body="{ data }">{{ data.category }}</template>
<template #filter="{ filterModel, filterCallback }">
<InputText v-model="filterModel.value" type="text" @input="filterCallback()" placeholder="Search by category" />
</template>
</Column>

</DataTable>
</div>
</template>

<script>
import DataTable from 'primevue/datatable';
import Column from 'primevue/column';
import InputText from 'primevue/inputtext';

export default {
 components: {
  DataTable,
  Column,
  InputText,
 },

 data() {
  return {
   products: [
    { name: 'Apple', price: '$1', category: 'Fruit' },
    { name: 'Carrot', price: '$0.5', category: 'Vegetable' },
    { name: 'Milk', price: '$2', category: 'Dairy' },
    { name: 'Banana', price: '$1.2', category: 'Fruit' },
    { name: 'Cheese', price: '$3', category: 'Dairy' },
    { name: 'Tomato', price: '$0.8', category: 'Vegetable' },
    { name: 'Strawberry', price: '$2.5', category: 'Fruit' },
    { name: 'Broccoli', price: '$1.5', category: 'Vegetable' },
    { name: 'Orange', price: '$1.3', category: 'Fruit' },
    { name: 'Butter', price: '$2.8', category: 'Dairy' },
    { name: 'Potato', price: '$0.9', category: 'Vegetable' },
   ],
   rows: 5, // 表示する行数
   filters: {
    global: { value: null, matchMode: 'contains' },
    name: { value: null, matchMode: 'contains' },
    price: { value: null, matchMode: 'contains' },
    category: { value: null, matchMode: 'contains' },
   },
  };
 },

 computed: {
  filteredProducts() {
   const globalFilter = this.filters.global?.value || '';
   if (globalFilter) {
    return this.products.filter((product) =>
     Object.values(product).some((value) =>
      value.toString().toLowerCase().includes(globalFilter.toLowerCase())
     )
    );
   }
   return this.products;
  },
 },
};
</script>
filter 実装の結果

Router をインストールして複数ページに挑戦

Vue Router のインストールをする

npm install vue-router@4  //vue3対応のルーター


Vue Router の設定ファイルを作成する
1. src 内に router フォルダを作成し、 index.js ファイルを配置する。

src/
├── router/
│   └── index.js


2. index.js

//index.js

import { createRouter, createWebHistory } from 'vue-router';
import Home from '../components/Home.vue'; // ホームページ用コンポーネント
import About from '../components/About.vue'; // 新しいページ用コンポーネント
const routes = [
{ path: '/', name: 'Home', component: Home },
{ path: '/about', name: 'About', component: About },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;


3. main.js に ルーターの情報を追記

//main.js

import { createApp } from 'vue';
import './style.css'
import App from './App.vue';
import PrimeVue from 'primevue/config';
import Aura from '@primevue/themes/aura';
import router from './router'; // ルーターをインポート

const app = createApp(App);
app.use(PrimeVue, {
theme: {
preset: Aura
}
});
app.use(router); // ルーターをユーズ
app.mount('#app');

components フォルダとファイルを作成

src/components 内にHome.vue と About.vue を作成する

src/ 
├── components/ 
│   ├── Home.vue 
│   ├── About.vue


Home.vue ( 元 App.vue )

<!-- Home.vue -->

<template>
 <div>
 <h1>PrimeVue DataTable with Filters</h1>
 <DataTable
  v-model:filters="filters"
  :value="filteredProducts"
  dataKey="name"
  filterDisplay="row"
  :globalFilterFields="['name', 'price', 'category']"
 >
<template #header>
 <div class="flex justify-end">
  <span class="p-input-icon-left">
   <i class="pi pi-search" />
   <InputText v-model="filters['global'].value" placeholder="Keyword Search" />
  </span>
 </div>
</template>
<template #empty>No products found.</template>

<!-- Name Column -->
<Column field="name" header="Name" style="min-width: 12rem">
<template #body="{ data }">{{ data.name }}</template>
<template #filter="{ filterModel, filterCallback }">
 <InputText v-model="filterModel.value" type="text" @input="filterCallback()" placeholder="Search by name" />
</template>
</Column>

<!-- Price Column -->
<Column field="price" header="Price" style="min-width: 12rem">
<template #body="{ data }">{{ data.price }}</template>
<template #filter="{ filterModel, filterCallback }">
 <InputText v-model="filterModel.value" type="text" @input="filterCallback()" placeholder="Search by price" />
</template>
</Column>

<!-- Category Column -->
<Column field="category" header="Category" style="min-width: 12rem">
<template #body="{ data }">{{ data.category }}</template>
<template #filter="{ filterModel, filterCallback }">
<InputText v-model="filterModel.value" type="text" @input="filterCallback()" placeholder="Search by category" />
</template>
</Column>

</DataTable>
</div>
</template>

<script>
import DataTable from 'primevue/datatable';
import Column from 'primevue/column';
import InputText from 'primevue/inputtext';

export default {
 components: {
  DataTable,
  Column,
  InputText,
 },

 data() {
  return {
   products: [
    { name: 'Apple', price: '$1', category: 'Fruit' },
    { name: 'Carrot', price: '$0.5', category: 'Vegetable' },
    { name: 'Milk', price: '$2', category: 'Dairy' },
    { name: 'Banana', price: '$1.2', category: 'Fruit' },
    { name: 'Cheese', price: '$3', category: 'Dairy' },
    { name: 'Tomato', price: '$0.8', category: 'Vegetable' },
    { name: 'Strawberry', price: '$2.5', category: 'Fruit' },
    { name: 'Broccoli', price: '$1.5', category: 'Vegetable' },
    { name: 'Orange', price: '$1.3', category: 'Fruit' },
    { name: 'Butter', price: '$2.8', category: 'Dairy' },
    { name: 'Potato', price: '$0.9', category: 'Vegetable' },
   ],
   rows: 5, // 表示する行数
   filters: {
    global: { value: null, matchMode: 'contains' },
    name: { value: null, matchMode: 'contains' },
    price: { value: null, matchMode: 'contains' },
    category: { value: null, matchMode: 'contains' },
   },
  };
 },

 computed: {
  filteredProducts() {
   const globalFilter = this.filters.global?.value || '';
   if (globalFilter) {
    return this.products.filter((product) =>
     Object.values(product).some((value) =>
      value.toString().toLowerCase().includes(globalFilter.toLowerCase())
     )
    );
   }
   return this.products;
  },
 },
};
</script>


About.vue (新ページ)

<!-- About.vue -->

<template>
 <div>
  <h1>About Page</h1>
  <p>This is the About Page!</p>
 </div>
</template>

<script>
export default {
name: 'About',
};
</script>

<style>
body{
display: block;
}
</style>


App.vue (ページ間で共通のナビゲーション)

<!-- App.vue -->

<template>
 <div>
  <nav>
   <ul>
    <li><router-link to="/">Home</router-link></li>
    <li><router-link to="/about">About</router-link></li>
   </ul>
  </nav>
  <router-view />
 </div>
</template>

<script>
 export default {
 name: 'App',
 };
</script>

<style>
 nav ul {
  list-style-type: none;
  padding: 0;
 }
 nav ul li {
  display: inline;
  margin-right: 10px;
 }
</style>
Home.vue の表示結果
About.vue の表示結果

App.vue の役割

1.ルートコンポーネント:
 Vue.js アプリケーション全体を管理するメインコンポーネント。
 他のページコンポーネント(Home.vue や About.vue)の親となる。
2.テンプレートの固定部分:
 ページ間で共通の(ナビゲーションやフッターなど)を記述する。
 ページの切り替え部分には <router-view> を配置する。
3.シングルページアプリケーション (SPA) 対応:
 Vue Router を使って複数のページを切り替える仕組みを提供する。
 ページ切り替え時にブラウザのリロードが発生しないのが特徴。


いいなと思ったら応援しよう!