VueのUIライブラリElement(Element UI)で泥沼にハマる

gigazine.net

ウェブの世界では色をsRGBと呼ばれる色空間で処理しており、1677万7216色(赤256×緑256×青256)を処理することが可能です。しかし、sRGBは非可逆圧縮方式のようなもので、sRGBで表現された画像に編集を加えると、上述の事例のようにオリジナル画像とはかけ離れたものが生成される場合があります。

ChromeやFirefoxなどのウェブブラウザでは色が正しく表示されない場合がある - GIGAZINE

Web color is still brokenでは、この現象について「低ビットレートなMP3形式で保存された音楽同士をミキシングするようなこと」と説明しています。

ChromeやFirefoxなどのウェブブラウザでは色が正しく表示されない場合がある - GIGAZINE

ウェブブラウザで正しい色を表示させるには、sRGBではなく線形RGB(リニアRGB)に変換した上で処理する必要があるとのこと。

ChromeやFirefoxなどのウェブブラウザでは色が正しく表示されない場合がある - GIGAZINE

ウェブブラウザで線形RGBを扱うための要素としてはSVGの機能の1つである「color-interpolation」が2003年に提案されていますが、記事作成時点ではGoogle ChromeMicrosoft EdgeMozilla Firefoxといった主要なウェブブラウザはcolor-interpolationに対応していません。

ChromeやFirefoxなどのウェブブラウザでは色が正しく表示されない場合がある - GIGAZINE

⇧ いまが、2022年なので、「color-interpolation」という機能が提案されて、もうすぐ20年経とうしていますが、未だ進展はないようですと...

ブラウザで表示される色に違和感がある時は、この問題である時もあるんですかね?

VueのUIライブラリElement(Element UI)とは?

何て言うか、Element(Element UI)って言った場合、他にもヒットしてしまうんで、Vue.jsのElement UIと呼ぶことにしますが、

element.eleme.io

⇧ 公式のページだと、『You’re browsing the documentation of Element UI for Vue 2.x version.』って言ってるんだけども、GitHubのページだと、Elementって説明で、正解はどっちなんだい?ってなりますね...

github.com

A Vue.js 2.0 UI Toolkit for Web

Element will stay with Vue 2.x

For Vue 3.0, we recommend using Element Plus from the same team

https://github.com/ElemeFE/element

⇧ Vue.jsに限定したUIフレームワークということのようです。対応は、Vue.jsのバージョン2.xオンリーですと。

Vue.js 3.x系は別のUIライブラリを使ってくれとありますね...

ドキュメントもあるにはあるんですが、

github.com

⇧ 結構、制約が多いイメージはありますと。

2022年4月24日(日)追記:↓ ここから

Vue UI frameworkと言いつつも、

element.eleme.io

⇧ まさかの、React、Angular用も存在するようです...

というか、こちらのドキュメントのほうがサンプルも見れるので良い気がします。もっと早く気付きたかった...

2022年4月24日(日)追記:↑ ここまで

結局のところ、CSS上書きするしかないケースが多い気がする

UIフレームワークが便利っていうのは、分かるのですが、痒い所に手が届かないのが一般的なUIフレームワークの宿命なのか分からないですが、Element UIも御多分に漏れずその傾向があるような気がしますと。

qiita.com

  • Element の要素に Scoped CSS のスタイルが適用されないケースがある。
  • 原因は、通常の記述方法だとセレクタの子要素に data 属性がつき、そこに対してスタイルがあたるが、Element が書き出す一部の要素には data 属性がつかない。
  • 対応策としては /deep/ セレクタを使用する。

ElementUI に Scoped CSS が適用されない問題対応策 - Qiita

⇧ 上記サイト様によりますと、Element独自のCSSを打ち消すのは、罠が多い様子。

で、結局のところ、良きようにデザインをカスタマイズするには自力でCSS当てなきゃならんと言うね...

Element UIが独自にHTMLの構造も決めてしまうので、そのHTMLの構造に合わせてCSSも考える必要がありますと。

困ったのが、チェックボックスとラベルの位置を入れ替えるってので悩んでいて、CSSでできることが分かったので、備忘録。正確には、HTMLとCSSの組み合わせになりますが。

Vue CLIでVue.jsのバージョンが2.x系のプロジェクトを作成しています。npmのライブライとしては以下をインストールしてます。element-uiもインストールしてます、というかnpmのライブラリ名だと、Element UIなんですね。

