---
# System prepended metadata

title: Nuxt 起手式筆記

---

# 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/)