マスタッシュ構文
<タグ>ここにしか使えない<タグ>
ディレクティブ
<タグ class=ここに使える>
v-bind
定義した変数を属性に埋め込める。
v-bind:属性="変数"
省略できる
:属性="変数"
こんなこともできる
<p><a :href="url + '/?contents=4991307412749'">ページ</a></p>
属性名をテンプレート変数にもできる
<p><a :[data.href]="url + '/?contents=4991307412749'">ページ</a></p>
属性をまとめて定義して、まとめてbindできる
const imageAttribute = reactive({
height: 600,
width: 400,
src: "image/画像.png",
alt: "画像",
})
<img v-bind="imageAttribute"> //この時はセミコロンじゃなくて=になる
後に書いた記述が優先。alt=を上記のbindの後に付け足せば、そっちで上書きされる
styleを指定できる
これは一つずつ指定するパターン
const textColor = ref('pink');
<p :style="{color: textColor}">サイトへようこそ</p>
まとめても指定できる
const style1 = ref({
color: pink,
font-size: 24px,
})
<p :style="style1">サイトへようこそ</p>
さらにまとめたものを複数指定できる
const style1 = ref({
color: pink,
font-size: 24px,
})
const style2 = ref({
background-color:red
})
<p :style="[style1, style2]">サイトへようこそ</p>
compute関数の値も入れることが出来る
const msgStyles2 = computed(
():string => {
const size = Math.round(Math.random()*25) + 10;
return `${size}pt`; /// shift + @のバッククォート。シングルクォーテーションじゃない。
}
)
//本来はケバブ記法のfont-sizeだがキャメルになる
<p :style="{fontSize: msgStyles2}">サイトへようこそ</p>
fontSizeのようにキャメルで書くのはjavascriptのオブジェクトリテラルを使用しているから。
オブジェクトリテラルではキャメルケースしか使えない。
https://typescriptbook.jp/reference/values-types-variables/object/object-literal
シングルクォートで'font-size'とすればいけるっぽい。
ただし統一はしたほうが良い。
リテラル
直接記述した値のこと
算出プロパティ
computeの値
publicフォルダ
外部公開するファイルはpublicに入れる
イベント系
v-onディレクティブ
v-on:イベント = "関数名"
@イベント = "関数名" // 省略形
v-onは引数で値を送ることもできる
const bgColorChange = (color: string):void => {
bgColor.value = color
}
@click="bgColorChange('black')"
v-onで複数値を引数としたい、かつその中にイベントオブジェクト(カーソル動かした座標とか)を送りたいときは明記する必要がある。イベントオブジェクト単体であれば引数は省略可能。関数側では書く必要がある。
<p><button type="button" @click="bgColorChange('black',$event)">背景色変更ボタン</button></p>
修飾子
prevent
送信ボタンを押した後、sendFormを実行するが、サブミットは発生させない。(入力したデータもsubmitでは送られない)
非同期処理とかで使うのだろうか。その場合はinputタグに入力された値を取得する必要がありそうだけど
sendFormの中で通信して、受信したり登録したりはありそう
<form action="#" v-on:submit.prevent="sendForm">
<input type="text" required>
<button type="submit">送信</button>
</form>
業務で使いそうなので実際に中身を取得してみた
const sendForm = ($event):void => {
const formData = new FormData(event.target);
// 入力された値を取得
const test = formData.get('test');
console.log(test)
}
<form action="#" v-on:submit.prevent="sendForm">
<input type="text" name="test" required>
<button type="submit">送信</button>
</form>
コンソールに入力したデータが表示された。
v-model
入力した値を画面に表示した値をリアクティブに変更するのは結構大変。
値の入力をscriptの中で取得(v-on:inputで検知)して、それをテンプレート変数に代入する必要があった
だがv-modelは全部自動でやってくれる
v-modelを指定したタグで何か入力されたら、そのままテンプレート変数に値が代入される
const model = ref('テスト')
<input type="text" v-model="model">
<p>{{ model }}</p>
// 修飾子
<input type="text" v-model.lazy="model"> //全部入力が完了されてから反映
<input type="text" v-model.trim="model"> //入力されたものの、前後の余分な空白を取り除く
<input type="text" v-model.number="model"> //入力されたものを数値として扱う
こうすると、inputに値をいれる=modelへの代入になる
結果として表示が変わる
radioボタンとかselectボタン
選択した値が表示されるようになる。
すごすぎる、v-model。すごすぎて仕組みが良く分からない。
v-modelが指定されてる入力・選択系のものは、そこに何かが入力されたり選択されたらテンプレート変数が変わるってことかな
<label for=""><input type="radio" name="test" value="1" v-model="radioSelect">A</label>
<label for=""><input type="radio" name="test" value="2" v-model="radioSelect">B</label>
<p>{{ radioSelect }}</p>
<select name="selectTest" id="" v-model="select">
<option value="1">A</option>
<option value="2">B</option>
</select>
check
単一のチェックボックスの場合と、複数選択のチェックボックスで異なる
前者はbool
後者は配列
を定義する
const simpleCheck = ref(true)
const multiCheck = ref([])
<label for=""><input type="checkbox" name="simple" v-model="simpleCheck" id="" >あt</label>
{{ simpleCheck }}
<section>
<label for=""><input type="checkbox" name="multi" v-model="multiCheck" value="A" id="">A</label>
<label for=""><input type="checkbox" name="multi" v-model="multiCheck" value="B" id="">B</label>
</section>
<p>{{ multiCheck }}</p>
v-html
エスケープとは逃避のこと。
何から逃げてるのか?
const str = '<p>文字</p>'
のように書いた文字をhtmlに埋め込んだとする。
すると、勝手に「あぁこれはタグだな」と認識されて
画面上は
文字
とだけ表示される
この「あぁこれはタグだから勝手に処理しちゃおう」という決めつけからの逃亡
つまり、「これはあなたにはタグに見えるかもしれないけど、実際はただの文字列なんだよ!!」
と指示すること。
画面上に
<p>文字</p>
と表示させたい
文字列として書いたタグを文字列としてそのまま埋め込みたい!→エスケープをしたい
文字列として書いたタグをタグとしてレンダリングしたい!→エスケープをしてほしくない
v-htmlにhtmlタグを渡すとエスケープしてくれない。タグをタグとして勝手に解釈して画面に表示しちゃう。
XSSの恐れあり
つまり、v-htmlに指定されているリアクティブなテンプレート変数に、ユーザがみたいなことを入力して、それが登録されて表示されちゃうと、やばいことになる。
ユーザがスクリプトタグを文字列として登録
アプリがその文字列をv-htmlで画面に表示(色んなユーザの書き込みが見れるところとかは危ない。個人のページしか見れなきゃ問題ない)
その文字はタグとして読み込まれる。(エスケープされない)
つまりそのタグは何かの動き、働きを持つことになる
v-htmlは開発者側で用意した値のみを表示させるようにする。
v-pre
記述したタグの子供に関しては、一切vueの記法を通用させない。無力化する
<section>{{ htmlStr }}</section>
<section v-html="htmlStr"></section>
// 表示
{{ htmlStr }}
v-once
一回だけ(描画時)変化するようにする
というか実質最初の値から変化させない
v-cloak
これが付着しているタグは全部の処理が終わるまで、
cssでv-cloakと指定した属性のスタイルが適用される。
描画してる途中を見せたくない!!