フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

vee-validate/nuxtjsに導入する

はじめに

  • 前回、nuxtjs+vuetifyjs/vee-validateを調査しましたが、vuetifyjsを利用しない場合の実装方法が異なったので調査した内容を下記にまとめました。 px-wing.hatenablog.com

コード

  • plugins/vee-validate.jsファイルを作成して利用するルールやエラーメッセージを日本語化する
import Vue from 'vue'
import { ValidationProvider, ValidationObserver, localize, extend } from 'vee-validate'
# エラーメッセージを日本語化する設定
import ja from 'vee-validate/dist/locale/ja.json'
import { required, max, min, email, size } from 'vee-validate/dist/rules'

# 利用するルールを指定する
extend('required', required)
extend('email', email)
extend('max', max)
extend('min', min)
extend('size', size)

Vue.component('ValidationProvider', ValidationProvider)
Vue.component('ValidationObserver', ValidationObserver)
localize('ja', ja)
  • nuxt.confg.jsファイルに下記の記述を追記する
  plugins: [
    '@/plugins/vee-validate.js'
  ],
  build: {
    transpile: [
      "vee-validate/dist/rules"
    ]    
  },
  • pageの埋め込みたい場所に下記のフォームを追加する
    <validation-observer v-slot="{ handleSubmit }">
      <form ref="form" model="valid" lazy-validation @submit.prevent>
      <table>
        <tr>
          <td>メールアドレス</td>
          <td>
            <validation-provider v-slot="{ errors }" rules="required|email" name="メールアドレス">
              <input v-model="email" type="text" placeholder="メールアドレス">
              <p class="error-message">{{ errors[0] }}</p>
            </validation-provider>
          </td>
        </tr>
        <tr>
          <td>パスワード</td>
          <td>
            <validation-provider v-slot="{ errors }" rules="required" name="パスワード">
              <input v-model="passworfd" type="text" placeholder="パスワード">
              <p class="error-message">{{ errors[0] }}</p>
            </validation-provider>
          </td>
        </tr>
        <tr>
        <td colspan="2">
        <button class="form-btn2" style="background-color: gray; color: white" @click="handleSubmit(validate)">
          ログイン
        </button>
        </td>
        </tr>
      </table>
      </form>
    </validation-observer>

実際の画面

f:id:PX-WING:20201225125032p:plain

strapiのcontrollerを触ってみる

はじめに

  • strapiの独自実装しなくてもcurdのAPIは標準で準備されているので、controllerの実装も必要がなく開発できるが、機能としてあるので触ってみる。

手順

  • コントローラーを利用するための「customers」というコンテンツタイプを作成する f:id:PX-WING:20201225073534p:plain

  • 作成すると「api/customers/」フォルダが作成される。その中にある「config/routes.json」ファイルに下記の記述を追記する

    {
      "method": "GET",
      "path": "/customers_customfind",
      "handler": "customers.customfind",
      "config": {
        "policies": []
      }
    },
  • api/customers/」フォルダの中にある「controllers/customers.js」ファイルに下記の記述を追記する
'use strict';
const { sanitizeEntity } = require('strapi-utils');

module.exports = {
  async customfind(ctx) {
    let entities = await strapi.query('customers').find({ id: 1 });
    return entities.map(entity => sanitizeEntity(entity, { model: strapi.models.customers }));
  }
};
  • 上記の作業が完了したら管理画面にログインして作成したAPIのアクセス許可を与える。 ※コントローラーに記述した「customfind」メソッドが表示される f:id:PX-WING:20201225074417p:plain

実行結果

f:id:PX-WING:20201225074537p:plain

FlexboxのResponsive

はじめに

  • 前回、Flexboxを覚えたのでflexboxを利用したレスポンシブができないか試してみる。 px-wing.hatenablog.com

コード

  • ブラウザのサイズが800px以下の場合、flexboxを縦にして、800px以上の場合、横にするコードを作成してみました。
<!DOCTYPE html>
<html>
<head>
<style>

.flex-container {
  display: flex;
  flex-direction: row;
  font-size: 30px;
  text-align: center;
}

.flex-item-left {
  background-color: #f1f1f1;
  padding: 10px;
  flex: 50%;
}