package.jsonは以下のような感じ。

■C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-router-work\my-project-vue\package.json

{
  "name": "my-project-vue",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "vue": "^2.6.14",
    "vue-class-component": "^7.2.3",
    "vue-property-decorator": "^9.1.2",
    "vue-router": "^3.5.1"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^5.4.0",
    "@typescript-eslint/parser": "^5.4.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-plugin-router": "~5.0.0",
    "@vue/cli-plugin-typescript": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "@vue/eslint-config-typescript": "^9.1.0",
    "axios": "^0.26.1",
    "element-ui": "^2.15.8",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-vue": "^8.0.3",
    "prettier": "^2.4.1",
    "sass": "^1.32.7",
    "sass-loader": "^12.0.0",
    "typescript": "~4.5.5",
    "vue-template-compiler": "^2.6.14"
  }
}

    
    

ファイルの構成は以下のような感じ。いろいろ余計なものがあるけど、今回は、TestElementUI.vueを作成して、Element UIを試してます。

コンポーネントを作成。

■C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-router-work\my-project-vue\src\views\TestElementUi.vue

<template>
  <div class="app-container">
    <el-row :gutter="10">
      <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"
        ><div class="grid-content bg-purple">勇者</div></el-col
      >
      <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"
        ><div class="grid-content bg-purple-light">戦士</div></el-col
      >
      <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"
        ><div class="grid-content bg-purple">魔法使い</div></el-col
      >
      <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"
        ><div class="grid-content bg-purple-light">賢者</div></el-col
      >
    </el-row>
    <div>
      <el-form ref="form" :model="sizeForm" label-width="120px" size="mini">
        <el-form-item label="Activity name">
          <el-input v-model="sizeForm.name"></el-input>
        </el-form-item>
        <el-form-item label="Activity zone">
          <el-select
            v-model="sizeForm.region"
            placeholder="please select your zone"
          >
            <el-option label="Zone one" value="shanghai"></el-option>
            <el-option label="Zone two" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Activity time">
          <el-col :span="11">
            <el-date-picker
              type="date"
              placeholder="Pick a date"
              v-model="sizeForm.date1"
              style="width: 100%"
            ></el-date-picker>
          </el-col>
          <el-col class="line" :span="2">-</el-col>
          <el-col :span="11">
            <el-time-picker
              placeholder="Pick a time"
              v-model="sizeForm.date2"
              style="width: 100%"
            ></el-time-picker>
          </el-col>
        </el-form-item>
        <el-row :gutter="10" class="checkbox">
          <el-col>
            <el-form-item label="Activity type">
              <el-checkbox-button name="type"></el-checkbox-button>
            </el-form-item>
          </el-col>
          <el-col>
            <el-form-item label="Activity type">
              <el-checkbox-button name="type"></el-checkbox-button>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="Resources">
          <el-radio-group v-model="sizeForm.resource" size="medium">
            <el-radio border label="Sponsor"></el-radio>
            <el-radio border label="Venue"></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item size="large">
          <el-button type="primary" @click="onSubmit">Create</el-button>
          <el-button>Cancel</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
import Element from "element-ui";

Vue.use(Element);

@Component
export default class TestElementUi extends Vue {
  private sizeForm = {
    name: "",
    region: "",
    date1: "",
    date2: "",
    delivery: false,
    type: [],
    resource: "",
    desc: "",
  };

  created() {
    console.log("■");
  }
  
