LoginSignup
0
1

More than 3 years have passed since last update.

vue nuxt 個人メモ

Posted at

vue nuxt 個人メモ

データセット

dataメソッドで行う

index.vue
<script>
export default Vue.extend({
  data() {
    return {
      modal: false,
      email: '',
      password: ''
    }
  }
})
</script>

ハンドラー、イベント

methodsで行う

index.vue
<script>
export default Vue.extend({
  data() {
    return {
      modal: false,
      email: '',
      password: ''
    }
  },
  methods: {
    openModal() {
      this.modal = true
    },
    closeModal() {
      this.modal = false
    }
  }
})
</script>

api取得 ライフサイクル

画面の描画前にデータを取得する場合 asyncData

画面の描画後にデータを取得する場合 mounted

index.vue
<script>
export default Vue.extend({
  data() {
    return {
      modal: false,
      email: '',
      password: ''
    }
  },
  async asyncData({ query, params, $axios }) {
    try {
      const response = await $axios
        .$get(
          `/api/~~${query.id}`,
          {...params},
          { withCredentials: true }
        )
        .catch((error) => error.response)
      if (response === undefined) {
        throw new Error('undefined')
      }
      if (response.status !== 'success') {
        throw new Error(response.data.message)
      }
      return { error: false }
    } catch (error) {
      console.error(error.message)
      return { error: true }
    }
  },
  async mounted() {
    await this.getAPI()
  }
})
</script>

大きな違いはSSRで画面を表示するかどうか??
https://medium.com/veltra-engineering/in-ssr-vue-js-is-created-twice-7f9122de9b77

Nuxtでは特にユニバーサルなコードを書くことを意識するのが重要なので、
違いを理解する必要がある(まだ理解してない)

props

v-forなどでデータを渡す際はv-bindでそのまま渡す

index.vue
  <ul>
    <ListData
      v-for="item in data"
      :key="item.id"
      v-bind="item"
    />
  </ul>

渡されたデータがスネークケースの場合で、
キャメルケースに変換したい場合はハイフンでつなぐ

index.vue
  <ul>
    <ListData
      v-for="item in data"
      :key="item.id"
      :index="index + 1"
      :start-date="item.start_date"
      :end-date="item.end_date"
    />
  </ul>

watch method

dataで定義した値に変更が加わった時にフックして処理を実行したい場合などに使う


<script>
export default {
  props: {
    id: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      value: ''
    }
  },
  watch: {
    value(newValue, oldValue) {
      console.log(
    },
    id(newValue, oldValue) {
      console.log(
    }
  }
}
</script>

nuxt link

to="" でリンク先を指定するけど
変数を入れたい場合など


:to="`/myPage/${user.id}`"

親から子へ渡す props

親コンポーネント

書き方は下記


<template>
  <Child hoge1="ABC" hoge2="DEF"> 
</template>

値が変動する場合はデータバインドで渡す


<template>
  <Child :hoge1="dat1" :hoge2="dat2">
</template>

子コンポーネント

配列形式で受けとる場合


<script>
export default {
  props: ['hoge1', 'hoge2']
}
</script>

オブジェクトで受け取る場合


<script>
export default {
  props: {
    hoge1: {
      type: String,
      default: 'abc',
      required: true
    },
    hoge2: {
      type: String,
      default: '',
      required: false
    }
  }
}
</script>

子から親に伝達するemit

v-on:または@でイベントを紐づける

親コンポーネント

<Child  @click="onClick">

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  methods: {
    onClick(e: Event) {
      e.preventDefault()
      console.log(e)
    }
  }
})
</script>
子コンポーネント

<template>
    <button
      type="button"
      @click="$emit('click')"
    />
</template>
methodsなどで使用する場合

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  methods: {
    onClick(e: Event) {
      e.preventDefault()
      this.$emit('click')
      this.$emit('click', e) // 引数を渡す場合は第二引数
    }
  }
})
</script>