.flex-item-right {
  background-color: dodgerblue;
  padding: 10px;
  flex: 50%;
}

@media (max-width: 800px) {
  .flex-container {
    flex-direction: column;
  }
  body {
    color: blue;
  }

}

</style>
</head>
<body>

<h1>Flexbox レスポンシブ</h1>

<div class="flex-container">
  <div class="flex-item-left">カラム1</div>
  <div class="flex-item-right">カラム2</div>
</div>

</body>
</html>

実行結果

f:id:PX-WING:20201223230346p:plain

CSSのFlex boxを利用したときのメモ

はじめに

  • CSSFlex boxを利用する機会があったので、覚えたものをメモしたことをまとめてみた。

サポートブラウザ

属性 Chrome IE Firefox Safari opera
flex 29.0
21.0 -webkit-
11.0
10.0 -ms-
28.0
18.0 -moz-
9.0
6.1 -webkit-
17

Flex box 属性

プロパティ 説明
display HTML要素に使用されるボックスのタイプを指定します
flex-direction フレックスコンテナ内のフレキシブルアイテムの方向を指定します
justify-content アイテムが主軸の使用可能なスペースをすべて使用していない場合、フレックスアイテムを水平方向に配置します
align-items アイテムが交差軸上の使用可能なスペースをすべて使用していない場合、フレックスアイテムを垂直方向に整列します
flex-wrap 1つのフレックスラインに十分なスペースがない場合に、フレックスアイテムを折り返すかどうかを指定します
align-content flex-wrapプロパティの動作を変更します。 これはalign-itemsに似ていますが、フレックスアイテムを整列する代わりに、フレックスラインを整列します。
flex-flow フレックス方向とフレックスラップの省略形プロパティ
order 同じコンテナ内の残りのフレックスアイテムに対するフレキシブルアイテムの順序を指定します
align-self フレックスアイテムに使用されます。 コンテナのalign-itemsプロパティを上書きします
flex flex-grow、flex-shrink、およびflex-basisプロパティの省略形プロパティ

flex-direction のプロパティ値

プロパティ 説明
flex-start デフォルト値。 アイテムはコンテナの先頭に配置されます
flex-end アイテムはコンテナの端に配置されます
center アイテムはコンテナの中央に配置されます
space-between アイテムの間にスペースがあります
space-around アイテムの前、間、後にスペースがあります
space-evenly アイテムの周囲には同じスペースがあります
initial このプロパティをデフォルト値に設定します。
inherit 親要素からこのプロパティを継承します

justify-content のプロパティ値

プロパティ 説明
flex-start デフォルト値。 アイテムはコンテナの先頭に配置されます
flex-end アイテムはコンテナの端に配置されます
center アイテムはコンテナの中央に配置されます
space-between アイテムの間にスペースがあります
space-around アイテムの前、間、後にスペースがあります
space-evenly アイテムの周囲には同じスペースがあります
initial このプロパティをデフォルト値に設定します
inherit 親要素からこのプロパティを継承します。

align-itemsのプロパティ値

プロパティ 説明
stretch デフォルト。 アイテムはコンテナに合うように引き伸ばされます
center アイテムはコンテナの中央に配置されます
flex-start アイテムはコンテナの先頭に配置されます
flex-end アイテムはコンテナの端に配置されます
baseline アイテムはコンテナのベースラインに配置されます
initial このプロパティをデフォルト値に設定します。
inherit 親要素からこのプロパティを継承します。

nuxtjsで「もっと読む」機能を実装する

はじめに

  • nuxtjsでファーストビューで途中までテキストを表示して、ユーザーがリンクまたはボタンをクリックしたら、全テキストを表示するサンプルを作成してみた。

コード

Case1(テキスト)

- components/Readmore.vueファイルを作成して下記のコードを記述する

<template>
    <div>
        <span v-if="!readMoreActivated">{{longText.slice(0, 200)}}</span>
            <a class="" v-if="!readMoreActivated" @click="activateReadMore" href="#">
            read more...
        </a>
        <span v-if="readMoreActivated" v-html="longText"></span>
    </div>