  private onSubmit() {
    console.log("done");
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  max-width: 960px;
  margin: auto;
}
::v-deep {
  .checkbox {
    display: inline-flex;
    .el-form-item {
      display: flex;
    }
    label.el-form-item__label {
      order: 2 !important;
      width: max-content !important;
    }

    .el-form-item__content {
      margin-left: 0 !important;
    }
  }
}
</style>
    

⇧ 78行目の import文でElement UIを読み込んでます。

今回は、checkboxの横並び、且つ、labelとcheckboxを左右入替したいので、49~60行目のHTMLが対象。CSSについても、その部分だけ考慮。

Element UIのCSSを打ち消すために、!important地獄に陥るという...。

all: initial; すると消えて欲しくないElement UIのCSSも消えてしまう可能性があり悩ましいところですね。

CSSのinitialについては、

1-notes.com

⇧ 上記サイト様が詳しいです。

stackoverflowの回答が分かりやすいも。

stackoverflow.com

So initial is actually the default state for a certain element.

Certain elements like div or p are by default display: block. So setting it to display: initial would be the same.

An img-Tag is by default display: inline. So setting it to display: initial is the same as setting it to inline.

https://stackoverflow.com/questions/42741356/why-is-displayinitial-not-working-as-expected

⇧ HTMLタグ毎に、CSSのプロパティの初期値が違うってことで、結局のところ、どのHTMLタグにどんなCSSプロパティが設定されてるか把握しないと、どのCSSが影響しているのかが分からないという...

UIフレームワークのデザインをカスタマイズする時の辛みは、どのHTMLタグにどんなCSSプロパティを設定してるかを突き止める必要が出てきて、そのために時間が取られてくるということでしょうかね...

UIフレームワークが想定している利用ケースにおいては便利なものが、想定してない利用ケースになった場合に、調整のためにCSSの知識が必要になってくるというジレンマ...

ちなみに、

coliss.com

チェックボックスとテキストをdisplay: flex;で横並びに配置し、align-itemで垂直方向の位置を定義します。
チェックボックスとテキストの並びがマークアップの逆になっているのは、flex-direction: row-reverse;です。

このCSSなら簡単!フォームのチェックボックス・ラジオボタンとテキストをベースラインに揃えて配置 | コリス

⇧ 上記サイト様にある、flex-direction: row-reverseが効果がなかったんですが、Element UIが自動で生成するHTMLの構造も影響しているという気がする...教えて偉い人。

続きまして、Vue Routerを使っているので、コンポーネントへ遷移できるように設定を追加してます。

■C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-router-work\my-project-vue\src\router\index.ts

import Vue from "vue";
import VueRouter, { RouteConfig } from "vue-router";
import HomeView from "../views/HomeView.vue";

Vue.use(VueRouter);

const routes: Array<RouteConfig> = [
  {
    path: "/",
    name: "home",
    component: HomeView,
  },
  {
    path: "/about",
    name: "about",
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () =>
      import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),
  },
  // {
  //   path: "/test",
  //   name: "test",
  //   component: () => import("../views/NavigationGuard.vue"),
  // },
  // {
  //   path: "/testdom",
  //   name: "testdom",
  //   component: () => import("../views/TestDom.vue"),
  // },
  {
    path: "/testui",
    name: "testui",
    component: () => import("../views/TestElementUi.vue"),
  },
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
});

export default router;

Vue Routerで設定したリンクを追加。

■C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-router-work\my-project-vue\src\App.vue

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <!--
      <router-link to="/testdom">dom</router-link> |
      -->
      <router-link to="/testui">UI</router-link>
    </nav>
    <router-view />
  </div>
</template>

<style lang="scss">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;

  a {
    font-weight: bold;
    color: #2c3e50;

    &.router-link-exact-active {
      color: #42b983;
    }
  }
}
</style>

Vue Routerを読み込んでます。

■C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-router-work\my-project-vue\src\main.ts

import Vue from "vue";
import App from "./App.vue";
import router from "./router";

Vue.config.productionTip = false;

new Vue({
  router,
  render: (h) =< h(App),
}).$mount("#app");

で、npm run serveしてみる。

で、VS CodeVisual Studio Code)のターミナルに表示されてるURLにブラウザでアクセスし、UIのリンクをクリック。

Element UIを利用したコンポーネントのページが表示されます。

チェックボックスとラベルの位置が左右入替できてることが確認できました。

ChromeデベロッパーツールでHTMLの構造を確認してみると、

Element UIによってHTMLが自動生成されてるのですが、

