# Nuxt 起手式筆記
紀錄一些在使用nuxt開發時,常使用的外掛和全域設定。
## 建立Nuxt專案
`npx create-nuxt-app <proj-name>`
## 使用 normalize.css in Nuxt projects
`npm install normalize.css`
在 nuxt.config.js 加入:
```javascript=
css: [
'normalize.css/normalize.css'
],
```
## 使用 dotenv
`npm i dotenv --save`
跟目錄建立.env檔
```env=
// .env
NUXT_API_URL=abc
```
```javascript=
/* nuxt.config */
const env = require("dotenv").config();
export default {
//...
env: env.parsed
//...
}
```
使用 `process.env.NUXT_API_URL`
[來源](https://codecourse.com/watch/using-env-files-with-nuxt?part=using-env-files-with-nuxt)
## Nuxt 使用圖片
### 在html(vue)檔內
```html=
<img src="@/assets/images/...">
```
### 在css檔內:
```css=
background: url(~assets/images/...);
```
重點:assets前沒有斜線 **`/`**,使用 **`~`** 。
### static資料夾內的圖片引用
```html=
<img src="/images/...">
```
直接使用 **`/`**
## Nuxt 使用 Swiper
安裝 [vue-awesome-swiper](https://github.com/surmon-china/vue-awesome-swiper)
全域使用,至plugins中建立nuxt-swiper-plugin.js,
```javascript=
import Vue from "vue";
import VueAwesomeSwiper from "vue-awesome-swiper";
import "swiper/dist/css/swiper.css";
// If used in nuxt.js/ssr, you should keep it only in browser build environment
if (process.browser) {
const VueAwesomeSwiper = require("vue-awesome-swiper/dist/ssr");
Vue.use(VueAwesomeSwiper);
}
Vue.use(VueAwesomeSwiper);
```
至 nuxt.config.js 引入
```javascript=
//...
plugins: [{ src: "~/plugins/nuxt-swiper-plugin.js", ssr: false }],
//...
```
[使用方法](https://github.com/icguanyu/zzcc-nuxt/blob/dev/components/HomePage/swiper.vue)
[vue-awesome-swiper](https://github.com/surmon-china/vue-awesome-swiper)
## 使用 sass/scss
`npm install --save-dev node-sass sass-loader`
### 1. 引用自己建立的 scss 檔
先建立檔案在 **`assets/scss/main.scss`**
### 2. 全域使用
```javascript=
/* nuxt.config.js */
export default {
css: [
// CSS file in the project
// '@/assets/css/main.css',
// SCSS file in the project
'@/assets/scss/main.scss'
]
}
```
> [資料來源](https://nuxtjs.org/api/configuration-css)
### 3. 模組內引用
```scss
<style lang="scss" scoped>
@import '@/assets/css/main.scss';
</style>
```
補充:
```scss
import './' // 同一層目錄開始找
import '../' // 上一層目錄開始找
import '@/' // src目錄下開始找
import '' // 直接打名稱則是node_modules
```
### 4. 使用變數
先建立檔案在 **`assets/vars/_colors.scss`**
```sass
$primary: green;
```
安裝 `npm i @nuxtjs/style-resources`
```javascript=
/* nuxt.config.js */
export default {
styleResources: {
scss: [
'./assets/vars/_colors.scss'
]
},
modules: ['@nuxtjs/style-resources'],
}
```
這樣就可以在整個專案中使用這些變數了。
> [資料來源](https://github.com/nuxt-community/style-resources-module)
>
## Vuex 相關
#### getters
* 常見 getters 基本用法:
```javascript=
export const getters = {
getUsers(state) {
return state.users
},
}
```
在 component 中使用
```javascript=
computed: {
users() {
// return this.$nuxt.$store.getters.users
return this.$store.getters['<module-name>/<getter-name>']
}
}
```
或
```javascript=
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['<module-name>/<getter-name>'])
}
}
```
> 看不懂後面中括號內容的話:可複習 [Vuex Store - Moudles Mode](https://nuxtjs.org/guide/vuex-store/)
* 帶入參數的 getters 用法
情境:我做了一份問卷,問題和答案存放在 store 內,我透過路徑取得 id (`this.$nuxt.$route.params.id`)後,想要到store得取第 `id` 筆的 (問題與答案) 資料。
components這邊的寫法:
```javascript=
export default {
computed: {
question() {
return this.$store.getters['quiz/getQuestion'](this.id)
},
answers() {
return this.$store.getters['quiz/getAnswers'](this.id)
}
}
}
```
在vuex這邊,先看我原本直覺的錯誤寫法:
```javascript=
getQuestion(state,id) {
//錯誤寫法
return state.questions[id - 1]
},
```
正確寫法 (重點在 **id 的位置**)
```javascript=
export const getters = {
// -1是純粹因為陣列序列關係 可忽略
getQuestion(state) {
return id => state.questions[id - 1]
},
getAnswers(state) {
return id => state.answers[id - 1]
},
}
```
[參考資料](https://github.com/vuejs/vuex/issues/688)
## 在 Nuxt 引入第三方套件(待商榷)
在 vue 裡面我們都曾經在 main.js 內引用第三方套件作為 global 使用,但 nuxt 沒有 main.js 這是剛從 vue 轉到nuxt 的人最常見的問題之一。
* 一般使用方式
安裝完成你的外掛後,直接在 components 中 import 使用
```javascript=
<script>
import example from 'example'
export default {
...
}
</script>
```
但如果要重複大量使用就不太適合。
* 建立 plugins/example.js
網路上的兩個範例影片,都是引入 vuetify 作為範例:
[Nuxt Plugins - How to use arbitrary Vue libraries in your NuxtJS app](https://www.youtube.com/watch?v=j7l5e2ID0aw)
[5 Nuxt JS beginner tutorial - Understanding Plugins in Nuxtjs](https://www.youtube.com/watch?v=lYgnsyRNMxA)
```javascript=
/* plugins/example.js*/
import Vue from 'vue';
import example from 'example';
/* 外掛相關基本設定也可以寫在這邊,每個套件寫法不同 */
Vue.use(example)
```
再把它引入,記得重新 run dev
```javascript=
/* nuxt.config.js */
plugins: ['~/plugins/example'],
```
* Inject into Vue instances / 注入 Vue 實體
以 [sweetalert2](https://sweetalert2.github.io/) 套件為例(每個外掛寫法可能不同)
```javascript=
/* ~/plugins/example.js */
import Swal from 'sweetalert2';
export default ({ app }, inject) => {
/*inject('toast', swal.mixin({
toast: true,
type: 'success',
position: 'top-end',
showConfirmButton: false,
timer: 4000
}));*/
inject('swal', Swal.mixin({
buttonsStyling: false,
confirmButtonClass: 'el-button el-button--primary el-button--medium',//無客製class免填
cancelButtonClass: 'el-button el-button--default el-button--medium',//無客製class免填
showLoaderOnConfirm: true,
showCancelButton: true
}))
}
```
1. 新增的属性或方法名常使用$作為前缀。
2. `e`是外面使用外掛時,傳進來的值,提供給 `Swal.fire(e)`使用
一樣引入,記得重新 run dev
```javascript=
/* nuxt.config.js */
plugins: ['~/plugins/example'],
```
如此一來我們就可以在可以取得vue(this)的任何地方呼叫這個外掛了,在 component 內:
```javascript=
<script>
export default {
methods: {
swal() {
this.$Swal({...})
/* ... 傳入的就是上面提到的 e */
/* 詳細使用方法請見 sweetalert2 */
}
}
}
</script>
```
[nuxt 官方文件](https://nuxtjs.org/guide/plugins/)