先月2022/11にNuxt3のstable版がリリースがされ、いよいよNuxt3を積極的に使っていける状況となりました🎉
今回はvue3にも対応しているprimevueというフレームワークを使ってデザインをしてみます。primevueですが、GitHubのスター数を見ると以下のようになってます。
2022/12/9時点
| framework | fork | star | ライセンス |
| primevue | 598 | 3.1k | MIT |
| vuetify | 6.5k | 36k | MIT |
| daisyUI | 647 | 16k | MIT |
| bootstrap-vue | 1.9k | 14.1k | MIT |
他のUIフレームワークと比較してみました。よく知られているveutifyと比べるとスター数は決して多くはないのですが、primevueは用意されているコンポーネントが多く、個人的にお気に入りのUIフレームワークの1つです。
それでは、Nuxt3に導入して使ってみます。
インストール
primeflexというCSSライブラリも一緒にインストールします。
$ npx nuxi init primevue-sample $ cd primevue-sample $ npm i $ npm i primevue@^3 primeicons primeflex --save
設定
プラグイン設定
vueプラグインとして設定します。
import Avatar from 'primevue/avatar'
import AvatarGroup from 'primevue/avatargroup'
import Badge from 'primevue/badge'
import BadgeDirective from 'primevue/badgedirective'
import Button from 'primevue/button'
import Card from 'primevue/card'
import Carousel from 'primevue/carousel'
import Checkbox from 'primevue/checkbox'
import Chip from 'primevue/chip'
import Column from 'primevue/column'
import ColumnGroup from 'primevue/columngroup' // optional for column grouping
import PrimeVue from 'primevue/config'
import ConfirmationService from 'primevue/confirmationservice'
import ConfirmDialog from 'primevue/confirmdialog'
import ConfirmPopup from 'primevue/confirmpopup'
import DataTable from 'primevue/datatable'
import Dialog from 'primevue/dialog'
import Divider from 'primevue/divider'
import Dropdown from 'primevue/dropdown'
import Galleria from 'primevue/galleria'
import Image from 'primevue/image'
import InlineMessage from 'primevue/inlinemessage'
import InputSwitch from 'primevue/inputswitch'
import InputText from 'primevue/inputtext'
import Menu from 'primevue/menu'
import Menubar from 'primevue/menubar'
import Message from 'primevue/message'
import OrganizationChart from 'primevue/organizationchart'
import OverlayPanel from 'primevue/overlaypanel'
import Paginator from 'primevue/paginator'
import Password from 'primevue/password'
import ProgressBar from 'primevue/progressbar'
import ProgressSpinner from 'primevue/progressspinner'
import RadioButton from 'primevue/radiobutton'
import Rating from 'primevue/rating'
import Ripple from 'primevue/ripple'
import Row from 'primevue/row'
import SelectButton from 'primevue/selectbutton'
import Sidebar from 'primevue/sidebar'
import Skeleton from 'primevue/skeleton'
import Slider from 'primevue/slider'
import SplitButton from 'primevue/splitbutton'
import StyleClass from 'primevue/styleclass'
import TabMenu from 'primevue/tabmenu'
import Tag from 'primevue/tag'
import Textarea from 'primevue/textarea'
import TieredMenu from 'primevue/tieredmenu'
import Timeline from 'primevue/timeline'
import Toast from 'primevue/toast'
import ToastService from 'primevue/toastservice'
import ToggleButton from 'primevue/togglebutton'
import Toolbar from 'primevue/toolbar'
import Tooltip from 'primevue/tooltip'
const Locales: Record<string, any> = {
ja: {
weak: '弱い',
medium: '普通',
strong: '強い',
passwordPrompt: 'パスワードを入力',
aria: {
navigation: 'ナビゲーション',
},
},
}
export default defineNuxtPlugin((nuxtApp) => {
const locale = Locales["ja"];
nuxtApp.vueApp.use(PrimeVue, {
ripple: true,
locale,
});
// Messages
nuxtApp.vueApp.use(ToastService)
nuxtApp.vueApp.component('Toast', Toast)
nuxtApp.vueApp.component('Message', Message)
nuxtApp.vueApp.component('InlineMessage', InlineMessage)
// Form
nuxtApp.vueApp.component('Dropdown', Dropdown)
nuxtApp.vueApp.component('Checkbox', Checkbox)
nuxtApp.vueApp.component('InputText', InputText)
nuxtApp.vueApp.component('Textarea', Textarea)
nuxtApp.vueApp.component('Password', Password)
nuxtApp.vueApp.component('InputSwitch', InputSwitch)
nuxtApp.vueApp.component('RadioButton', RadioButton)
nuxtApp.vueApp.component('ToggleButton', ToggleButton)
nuxtApp.vueApp.component('Rating', Rating)
nuxtApp.vueApp.component('SelectButton', SelectButton)
nuxtApp.vueApp.component('Slider', Slider)
// Button
nuxtApp.vueApp.component('Button', Button)
nuxtApp.vueApp.component('SplitButton', SplitButton)
// Panel
nuxtApp.vueApp.component('Card', Card)
nuxtApp.vueApp.component('Divider', Divider)
nuxtApp.vueApp.component('Toolbar', Toolbar)
// Overlay
nuxtApp.vueApp.use(ConfirmationService)
nuxtApp.vueApp.component('ConfirmDialog', ConfirmDialog)
nuxtApp.vueApp.component('ConfirmPopup', ConfirmPopup)
nuxtApp.vueApp.component('OverlayPanel', OverlayPanel)
nuxtApp.vueApp.component('Dialog', Dialog)
nuxtApp.vueApp.component('Sidebar', Sidebar)
nuxtApp.vueApp.directive('tooltip', Tooltip)
// Data
nuxtApp.vueApp.component('Timeline', Timeline)
nuxtApp.vueApp.component('Paginator', Paginator)
nuxtApp.vueApp.component('DataTable', DataTable)
nuxtApp.vueApp.component('Column', Column)
nuxtApp.vueApp.component('ColumnGroup', ColumnGroup)
nuxtApp.vueApp.component('Row', Row)
nuxtApp.vueApp.component('DataView', DataView)
nuxtApp.vueApp.component('OrganizationChart', OrganizationChart)
// Media
nuxtApp.vueApp.component('Image', Image)
nuxtApp.vueApp.component('Galleria', Galleria)
nuxtApp.vueApp.component('Carousel', Carousel)
// Menu
nuxtApp.vueApp.component('Menu', Menu)
nuxtApp.vueApp.component('TabMenu', TabMenu)
nuxtApp.vueApp.component('Menubar', Menubar)
nuxtApp.vueApp.component('TieredMenu', TieredMenu)
// Misc
nuxtApp.vueApp.directive('styleclass', StyleClass)
nuxtApp.vueApp.directive('badge', BadgeDirective)
nuxtApp.vueApp.directive('ripple', Ripple)
nuxtApp.vueApp.component('ProgressBar', ProgressBar)
nuxtApp.vueApp.component('ProgressSpinner', ProgressSpinner)
nuxtApp.vueApp.component('Badge', Badge)
nuxtApp.vueApp.component('Chip', Chip)
nuxtApp.vueApp.component('Skeleton', Skeleton)
nuxtApp.vueApp.component('Tag', Tag)
nuxtApp.vueApp.component('Avatar', Avatar)
nuxtApp.vueApp.component('AvatarGroup', AvatarGroup)
})
上記では、使用するコンポーネントをimportして、vueコンポーネントとして使えるように登録しています。また、コンポーネントが内部で参照しているメッセージ表示のために一部Locale設定が必要です。もしコンポーネントを使用してエラーになるようであれば、都度Localeを編集すれば良いと思います。
参考:https://primefaces.org/primevue/locale
テーマ設定
デフォルトで使用できるテーマがいくつかあります。以下では、saba-blueというテーマを設定しています。テーマを変えたい場合は、nuxt.config.tsのcssセクションで該当するテーマのcssを指定すれば変更できます。
export default defineNuxtConfig({
typescript: {
shim: false,
},
build: {
transpile: ["primevue"],
},
css: [
"primevue/resources/themes/saga-blue/theme.css", // テーマ
"primevue/resources/primevue.css",
"primeicons/primeicons.css",
"primeflex/primeflex.css",
],
});
primevueのコンポーネントを使ってみます。
<script lang="ts" setup>
const username = ref("");
const password = ref("");
const login = () => {
console.log(username.value, password.value);
alert("ログイン");
};
const signup = () => {
alert("新規登録");
};
</script>
<template>
<div class="container">
<h2 class="text-center">ようこそ、サンプル</h2>
<div class="grid">
<div class="col-5 flex align-items-center justify-content-center">
<div class="p-fluid surface-ground p-5 border-round">
<div class="field">
<label for="username">ユーザー名</label>
<InputText id="username" type="text" v-model="username" />
</div>
<div class="field">
<label for="password">パスワード</label>
<InputText id="password" type="password" v-model="password" />
</div>
<Button label="ログイン" @click="login"></Button>
</div>
</div>
<div class="col-2">
<Divider layout="vertical"> または </Divider>
</div>
<div class="col-5 flex align-items-center justify-content-center">
<Button
label="新規登録"
icon="pi pi-user-plus"
class="p-button-success"
@click="signup"
></Button>
</div>
</div>
</div>
</template>
<style scoped>
.container {
width: 700px;
margin: auto;
}
</style>
参考ソース:https://primefaces.org/primevue/divider
サンプルを表示すると、以下のような感じで表示されることを確認できます。

参考リンク
- https://qiita.com/kensoz/items/6839fd47548f3609cb69
- https://blog.logrocket.com/best-ui-frameworks-vue-3/


コメント