<div data-v-a1539918="" class="checkbox el-row" style="margin-left: -5px; margin-right: -5px;">
  <div data-v-a1539918="" class="el-col el-col-24" style="padding-left: 5px; padding-right: 5px;">
    <div data-v-a1539918="" class="el-form-item el-form-item--mini">
      <label class="el-form-item__label" style="width: 120px;">Activity type</label>
      <div class="el-form-item__content" style="margin-left: 120px;">
        <label data-v-a1539918="" role="checkbox" class="el-checkbox-button el-checkbox-button--mini">
          <input type="checkbox" name="type" class="el-checkbox-button__original" value="">
          <!---->
        </label>
        <!---->
      </div>
    </div>
  </div>
  <div data-v-a1539918="" class="el-col el-col-24" style="padding-left: 5px; padding-right: 5px;">
    <div data-v-a1539918="" class="el-form-item el-form-item--mini">
      <label class="el-form-item__label" style="width: 120px;">Activity type</label>
      <div class="el-form-item__content" style="margin-left: 120px;">
        <label data-v-a1539918="" role="checkbox" class="el-checkbox-button el-checkbox-button--mini">
          <input type="checkbox" name="type" class="el-checkbox-button__original" value="">
          <!---->
        </label>
        <!---->
      </div>
    </div>
  </div>
</div>

⇧ このHTMLの作りがいろいろCSSのデザインを難しくさせてる部分でもあるようです。なので、HTMLの作りも大事になってくるわけですね。

ちなみに、CSS(SCSS)で、order: 2 !important; の部分をコメントアウトしてみると、

<template>
  <div class="app-container">
    <el-row :gutter="10">
      <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"
        ><div class="grid-content bg-purple">勇者</div></el-col
      >
      <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"
        ><div class="grid-content bg-purple-light">戦士</div></el-col
      >
      <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"
        ><div class="grid-content bg-purple">魔法使い</div></el-col
      >
      <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"
        ><div class="grid-content bg-purple-light">賢者</div></el-col
      >
    </el-row>
    <div>
      <el-form ref="form" :model="sizeForm" label-width="120px" size="mini">
        <el-form-item label="Activity name">
          <el-input v-model="sizeForm.name"></el-input>
        </el-form-item>
        <el-form-item label="Activity zone">
          <el-select
            v-model="sizeForm.region"
            placeholder="please select your zone"
          >
            <el-option label="Zone one" value="shanghai"></el-option>
            <el-option label="Zone two" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Activity time">
          <el-col :span="11">
            <el-date-picker
              type="date"
              placeholder="Pick a date"
              v-model="sizeForm.date1"
              style="width: 100%"
            ></el-date-picker>
          </el-col>
          <el-col class="line" :span="2">-</el-col>
          <el-col :span="11">
            <el-time-picker
              placeholder="Pick a time"
              v-model="sizeForm.date2"
              style="width: 100%"
            ></el-time-picker>
          </el-col>
        </el-form-item>
        <el-row :gutter="10" class="checkbox">
          <el-col>
            <el-form-item label="Activity type">
              <el-checkbox-button name="type"></el-checkbox-button>
            </el-form-item>
          </el-col>
          <el-col>
            <el-form-item label="Activity type">
              <el-checkbox-button name="type"></el-checkbox-button>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="Resources">
          <el-radio-group v-model="sizeForm.resource" size="medium">
            <el-radio border label="Sponsor"></el-radio>
            <el-radio border label="Venue"></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item size="large">
          <el-button type="primary" @click="onSubmit">Create</el-button>
          <el-button>Cancel</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
import Element from "element-ui";

Vue.use(Element);

@Component
export default class TestElementUi extends Vue {
  private sizeForm = {
    name: "",
    region: "",
    date1: "",
    date2: "",
    delivery: false,
    type: [],
    resource: "",
    desc: "",
  };

  created() {
    console.log("■");
  }
  