@clickに引数を渡す

忘れガチなのでメモ


<template>
  <div id="app">
    <button @click="click">button</button>
    <button @click="superClick('引数です')">param button</button>
  </div>
</template>

<script>
export default {
  methods: {
    superClick(value) {
      alert(value);
    }
  }
};

propsType

Typescript interface でpropsの受け取る型を指定

index.vue
<script lang="ts">
interface Schedule {
  id: Number,
  startDate: String,
  endDate: String,
  deliveryType: Number,
  afterTalkFlag: Number
}


export default Vue.extend({
  props: {
    userName: String,
    schedule: {
      type: Object as PropType<Schedule>,
      default: null
    }
  }
})
</script>

nuxt での form入力

input checkbox

まずデータを用意


<script>
export default {
  data() {
    return {
      dataList: [  // api から取得してきたデータ
        {name: "hoge"},
        {name: "fuga"},
        {name: "fugafuga"}
      ],
      formData: [] // form送信用
    }
  }
}
</script>

用意したデータをバインドする


<template>
  <div
    v-for="(item, index) in dataList"
    :key="'dataItem' + index"
  >
    <input
      :id="'dataItem_' + item.name"
      type="checkbox"
      :value="item.name"
      v-model="formData"
      name="'dataItem_' + item.name"
    />
    <label :for="'dataItem_' + item.name">
      {{ item.name }}
    </label>
  </div>
</template>

デフォルトでチェックを入れる場合

デフォルトでチェックを入れる場合はv-modelで紐付ける
form送信用のdataオブジェクトに初期値をセットする


<script>
export default {
  data() {
    return {
      dataList: [  // api から取得してきたデータ
        {
          name: "hoge",
          value: true
        },
        {
          name: "fuga",
          value: true
        },
        {
          name: "hogege",
          value: false
        }
      ],
      formData: [] // form送信用
    }
  },
  mounted() {
    this.formData = this.dataList.map((item: any) => item.value)
  }
}
</script>

子のプロパティまたはメソッドを参照する(refs)

親のresetボタンを押した際に、子供のフォームの内容をresetする場合など

ChildForm.vue

<script>
export default {
  name: 'ChildForm',
  data() {
    value: ''
  },
  methods: {
    onClear() {
      this.value = ''
    }
  }
}
</script>
parent.vue
<template>
  <div>
    <ChildForm ref="childForm"/>
    <button @click="clear">
      Clear
    </base-button>
  </div>
</template>

<script>
import ChildForm from '@/components/ChildForm.vue'

export default {
  components: ChildForm,
  methods: {
    clear() {
      this.$refs.childForm.onClear()
    }
  }
}
</script>

v-for での特定回数の繰り返し

記事データを表示する際、1 ~ 10 件のデータを表示する場合がある
他に、ページャーなどの機能で配列の10 ~ 20件の間のデータを抽出したいなど
v-forに整数値を与えることで繰り返しの回数を制御できるがそれだと実現したい機能とは違うのでまとめておく

<template>
  <div v-for="item in pages">
    <div>{{ item.name }}</div>
    <div>{{ item.age }}</div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      currentPage: 1, //現在のページ
      pageLimit: 50,  // 表示できるページ数
      limitItem: 10, // 表示できる要素数
      customerList: [
        { id:1, name: 'hoge', age: 20 },
        { id:2, name: 'fuga', age: 22 },
        { id:3, name: 'aaaa', age: 30 },
        { id:4, name: 'fugafuga', age: 10 }
        // 以降 200件のデータが続く
      ]
    }
  },
  computed: {
    pages() {
      const maxItem = Number(this.itemLimit)
      const start = this.currentPage === 1 ? 0 : (this.currentPage - 1) * maxItem
      const end = this.currentPage === 1 ? maxItem : this.currentPage * maxItem
      return this.customerList.filter((_element, index) => {
        return index >= start && index < end
      })
    }
  }
}
</script>
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1