先月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ライブラリも一緒にインストールします。
1 2 3 4 |
$ npx nuxi init primevue-sample $ cd primevue-sample $ npm i $ npm i primevue@^3 primeicons primeflex --save |
設定
プラグイン設定
vueプラグインとして設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
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を指定すれば変更できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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のコンポーネントを使ってみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<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/
コメント