  private onSubmit() {
    console.log("done");
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  max-width: 960px;
  margin: auto;
}
::v-deep {
  .checkbox {
    display: inline-flex;
    .el-form-item {
      display: flex;
    }
    label.el-form-item__label {
      //order: 2 !important;
      width: max-content !important;
    }

    .el-form-item__content {
      margin-left: 0 !important;
    }
  }
}
</style>
    

checkboxとラベルの位置は、HTMLの構造のままになります。

ちなみに、HTMLの構造を変えると、CSSも変更が必要になることを検証するために、divで囲ってみました。

<template>
  <div class="app-container">
    <el-row :gutter="10">
      <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"
        ><div class="grid-content bg-purple">勇者</div></el-col
      >
      <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"
        ><div class="grid-content bg-purple-light">戦士</div></el-col
      >
      <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"
        ><div class="grid-content bg-purple">魔法使い</div></el-col
      >
      <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"
        ><div class="grid-content bg-purple-light">賢者</div></el-col
      >
    </el-row>
    <div>
      <el-form ref="form" :model="sizeForm" label-width="120px" size="mini">
        <el-form-item label="Activity name">
          <el-input v-model="sizeForm.name"></el-input>
        </el-form-item>
        <el-form-item label="Activity zone">
          <el-select
            v-model="sizeForm.region"
            placeholder="please select your zone"
          >
            <el-option label="Zone one" value="shanghai"></el-option>
            <el-option label="Zone two" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Activity time">
          <el-col :span="11">
            <el-date-picker
              type="date"
              placeholder="Pick a date"
              v-model="sizeForm.date1"
              style="width: 100%"
            ></el-date-picker>
          </el-col>
          <el-col class="line" :span="2">-</el-col>
          <el-col :span="11">
            <el-time-picker
              placeholder="Pick a time"
              v-model="sizeForm.date2"
              style="width: 100%"
            ></el-time-picker>
          </el-col>
        </el-form-item>
        <div class="checkbox">
          <el-row :gutter="10">
            <el-col>
              <el-form-item label="Activity type">
                <el-checkbox-button name="type"></el-checkbox-button>
              </el-form-item>
            </el-col>
            <el-col>
              <el-form-item label="Activity type">
                <el-checkbox-button name="type"></el-checkbox-button>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
        <el-form-item label="Resources">
          <el-radio-group v-model="sizeForm.resource" size="medium">
            <el-radio border label="Sponsor"></el-radio>
            <el-radio border label="Venue"></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item size="large">
          <el-button type="primary" @click="onSubmit">Create</el-button>
          <el-button>Cancel</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
import Element from "element-ui";

Vue.use(Element);

@Component
export default class TestElementUi extends Vue {
  private sizeForm = {
    name: "",
    region: "",
    date1: "",
    date2: "",
    delivery: false,
    type: [],
    resource: "",
    desc: "",
  };

  created() {
    console.log("■");
  }
  
