レンサバで php+Vue3(ローカル開発編)#01
Chat Gptさんのお力を借りて、CDNではない方法でvueを導入しました。
cli、vite、dev 、build など不明だったことが少しづつ解ってきました。
導入から開発中の現在までの流れを記録し公開します。
開発環境は、Windows11 で VSCode を使用しています。
node.js のインストール
1 Node.js公式サイトから「Installer」をダウンロードし、実行する。
2. コマンドプロンプトでコマンドを実行してバージョンを確認する。
node -v
npm -v
VUEのプロジェクト作成
npm create vite@latest myapp --template vue
npm 依存パッケージをインストール
cd myapp //プロジェクト内に移動する
npm install //依存パッケージをインストール
npm run dev //開発サーバーを起動する
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 にソートを追加
<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
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>
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>