</template>
<script>
export default {
    name: "Readmore",
    data(){
        return {
            longText: `Brown skin girl
Your skin just like pearls
The best thing in the world
Never trade you for anybody else
Singin' brown skin girl
Your skin just like pearls
The best thing in the world
I never trade you for anybody else, singin'
She said she really grew up poor like me
Don't believe in nothin' but the Almighty
Just a likkle jeans and a pure white tee
She never did forever be nobody wifey, yeah
So while I may not pretty boy, your heart is amiss
Play it like a villain 'cause she caught in a wave
Tonight I am walkin' away
Lined up my mind, on the grind, yeah, yeah
Tonight I might fall in love, dependin' on how you hold me
I'm glad that I'm calmin' down, can't let no one come control me
Keep dancin' and call it love, she fightin' but fallin' slowly
If ever you are in doubt, remember what mama told me
Brown skin girl, ya skin just like pearls
Your back against the world
I never trade you for anybody else, say
Brown skin girl, ya skin just like pearls
The best thing inna di world
I never trade you for anybody else, say
Pose like a trophy when Naomis walk in
She need an Oscar for that pretty dark skin
Pretty like Lupita when the cameras close in
Drip broke the levee when my Kellys roll in
I think tonight she might braid her braids
Melanin too dark to throw her shade
She minds her business and whines her waist
Gold like 24k, okay
Tonight I might fall in love, dependin' on how you hold me
I'm glad that I'm calmin' down, can't let no one come control me
Keep dancin' and call it love, she fightin' but fallin' slowly
If ever you are in doubt, remember what mama told me
Brown skin girl, ya skin just like pearls
Your back against the world
I never trade you for anybody else, say
Brown skin girl, ya skin just like pearls
The best thing inna di (about the) world
I never trade you for anybody else, say
Oh, have you looked in the mirror lately? (Lately)
Wish you could trade eyes with me ('cause)
There's complexities in complexion
But your skin, it glow like diamonds
Dig me like the earth, you be giving birth
Took everything in life, baby, know your worth
I love everything about you, from your nappy curls
To every single curve, your body natural
Same skin that was broken be the same skin takin' over
Most things out of focus, view
But when you're in the room, they notice you (notice you)
'Cause you're beautiful
Yeah, you're beautiful
The men dem gon' fall in love 
With you and all of your glory
Your skin is not only dark, it shines and it tells your story
Keep dancin', they can't control you
They watchin', they all adore you
If ever you are in doubt, remember what mama told you
Brown skin girl (brown skin girl), ya skin just like pearls (brown skin girl)
Your back against the world (oh)
I never trade you for anybody else, say (no, no)
Brown skin girl (brown skin girl), ya skin just like pearls (brown skin)
The best thing in all the world
I never trade you for anybody else, say
Brown skin girl
Your skin just like pearls
The best thing in the world
I never trade you for anybody else, singin'`,
            readMoreActivated: false
        }
    },
    methods: {
        activateReadMore(){
            this.readMoreActivated = true;
        },
    }
    
}
</script>

github.com

Case2(オリジナル / ボタン)

- components/Readmore2.vueファイルを作成して下記のコードを記述する

<template>
  <div class="card">
    <div class="card__thumbnail">
      <img class="card__img" src="@/assets/images/sample.jpg">
    </div>
    <div class="card__content">
      <div class="card__title">
        タイトルが入ります。
      </div>
      <p class="card__description" :class="[toggle ? 'card__max_description' : 'card__min_description']">
        こちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストですこちらはテストです
      </p>
    </div>
    <button class="card__button" @click="toggleBtn">
      {{ toggle ? '▲ close' : '▼ more' }}
    </button>
  </div>
</template>

<script>
export default {
  filters: {
    ellipsis (value, toggle) {
      if (!value) { return '' }
      if ((value.length > 150) && (!toggle)) {
        return value.slice(0, 150) + '...'
      }
      return value
    }
  },
  data: () => ({
    toggle: false
  }),
  methods: {
    toggleBtn () {
      this.toggle === true ? this.toggle = false : this.toggle = true
    }
  }
}
</script>
<style>

(一部省略)

## 閉じている時のスタイルシート
.card__min_description{
  font-size: 14px;
  height: 85px;
  overflow: hidden;
  -webkit-animation: fadeout 3s linear 0s 1;
}