  private onSubmit() {
    console.log("done");
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  max-width: 960px;
  margin: auto;
}
::v-deep {
  .checkbox {
    display: inline-flex;
    .el-row {
      display: inline-flex;
    }
    .el-form-item {
      display: flex;
    }
    label.el-form-item__label {
      order: 2 !important;
      width: max-content !important;
    }

    .el-form-item__content {
      margin-left: 0 !important;
    }
  }
}
</style>

⇧ 上記で保存して、npm run run serveしてブラウザにアクセスすると、

<div data-v-a1539918="" class="checkbox">
  <div data-v-a1539918="" class="el-row" style="margin-left: -5px; margin-right: -5px;">
    <div data-v-a1539918="" class="el-col el-col-24" style="padding-left: 5px; padding-right: 5px;">
      <div data-v-a1539918="" class="el-form-item el-form-item--mini">
        <label class="el-form-item__label" style="width: 120px;">Activity type</label>
        <div class="el-form-item__content" style="margin-left: 120px;">
          <label data-v-a1539918="" role="checkbox" class="el-checkbox-button el-checkbox-button--mini">
            <input type="checkbox" name="type" class="el-checkbox-button__original" value="">
            <!---->
          </label>
          <!---->
        </div>
      </div>
    </div>
    <div data-v-a1539918="" class="el-col el-col-24" style="padding-left: 5px; padding-right: 5px;">
      <div data-v-a1539918="" class="el-form-item el-form-item--mini">
        <label class="el-form-item__label" style="width: 120px;">Activity type</label>
        <div class="el-form-item__content" style="margin-left: 120px;">
          <label data-v-a1539918="" role="checkbox" class="el-checkbox-button el-checkbox-button--mini">
            <input type="checkbox" name="type" class="el-checkbox-button__original" value="">
            <!---->
          </label>
          <!---->
        </div>
      </div>
    </div>
  </div>
</div>

⇧のようにHTMLがレンダリングされますと。

HTMLとCSSとの適切な組み合わせが難しいということですかね。

HTMLの構造を変えられない時は、CSSで強引に頑張るしかないわけですが、限界はある気がしますかね...

で、HTMLの構造が変わると、CSSも考え直さないといけなくなるので、なかなか辛みが多い感はありますと。

UIフレームワークに限らないですが、フレームワークはカスタマイズ性に難ありですね...

2022年4月24日(日)追記:↓ ここから

Element UIは、importでCSSを別途読み込む必要があったようです。

qiita.com

element.eleme.io

github.com

⇧ themeを変更もできる模様。

何て言うか、GitHubのほうは情報が省略されてたようで、

element.eleme.io

⇧ 公式のページだとCSSも読み込んでました、何故にGitHubのほうで省略してるのかがよく分からないですが...

で、読み込んだところ、見事にデザイン崩れたので、再調整しました...

■C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-router-work\my-project-vue\src\main.ts

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import Element from "element-ui";
// ElementUIでの言語設定、datePickerとかで適用される
import locale from "element-ui/lib/locale/lang/ja";
import "element-ui/lib/theme-chalk/index.css";

Vue.config.productionTip = false;
Vue.use(Element, { locale });

new Vue({
  router,
  render: (h) =>);

 

■C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-router-work\my-project-vue\src\views\TestElementUi.vue

<template>
  <div class="app-container">
    <el-row :gutter="10">
      <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"
        ><div class="grid-content bg-purple">勇者</div></el-col
      >
      <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"
        ><div class="grid-content bg-purple-light">戦士</div></el-col
      >
      <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11"
        ><div class="grid-content bg-purple">魔法使い</div></el-col
      >
      <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1"
        ><div class="grid-content bg-purple-light">賢者</div></el-col
      >
    </el-row>
    <div>
      <el-form ref="form" :model="sizeForm" label-width="120px" size="mini">
        <el-form-item label="Activity name">
          <el-input v-model="sizeForm.name"></el-input>
        </el-form-item>
        <el-form-item label="Activity zone">
          <el-select
            v-model="sizeForm.region"
            placeholder="please select your zone"
          >
            <el-option label="Zone one" value="shanghai"></el-option>
            <el-option label="Zone two" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Activity time">
          <el-col :span="11">
            <el-date-picker
              type="date"
              placeholder="Pick a date"
              v-model="sizeForm.date1"
              style="width: 100%"
            ></el-date-picker>
          </el-col>
          <el-col class="line" :span="2">-</el-col>
          <el-col :span="11">
            <el-time-picker
              placeholder="Pick a time"
              v-model="sizeForm.date2"
              style="width: 100%"
            ></el-time-picker>
          </el-col>
        </el-form-item>
        <div class="checkbox">
          <el-row :gutter="10">
            <el-col>
              <el-form-item label="Activity type">
                <el-checkbox-button name="type"></el-checkbox-button>
              </el-form-item>
            </el-col>
            <el-col>
              <el-form-item label="Activity type">
                <el-checkbox-button name="type"></el-checkbox-button>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
        <el-form-item label="Resources">
          <el-radio-group v-model="sizeForm.resource" size="medium">
            <el-radio border label="Sponsor"></el-radio>
            <el-radio border label="Venue"></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item size="large">
          <el-button type="primary" @click="onSubmit">Create</el-button>
          <el-button>Cancel</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
import Element from "element-ui";

Vue.use(Element);

@Component
export default class TestElementUi extends Vue {
  private sizeForm = {
    name: "",
    region: "",
    date1: "",
    date2: "",
    delivery: false,
    type: [],
    resource: "",
    desc: "",
  };

  created() {
    console.log("■");
  }
  
  private onSubmit() {
    console.log("done");
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  max-width: 960px;
  margin: auto;
}
::v-deep {
  .checkbox {
    display: inline-flex;
    .el-row {
      display: inline-flex;
    }
    .el-form-item {
      display: flex;
      margin-bottom: 1rem !important;
    }
    label.el-form-item__label {
      order: 2 !important;
      width: max-content !important;
      padding-left: 1rem;
    }

    .el-form-item__content {
      margin-left: 0 !important;
    }

    .el-checkbox-button__original {
      opacity: 1;
    }

    .el-checkbox-button {
      padding-bottom: 0.6rem;
    }
  }
}
</style>

で、確認。

⇧ とりあえず、無理やり感が半端ないけど...

おそらく、

element.eleme.io

⇧ HTMLの構造を変えれるケースであれば変えた方がスマートな気はする、というかGitHubのドキュメントのほうで、こっちのドキュメントを参照する導線が、Quick Startのリンクってのが分かり辛いです...

2022年4月24日(日)追記:↑ ここまで

毎度モヤモヤ感が半端ない...

今回はこのへんで。