ã²ãã³ãã«æ°è¦ã§Nuxtã¢ããªãä½ããã¨æã£ããã
ããããå¤ãã£ã¦ããã®ã§ãåå¿ç¨ã®ã¾ã¨ãã
(æéããªãã£ãã®ã§å²ã¨éã...ãã¤ããããã«å çããäºå®...)
ã½ã¼ã¹ã³ã¼ã
èªåç¨ã®ã¹ã¿ã¼ã¿ã«ãªãããã«GitHubã§å ¬éãã¦ã¿ãã (ãã®è¨äºã®å·çæãããå¤ãã£ã¦ããã¨æãã¾ã...)
ããã¸ã§ã¯ãä½æ
# éå½¢ã®ä½æ $ npx create-nuxt-app <project_name> # Gitã¨GitFlowã®åæå $ cd <project_name> $ git init $ git flow init # giboã§gitignoreãçæ $ gibo dump Vim macOS VisualStudioCode Node > .gitignore # remoteã®è¨å® $ git remote add origin [email protected]:memory-lovers/<project_name>.git $ git push -u origin --all
åè: ã»ã¤ã³ã¹ãã¼ã« - NuxtJS ã»simonwhitaker/gibo: Easy access to gitignore boilerplates
TypeScriptã®è¨å®(ãã«ã)
ããã±ã¼ã¸ã®ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev @nuxt/typescript-build
nuxt.config.jsã®è¨å®
// nuxt.config.js export default { buildModules: ['@nuxt/typescript-build'] }
tsconfig.jsonã®ä½æ
// tsconfig.json { "compilerOptions": { "target": "esnext", "module": "esnext", "moduleResolution": "node", "lib": ["esnext", "esnext.asynciterable", "dom"], "esModuleInterop": true, "allowJs": true, "sourceMap": true, "strict": true, "noEmit": true, "baseUrl": ".", "paths": { "~/*": ["./*"], "@/*": ["./*"] }, "types": ["@types/node", "@nuxt/types"] }, "exclude": ["node_modules"] }
TypeScriptã®è¨å®(ã©ã³ã¿ã¤ã )
ããã±ã¼ã¸ã®ã¤ã³ã¹ãã¼ã«
$ npm install @nuxt/typescript-runtime
package.jsonã§nuxt-tsã使ãããã«å¤æ´
"scripts": { - "dev": "nuxt", - "build": "nuxt build", - "start": "nuxt start", - "generate": "nuxt generate" + "dev": "nuxt-ts", + "build": "nuxt-ts build", + "start": "nuxt-ts start", + "generate": "nuxt-ts generate" },
nuxt.configãtså
ãã¡ã¤ã«åã.jsãã.tsã«å¤ãã¤ã¤ãä¸èº«ãå¤ããã
æã¯NuxtConfiguration
ã ã£ããã©ãConfiguration
ã«å¤ãã£ã¦ããã
+import { Configuration } from "@nuxt/types"; +require("dotenv").config(); -export default { +const config: Configuration = { mode: "universal", }; +export default config;
nuxt-property-decoratorãå ¥ãã
Nuxt TypeScriptã®Cookbookã«ããã³ã³ãã¼ãã³ãããã
Class APIããããªã®ã§ãnuxt-property-decoratorãå
¥ãã
# See: https://typescript.nuxtjs.org/ja/cookbook/components/#script $ npm install nuxt-property-decorator
ãã³ã¬ã¼ã¿ã使ãå ´åã¯ãexperimentalDecorators
ãæå¹ã«ããå¿
è¦ãããã®ã§ã
tsconfig.jsonãå¤æ´ããã
// tsconfig.json
{
"compilerOptions": {
+ "experimentalDecorators": true,
},
}
Vuexã§åã使ããããã«vuex-module-decoratorsãå ¥ãã
å ¬å¼ã¬ã¤ãã®ã¹ãã¢ã®ãã¼ã¸ã«ãããªä¸æãã
æã人æ°ã®ããã¢ããã¼ãã®1ã¤ã¯vuex-module-decoratorsã§ãã- ã¬ã¤ããåç §ãã¦ãã ããã
ãã®è¨äºãããããããã£ãã ã»Nuxt.js + Typescript + Vuexããç¾æç¹ã®ãã¹ãã¨æãæ¹æ³ - Qiita
ã¹ãã¢ã®ã¢ã¸ã¥ã¼ã«ãä½æãã
ã¾ãã¯ãã¢ã¸ã¥ã¼ã«ãä½æã
// ~/store/user.ts import { Module, VuexModule, Mutation, Action } from "vuex-module-decorators"; // Stateã®åãå®ç¾©ãã export interface UserState { uid: string | null; } // ãã³ã¬ã¼ã¿ãè¨å®ãnameã«ã¢ã¸ã¥ã¼ã«åãæå®ãããUserStateãç¶æ¿ãã @Module({ stateFactory: true, namespaced: true, name: "user" }) export default class UserModule extends VuexModule implements UserState { uid: string | null = null; // getterã¯ãã³ã¬ã¼ã¿ãªãã®getã¢ã¯ã»ãµã§æ¸ã get isLogin(): boolean { return this.uid != null; } // mutationã¯ãã³ã¬ã¼ã¿ã§æå® @Mutation setUser(uid: string | null) { this.uid = uid; } // actionããã³ã¬ã¼ã¿ã§æå® @Action async login(uid: string | null) { // thisã§mutationãå¼ã¹ã this.setUser(uid); } }
ã¹ãã¢ãåãã¾ã¨ããUtilã¯ã©ã¹ãä½æãã
ã¹ãã¢ã®åæåã¨åå¾ããUtilã¯ã©ã¹ãç¨æã
ã¢ã¸ã¥ã¼ã«ãå¢ããã¨ãã®ã¯ã©ã¹ãå¢ããã¦ããã
// ~/utils/store-accessor.ts import { Store } from "vuex"; import { getModule } from "vuex-module-decorators"; import UserModule from "~/store/user"; let userStore: UserModule; // ã¹ãã¢ãåæåããé¢æ°ãrootã®storeãåãåã£ã¦ãã¢ã¸ã¥ã¼ã«ãåæåãã function initialiseStores(store: Store<any>): void { // userStoreã¯ããã§åæåã userStore = getModule(UserModule, store); } export { initialiseStores, userStore };
store/index.tsãä½æ
æå¾ã«ãstore/index.ts
ã«ãstore-accessor.tsã®initialiseStores()ãå¼ã³åºãããã«ããã
ä¸åº¦æ¸ããããåºæ¬å¤æ´ãããã¨ã¯ãªãããã
// ~/store/index.ts import { Store } from 'vuex' import { initialiseStores } from '~/utils/store-accessor' // Vuexã®ãã©ã°ã¤ã³ãå©ç¨ãã¦åæåãã const initializer = (store: Store<any>) => initialiseStores(store) export const plugins = [initializer] export * from '~/utils/store-accessor'
ã³ã³ãã¼ãã³ããã使ã£ã¦ã¿ã
æºåã¯ä¸ã®3ã¤ã§å®äºã使ãæ¹ã¯ã¢ã¸ã¥ã¼ã«ãimportãã¦ä½¿ãã£ã½ãã
import { Component, Vue, Prop } from "nuxt-property-decorator"; import { userStore } from "~/store"; @Component export default class LoginPage extends Vue { private async onClickLogin(uid:string) { await userStore.setUser(uid); } }
ã¢ã¸ã¥ã¼ã«ããã®ã¾ã¾å¼ã¶ã®ã§ãåããã®ã¾ã¾ä½¿ãã!!
ãã¡ããã$store
ã§ã使ãã(´Ïï½)
SASSã¨Buefyã®è¨å®
Buefyã®ãã¼ããSASSã§ã«ã¹ã¿ãã¤ãºãããã®ã§è¨å®ãã¦ããã
ã¨ãããããSASS loarderãã¤ã³ã¹ãã¼ã«
$ npm install --save-dev node-sass sass-loader
buefyç¨ã®scssãç¨æ(assets/css/buefy.scss
)
// Import Bulma's core @import "~bulma/sass/utilities/_all"; // Set your colors $primary: #ff99a3; $primary-invert: findColorInvert($primary); $twitter: #4099ff; $twitter-invert: findColorInvert($twitter); // Setup $colors to use as bulma classes (e.g. 'is-twitter') $colors: ( "white": ( $white, $black ), "black": ( $black, $white ), "light": ( $light, $light-invert ), "dark": ( $dark, $dark-invert ), "primary": ( $primary, $primary-invert ), "info": ( $info, $info-invert ), "success": ( $success, $success-invert ), "warning": ( $warning, $warning-invert ), "danger": ( $danger, $danger-invert ), "twitter": ( $twitter, $twitter-invert ) ); // Links $link: $primary; $link-invert: $primary-invert; $link-focus-border: $primary; // Fottoer $footer-background-color: $primary; // Import Bulma and Buefy styles @import "~bulma"; @import "~buefy/src/scss/buefy";
ã¤ãã§ã«ãpage-transitionç¨ã®scssãç¨æ(assets/css/transition.scss
)
// page transiton: slide-fade .page-enter-active, .layout-enter-active { transition: all 0.3s ease; } .page-leave-active, .layout-leave-active { transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); } .page-enter, .page-leave-to, .layout-enter, .layout-leave-to { transform: translateX(30px); opacity: 0; }
æå¾ã«ãnuxt.config.tsã«è¨å®ã
const config: Configuration = { /* ** Global CSS */ - css: [], + css: ["~/assets/css/buefy.scss", "~/assets/css/transition.scss"], ... + + /** + * nuxt-buefy + * Doc: https://github.com/buefy/nuxt-buefy + * Doc: https://buefy.org/documentation/constructor-options + */ + buefy: { + css: false + }, +
Firebaseãå©ç¨ã§ããããã«ãã
Firebase Authã¨Firebase Cloudstoreã使ãã®ã§ããã®è¨å®ããã¦ããã
ã¾ãã¯ãããã±ã¼ã¸ã®ã¤ã³ã¹ãã¼ã«.
$ npm install --save firebase
次ã«ã.dotenv
ãã¡ã¤ã«ãç¨æ
BASE_URL=http://localhost:3000 API_KEY='AIXXXXXXXXXXXXXXXXXXXXXXXX' AUTH_DOMAIN='hogefuga.firebaseapp.com' DATABASE_URL='https://hogefuga.firebaseio.com' PROJECT_ID='hogefugao' STORAGE_BUCKET='hogefuga.appspot.com' MESSAGING_SENDER_ID='123456789' APP_ID='1:123456789:web:abcde1234' MEASUREMENT_ID='G-AAAAAA'
åè: - [Nuxt.js] Firebaseã®è¨å®ã§ç°å¢å¤æ°dotenvãæ±ã - Qiita
firebaseãåæåããpluginãä½æ(plugins/firebase.ts
)
//firebase.ts import * as firebase from "firebase/app"; import "firebase/auth"; import "firebase/firestore"; if (!firebase.apps.length) { firebase.initializeApp({ apiKey: process.env.API_KEY, authDomain: process.env.AUTH_DOMAIN, databaseURL: process.env.DATABASE_URL, projectId: process.env.PROJECT_ID, storageBucket: process.env.STORAGE_BUCKET, messagingSenderId: process.env.MESSAGING_SENDER_ID, appId: process.env.APP_ID, measurementId: process.env.MEASUREMENT_ID }); firebase.auth().useDeviceLanguage(); } export default firebase;
ãããnuxt.config.tsã«è¨å®
const config: Configuration = { /* ** Plugins to load before mounting the App */ - plugins: [], + plugins: ["~/plugins/firebase.ts"],
Firebase Authã®ä¾¿å©ã¯ã©ã¹ãç¨æ
èªè¨¼ããã§ãã¯ãã便å©ã¯ã©ã¹ããã使ãã®ã§ãç¨æãã¦ããã
èªè¨¼ç¶æ ã®å¤æ´ãã§ãã¯é¢æ°
// plugins/authState.ts import firebase from "~/plugins/firebase"; export default function(): Promise<firebase.User | null> { return new Promise(function(resolve, reject) { firebase.auth().onAuthStateChanged(function(user) { resolve(user || null); }); }); }
æªèªè¨¼ã®å ´åããã°ã¤ã³ç»é¢ã«ãªãã¤ã¬ã¯ãããmiddleware
// middleware/checkAuthed.ts import authState from "~/plugins/authState"; export default async function({ store, redirect }) { try { // ãããªæãã®ãã¨ãæ¸ãããã®ã¾ã¾ã ã¨ç¡éã«ã¼ããã... // if (!!store.getters["user/isLogin"]) return; // redirect({ name: "login" }); } catch (e) { console.error(`error=${e}`, e); return; } }
nuxt.config.tsã«ã追å
import { Configuration } from "@nuxt/types";
require("dotenv").config();
const config: Configuration = {
router: {
+ middleware: ["checkAuthed"]
},
}
ãããã«
ã ããããã¤ããããªæãã®ãã¨ããã¦ããã
ã²ãã³ãã«å
¬å¼ããã¥ã¡ã³ããã¿ãã¨ãæ°ããããæ¹ãå¢ãã¦ããã®ã§ã
å®æçã«æ¯ãè¿ã£ã¦ã¾ã¨ããã®å¤§äº...
ã¾ããã¿ã¤ãã³ã°è¦ã¦ãæ´æ°ã»è¿½è¨ãã¦ããäºå®...
以ä¸!!