## 開いている時のスタイルシート
.card__max_description{
  font-size: 14px;
  animation: hideop 1s linear 0s;
  -webkit-animation: fadeout 3s linear 0s 1;
}

(一部省略)

</style>
<template>
  <div>
    <Readmore />
    <Readmore2 />
  </div>
</template>

<script>
import Readmore from '@/components/Readmore'
import Readmore2 from '@/components/Readmore2'

export default {
  components: {
    Readmore,
    Readmore2
  }
}
</script>

実際の画面

  • ファーストビューの状態 f:id:PX-WING:20201221223053p:plain

  • ユーザーがリンクまたはボタンをクリックした状態 f:id:PX-WING:20201221223108p:plain

nuxtjsでvuexを使ってみる

はじめに

  • 最近、nuxtjsを触っているので、vuexを使ってみる

px-wing.hatenablog.com

px-wing.hatenablog.com

storeの設定

  • store/auth.jsというファイルを作成して下記のように記述する
export default {
  namespace: true,
  state: () => ({
    loginAccount: '',
    passWord: [],
  }),
  mutations: {
    setDateForm (state, params) {
      state.loginAccount = params.loginAccount
      state.passWord = params.passWord
    }
  }
}

pageの設定

<template>
  <v-app id="inspire">
    <v-content>
      <v-row justify="center">
        <v-col cols="6">
          <v-card>
            <v-card-title>ログイン画面</v-card-title>
          </v-card>
        </v-col>
      </v-row>
      <v-row justify="center">
        <v-col cols="6">
          <v-form ref="form" v-model="valid" lazy-validation>
            <v-text-field v-model="loginAccount" :rules="loginAccountRules" label="ログインアカウント" required />
            <v-text-field v-model="passWord" :rules="passWordRules" label="パスワード" required />
            <v-btn :disabled="!valid" color="success" class="mr-4" @click="validate">
              ログイン
            </v-btn>
            <v-btn color="error" class="mr-4" @click="reset">
              リセット
            </v-btn>
          </v-form>
        </v-col>
      </v-row>
      </div>
      </v-container>
    </v-content>
  </v-app>
</template>

<script>

export default {
  data () {
    return ({
      valid: true,
      loginAccount: '',
      loginAccountRules: [
        v => !!v || 'ログインアカウントは必須項目です'
      ],
      passWord: '',
      passWordRules: [
        v => !!v || 'パスワードは必須項目です'
      ]
    })
  },
  methods: {
    validate () {
      if (this.$refs.form.validate()) {
        this.$store.commit('auth/setDateForm', { loginAccount: this.loginAccount, passWord: this.passWord })
        this.$router.push('/dashboard')
      }
    },
    reset () {
      this.$refs.form.reset()
    }
  }
}
</script>
  • 次のページで下記の
   <div>
    {{ $store.state.auth.loginAccount }}
    {{ $store.state.auth.passWord }}
   </div>

画面イメージ

f:id:PX-WING:20201220011638p:plainf:id:PX-WING:20201220011644p:plain

nuxtjsでページ内リンクをする方法

はじめに

  • nuxtjsでページ内リンクする方法を調べてみたところ2つ方法を見つけましたが、1回目の遷移は正しく動作しますが、2回目以降が動作しないことがわかりました。この2回目以降の対応方法が見つからず。

1つ目の方法

  • vue-routerの機能で実装する方法があったので参考に実装してみたところ、1回目の遷移だけはうまく行きました。 stackoverflow.com
            <v-btn color="success" class="mr-12" :to="{ path: '/hoge',hash:'#profile'}" nuxt>次の場所へ遷移</v-btn>
            (省略)
            <div id="profile"></div>

2つ目の方法

  • vue-scrolltoというパッケージがあり、こちらをインストールすると楽に実装できるらしいが、ほぼ上記の実装と同じだったので、インストールしなくても大丈夫かなと思いました。

www.npmjs.com

パッケージのインストール

yarn add vue-scrollto

設定

  • nuxt.config.jsファイルに下記の記述を追記する
  modules: [
    ['vue-scrollto/nuxt', { duration: 300 }]
  ],

コード

            <nuxt-link to="#profile">次の場所へ遷移</nuxt-link>
            (省略)
            <div id="profile"></div>