vue.jsのtips 殴り書き

# 目次
・[はじめに](#はじめに)
・[タブをつくる](#タブをつくる)
・[assets配下の画像ファイルパスの指定方法](#assets配下の画像ファイルパスの指定方法)
・[PageTopスクロール](#pagetopスクロール)

## はじめに
ここでは、個人的にvue.jsを触って学んだことや覚えておきたいことなどを適宜殴り書きしていくスタイルのページとなります。

## タブをつくる
vue.jsでのタブの作り方

### template

```vuejs
<ul class="tabs">
  <li
    v-for="(tab, index) in tabs"
    :key="tab.id"
    :class="{ 'is-active': isActive === index }"
    class="seminarSearch_tabItem"
    @click="isActive = index"
  >
    {{ tab.tabName }}
  </li>
</ul>
<div v-show="isActive === 0" class="content">
  <Component />
</div>
<div v-show="isActive === 1" class="content">
  <div>
    <p>ほげほげ</p>
  </div>
</div>
```

```vuejs
<Component />
```
を読み込ませることや

```vuejs
<div>
  <p>ほげほげ</p>
</div>
```

直接htmlを入れることもok.

### typescript

```typescript
import Component from '~/components/presentationals/Component.vue'

export default {
  components: {
    Component,
  },
  data() {
    return {
      isActive: 0,
      id: 0,
      tabs: [
        { id: 1, tabName: 'タブ１' },
        { id: 2, tabName: 'タブ2' },
      ],
    }
  },
}
```

これでタブが出来上がる。
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="miyawash" data-slug-hash="BazQrYg" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="BazQrYg">
  <span>See the Pen <a href="https://codepen.io/miyawash/pen/BazQrYg">
  BazQrYg</a> by miyawash (<a href="https://codepen.io/miyawash">@miyawash</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

---

## assets配下の画像ファイルパスの指定方法

### 直接テンプレートに記述して読み込む場合

```vuejs
<img src="@/assets/sample.png">
```

### v-bindまたはvalueで読み込ませる場合
テンプレート側

```vuejs
<img v-bind:src="src" />
or
<img :src="src" />
```

typescript側

```typescript
export default {
  data() {
    return {
      src:  require('@/assets/sample.png'),
    }
  }
}

```

requireを使って読み込ませる。

---

## PageTopスクロール
vue.jsでのPageTopスクロールの実装

### template

```vuejs
    <transition name="fade">
      <div v-show="scY > 300" class="pageScroll" @click="toTop">
        <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#4a5568" stroke-width="1" stroke-linecap="square" stroke-linejoin="arcs"><path d="M18 15l-6-6-6 6"/></svg>
      </div>
    </transition>
```
Vue.jsのtransitionタグを使うことで、簡易的にトランジション効果を適用できます。
[Enter/Leave とトランジション一覧](https://jp.vuejs.org/v2/guide/transitions.html)

name属性に入れた名前がcssで.fadeとして使用できます。
今回はフェードアクションを入れたかったので、fadeとしてcssで.fadeに効果を入れています。

スクロールボタン表示は「v-show」で300以上になったら表示という状態にしてます。
scYの値はtsで取得。

### typescript

```typescript
export default {
  data() {
    return {
      scTimer: 0,
      scY: 0,
    }
  },
  mounted() {
    window.addEventListener('scroll', this.handleScroll)
  },
  methods: {
    handleScroll() {
      if (this.scTimer) return
      this.scTimer = window.setTimeout(() => {
        this.scY = window.scrollY
        clearTimeout(this.scTimer)
        this.scTimer = 0
      }, 100)
    },
    toTop() {
      window.scrollTo({
        top: 0,
        behavior: 'smooth',
      })
    },
  },
}
```

handleScrollで、スクロール値を取得し、window.scrollToで画面トップへのスクロール実装をしてます。
window.scrollToのオプションbehaviorを入れれば、滑らかに移動します。
[MDN window.scrollTo](https://developer.mozilla.org/ja/docs/Web/API/Window/scrollTo)


```scss
.contents {
  height: 50vh;
  background-color: #ededed;
  border-bottom: 1px solid #000
}
.pageScroll {
  position: fixed;
  right: 0;
  bottom: 00;
  cursor: pointer;
  &:hover {
    background-color: #fef3eb;
  }
}
.fade {
  &-enter {
    opacity: 0;
  }
  &-enter-active {
    transition: opacity 1s;
  }
  &-enter-to {
    opacity: 1;
  }
}
```

fade classは
・fade-enterが開始の状態
・fade-enter-activはenterの活性状態、つまり終了までの間
・fade-enter-toが終了の状態（今回で言えば表示中）

この内容でページスクロールをするとフェードイン・アウトで表示されます。

```
behavior: 'smooth',
```

ちなみにこれはsafariなどでは効かないため smoothscroll-polyfill を入れること使えます。

### smoothscroll-polyfill
 
```
yarn add smoothscroll-polyfill
```

```plugins/smooth-scroll.ts
import Vue from 'vue'
import SmoothScroll from 'smoothscroll-polyfill'

SmoothScroll.polyfill()

Vue.use(SmoothScroll)
```

```nuxt.config.ts
    { src: '~/plugins/smooth-scroll.ts', mode: 'client' },
```

この記述で使えるようになります。

※SSRでない場合は

```
mode: 'client'
```
はなくても動くと思います。

SSRの時は

```
mode: 'client'
```
がないと

**window is not defined**
になると思います。

<p class="codepen" data-height="500" data-theme-id="light" data-default-tab="js,result" data-user="miyawash" data-slug-hash="YzWxogW" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="vue pagetop scroll">
  <span>See the Pen <a href="https://codepen.io/miyawash/pen/YzWxogW">
  vue pagetop scroll</a> by miyawash (<a href="https://codepen.io/miyawash">@miyawash</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
---