はじめに
Vue.jsを書いている時に、「〇〇なときどう書いたっけな?」と困ることがあったりするので、備忘録として残していくだけの記事です。
では始めていきましょう。
前提
ここで紹介するVueファイルを構成するソースコードは、 Pug / TypeScript / Scss
とします。
また、UIコンポーネントにElementUIを採用しています。
ソースコード
githubにPushしてます。
https://github.com/ryo-is/vue-demo-sample
1. onClickやonChangeで関数を呼びたいとき
@click
や @change
を使う。
この @hoge
というのは v-on:hoge
表記の省略形です。
1-1. ClickEvent
下記の例では、ボタンをクリックすると countNumber
を1ずつ増やしています。
.click-event
.child-title ClickEvent デモ
el-row
el-col(:span="16")
el-button(@click="addCount") カウントアップ
el-col(:span="2")
.count-number {{ countNumber }}
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class ClickEventComponent extends Vue {
public countNumber: number = 0;
public addCount() {
this.countNumber += 1;
}
}
1-2. ChangeEvent
セレクトボックスの選択肢を変更した時にテキストの内容 ( selectedText
) を書き換えています。
.change-event
.child-title ChangeEvent デモ
el-row
el-col(:span="16")
el-select(v-model="selectItem" @change="changeItem")
el-option(label="Apple" value="Apple") Apple
el-option(label="Banana" value="Banana") Banana
el-option(label="Orange" value="Orange") Orange
el-col(:span="4")
.select-text {{ selectedText }}
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class ChangeEventComponent extends Vue {
public selectItem: string = "";
public selectedText: string = "";
public changeItem() {
this.selectedText = this.selectItem;
}
}
2. 要素の表示 / 非表示を切り替えたいとき
v-show
や v-if
を使う。
2-1. v-show の場合
ボタンをクリックした時に displayFlag
を切り替えています。
trueなら display:block
、falseなら display:none
となります。
.v-show
.child-title v-showによる表示/非表示切り替え
.button-area
el-button(@click="displayFlag=!displayFlag") 切り替えボタン
img.logo-img(v-show="displayFlag" alt="" src="../../assets/logo.png")
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class vShowComponent extends Vue {
public displayFlag: boolean = true;
}
2-2. v-if の場合
v-show
とは少し違って条件式を書くことができるので、表示/非表示の状態を、割と自由に設定することができます。
下記の例では、ボタンをクリックした時に displayFlag
を indicate
または hide
に切り替えています。
indicate
なら display:block
、 hide
なら display:none
となります。
.v-if
.child-title v-ifによる表示/非表示切り替え
.button-area
el-button(@click="changeDisplayFlag") 切り替えボタン
img.logo-img(v-if="displayFlag==='indicate'" alt="" src="../../assets/logo.png")
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class vIfComponent extends Vue {
public displayFlag: string = "indicate";
public changeDisplayFlag() {
if (this.displayFlag === "indicate") {
this.displayFlag = "hide";
} else {
this.displayFlag = "indicate";
}
}
}
3. 要素の表示 / 非表示にアニメーションを付けたいとき
transition
を使う。
transitionとは、Vueがデフォルトで用意してくれている、 DOM からアイテムが追加、更新、削除されたときにトランジション効果を適用するための方法です。
先程の v-show
のソースコードを少し書き換えます。
.v-show
.child-title v-show デモ
.button-area
el-button(@click="displayFlag=!displayFlag") 切り替えボタン
transition(name="image-transition")
img.logo-img(v-show="displayFlag" alt="" src="../../assets/logo.png")
transitionのnameで渡している値 (上記のソースコード内で言う image-transition
) が、Styleの image-transition-enter-active
に対応するので、Styleを調整するときは下記のように書くことができます。
.v-show {
.image-transition-enter-active,
.image-transition-leave-active {
transition: all .5s;
}
.image-transition-enter,
.image-transition-leave-to {
opacity: 0;
transform: translateY(-10px);
}
}
4. 要素を繰り替えし生成したいとき
v-for
を使う。
下記の例では ["Apple", "Banana", "Orange"]
という文字列をli要素として生成しています。
.v-for
.child-title v-for デモ
ul.list-items
li(v-for="item in listItems" :key="item") {{ item }}
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class vForComponent extends Vue {
public listItems: string[] = ["Apple", "Banana", "Orange"];
}
5. inputの要素を変数に保存したいとき
v-model
を使う。
下記の例では、テキストエリアに入力した値を、別要素のテキストとして表示しています。
.v-model
.child-title v-model デモ
el-row
el-col(:span="10")
el-input(v-model="inputText")
el-col(:span="14")
.input-text {{ inputText }}
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class vModelComponent extends Vue {
public inputText: string = "";
}
6. 親Componentの関数を子Componentから呼び出したいとき
$emit
を使う。
下記の例では、子Componentのボタンをクリックしたら、親Componentのテキストを非表示にしたり、表示したりしています。
子Component
.emit
.child-title $emit デモ
el-button(@click="$emit('changeTitleDisplay')") タイトル表示/非表示
親Component
.home
.title(v-show="titleDisplay") {{ homeTitle }}
emitComponent(v-on:changeTitleDisplay="changeTitleDisplay")
import { Component, Vue } from "vue-property-decorator";
import emitComponent from "@/components/emit/Emit.vue";
@Component({
components: {
emitComponent,
},
})
export default class Home extends Vue {
public homeTitle: string = "Vue Demo Sapmle";
public titleDisplay: boolean = true;
public changeTitleDisplay() {
this.titleDisplay = !this.titleDisplay;
}
}
7. 動的にclassを切り替えたいとき
v-bind:class
を使う。
下記の例では、タイトルのClassを変更することで、文字色を変更しています。
.change-class
.child-title(v-bind:class="fontColorClass") Change Class デモ
el-button(@click="changeFontColor('red')") 赤色に変更
el-button(@click="changeFontColor('yellow')") 黄色に変更
el-button(@click="changeFontColor('normal')") 元に戻す
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class ChangeClassComponent extends Vue {
public fontColorClass: string = "normal-font-color";
public changeFontColor(color: string) {
this.fontColorClass = color + "-font-color";
}
}
.change-class {
.red-font-color {
color: red;
};
.yellow-font-color {
color: yellow;
}
}
8. 子Componentに値を渡したいとき
Prop
を使う。
下記の例では、親Componentから子Componentに直接テキストを渡したり、インスタンス変数を渡したりしています。
子Component
.prop
.child-title Prop デモ
.prop-text {{ propText }}
.prop-value {{ propValue }}
import { Component, Vue, Prop } from "vue-property-decorator";
@Component({})
export default class PropComponent extends Vue {
@Prop() public propText: string;
@Prop() public propValue: string;
}
親Component
.home
propComponent(:prop-text="'Propで値を子Componentに渡す'", :prop-value="propValue")
import { Component, Vue } from "vue-property-decorator";
import propComponent from "@/components/prop/Prop.vue";
@Component({
components: {
propComponent,
},
})
export default class Home extends Vue {
public propValue: string = "インスタンス変数を子Componentに渡す";
}
9. 親Componentから子Componentを識別したいとき (2019/01/10 追記)
ref
を使う。
親コンポーネントの template
に子コンポーネントを読み込むときに ref
属性を定義すると vm.$refs
で子コンポーネントを識別することができます。
ただ注意が必要なのが created()
の段階ではまだ子コンポーネントがインスタンス化されていないので取得できません。 mounted()
やClickなどのイベントなどで取得しましょう。
下記の例では子コンポーネントの変数を取得して、標準出力しています。
子Component
.ref
.child-title Ref デモ
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class RefComponent extends Vue {}
親Component
.home
refComponent(ref="refDemo")
import { Component, Vue } from "vue-property-decorator";
import refComponent from "@/components/ref/Ref.vue";
@Component({
components: {
refComponent,
},
})
export default class Home extends Vue {
public created() {
const refDemoComponent: refComponent = this.$refs.refDemo as refComponent;
console.log(refDemoComponent); // undefined
}
public mounted() {
const refDemoComponent: refComponent = this.$refs.refDemo as refComponent;
console.log(refDemoComponent);
}
}
10. 親Componentから子Componentの関数を呼びたいとき (2019/01/10 追記)
ref
を使う。
「9. 親Componentから子Componentを識別したいとき」と同じように ref
を使っていきます。
下記の例では親Componentの mounted()
のタイミングで、子Componentのメソッドを呼び出して、変数に代入しています。
途中型宣言がうまくできなくてやむなく any
を使っています…ここきれいに型宣言できる方法知っている方いたら、コメントいただけると幸いです。
子Component
.ref
.child-title Ref デモ
import { Component, Vue, Prop } from "vue-property-decorator";
@Component({})
export default class RefComponent extends Vue {
public sampleText: string = "Refのデモです";
public returnText(): string {
return this.sampleText;
}
}
親Component
.home
refComponent(ref="refDemo")
.ref-demo-text {{ refDemoText }}
import { Component, Vue } from "vue-property-decorator";
import refComponent from "@/components/ref/Ref.vue";
@Component({
components: {
refComponent,
},
})
export default class Home extends Vue {
public refDemoText: string = "";
public mounted() {
const refDemoComponent: any = this.$refs.refDemo; // ここの型宣言がうまくできなかった…
this.refDemoText = refDemoComponent.returnText();
}
}
11. Propの変数が更新されたら子Componentも更新したいとき (2019/01/10 追記)
ref
を使う。
「9. 親Componentから子Componentを識別したいとき」と同じように ref
を使っていきます。
というよりは「10. 親Componentから子Componentの関数を呼びたいとき」の応用です。
下記の例では、親Componentのテキストボックスの内容(refInputText
)をpropで子Componentの値(refText
)に渡していて、 refInputText
を更新した時に、子Componentの updateRefText()
を呼び出して refText
を更新しています。
子Component
.ref
.child-title Ref デモ
.ref-input-text {{ refText }}
import { Component, Vue, Prop } from "vue-property-decorator";
@Component({})
export default class RefComponent extends Vue {
@Prop() public refText: string;
public sampleText: string = "Refのデモです";
public updateRefText(newText: string) {
this.refText = newText;
}
}
親Component
.home
refComponent(ref="refDemo")
el-row
el-col(:span="10")
el-input(v-model="refInputText" @change="changeRefInputText")
el-col(:span="14")
.ref-demo-text {{ refDemoText }}
import { Component, Vue } from "vue-property-decorator";
import refComponent from "@/components/ref/Ref.vue";
@Component({
components: {
refComponent,
},
})
export default class Home extends Vue {
public refDemoText: string = "";
public mounted() {
const refDemoComponent: any = this.$refs.refDemo;
this.refDemoText = refDemoComponent.returnText();
}
public changeRefInputText() {
const refDemoComponent: any = this.$refs.refDemo;
refDemoComponent.updateRefText(this.refInputText);
}
}
さいごに
これからも「〇〇なときどう書いたっけな?」と困ることがあったら随時アップデートしていこうと思います!
ではまた!!