「JavaScript framework」の版間の差分
(JavaScriptからFrameworkを分離。) |
(Vue.jsメモ。) |
||
122行目: | 122行目: | ||
<template> | <template> | ||
<nowiki> </nowiki> <nowiki><div role="group" class="bv-no-focus-ring"> | <nowiki> </nowiki> <nowiki><div role="group" class="bv-no-focus-ring"> | ||
<div | |||
class="form-group-text" | |||
:class="{ active: '' + value, 'is-invalid': error }" | |||
> | |||
<b-form-input | |||
:id="'input-text-' + _uid" | |||
type="text" | |||
:formatter="formatter" | |||
:value="value" | |||
@input="$emit('input', $event)" | |||
@compositionend="$emit('input', normalize($event.target.value))" | |||
@paste="$emit('input', paste($event))" | |||
/> | |||
<label :for="'input-text-' + _uid">{{ | |||
/[._]/.test(label) ? $t(label) : label | |||
}}</nowiki><nowiki></label></nowiki> | |||
<nowiki> </nowiki> <nowiki></div></nowiki> | <nowiki> </nowiki> <nowiki></div></nowiki> | ||
<nowiki> </nowiki> <nowiki><div :id="'input-live-feedback-' + _uid" class="invalid-feedback"> | <nowiki> </nowiki> <nowiki><div :id="'input-live-feedback-' + _uid" class="invalid-feedback"> | ||
{{ $t(error) }}</nowiki> | |||
<nowiki> </nowiki> <nowiki></div></nowiki> | <nowiki> </nowiki> <nowiki></div></nowiki> | ||
<nowiki> </nowiki> <nowiki></div></nowiki> | <nowiki> </nowiki> <nowiki></div></nowiki> | ||
</template> | </template> | ||
<nowiki><script> | <nowiki><script> | ||
export default { | |||
props: { | |||
value: { type: String, default: ''</nowiki>, required: true }, | |||
<nowiki> </nowiki> label: { type: String, default: <nowiki>''</nowiki>, required: true }, | <nowiki> </nowiki> label: { type: String, default: <nowiki>''</nowiki>, required: true }, | ||
<nowiki> </nowiki> // ファームウェアとスケジュールにエラーのないフォームがある。 | <nowiki> </nowiki> // ファームウェアとスケジュールにエラーのないフォームがある。 | ||
195行目: | 195行目: | ||
<template> | <template> | ||
<nowiki> </nowiki> <nowiki><div role="group" class="bv-no-focus-ring mb-3"> | <nowiki> </nowiki> <nowiki><div role="group" class="bv-no-focus-ring mb-3"> | ||
<div | |||
class="form-group-text" | |||
:class="{ active: '' + value, 'is-invalid': error }" | |||
> | |||
<b-form-input | |||
:id="'input-number-' + _uid" | |||
class="form-control" | |||
type="tel" | |||
autocomplete="off" | |||
maxlength="10" | |||
:formatter="formatter" | |||
:value="value" | |||
@input="$emit('input', $event)" | |||
@compositionend="$emit('input', normalize($event.target.value))" | |||
/> | |||
<label :for="'input-number-' + _uid">{{ $t(label) }}</nowiki><nowiki></label></nowiki> | |||
<nowiki> </nowiki> <nowiki></div></nowiki> | <nowiki> </nowiki> <nowiki></div></nowiki> | ||
<nowiki> </nowiki> <nowiki><div :id="'input-live-feedback-' + _uid" class="invalid-feedback"> | <nowiki> </nowiki> <nowiki><div :id="'input-live-feedback-' + _uid" class="invalid-feedback"> | ||
{{ $t(error) }}</nowiki> | |||
<nowiki> </nowiki> <nowiki></div></nowiki> | <nowiki> </nowiki> <nowiki></div></nowiki> | ||
<nowiki> </nowiki> <nowiki></div></nowiki> | <nowiki> </nowiki> <nowiki></div></nowiki> | ||
</template> | </template> | ||
<nowiki><script> | <nowiki><script> | ||
export default { | |||
props: { | |||
value: { type: [String, Number], default: ''</nowiki>, required: true }, | |||
<nowiki> </nowiki> error: { type: String, default: <nowiki>''</nowiki>, required: true }, | <nowiki> </nowiki> error: { type: String, default: <nowiki>''</nowiki>, required: true }, | ||
<nowiki> </nowiki> label: { type: String, default: <nowiki>''</nowiki>, required: true }, | <nowiki> </nowiki> label: { type: String, default: <nowiki>''</nowiki>, required: true }, | ||
250行目: | 250行目: | ||
<nowiki></script></nowiki> | <nowiki></script></nowiki> | ||
==== error '<template>' cannot be keyed. Place the key on real elements instead vue/no-template-key ==== | |||
[https://stackoverflow.com/questions/56476413/custom-elements-in-iteration-require-v-bindkey-directives vue.js - Custom elements in iteration require 'v-bind:key' directives - Stack Overflow] | |||
==== ハイライト ==== | |||
<nowiki>https://forum.vuejs.org/t/highlight-in-html-a-new-object-in-javascript-array/38877/9</nowiki> | |||
nextTickでやればいいか。 | |||
[https://sagatto.com/20181031_highlight_display_at_vue_js 【Vue.js】検索文字などの特定文字を、マーカーでハイライト表示するコンポーネントを作った | SAGA.TXT] | |||
検索キーワードで検索対象をsplitして、key/value形式で順番に配列で配置する。 | |||
==== カスタムコンポーネントのv-bind ==== | |||
[https://stackoverflow.com/questions/42918710/how-to-use-v-bind-in-a-custom-component javascript - How to use v-bind in a custom component? - Stack Overflow] | |||
[https://github.com/buefy/buefy/issues/1038 using v-model b-input component · Issue #1038 · buefy/buefy] | |||
[[Category:JavaScript]] | [[Category:JavaScript]] |
2024年10月29日 (火) 12:04時点における最新版
jQuery
レガシー
- jQueryはもう古い!?これから・・・ | YORIYORK|栃木県佐野市
- jQueryとは何なのか? なぜ使わなくても(あるいは使わないほうが)いいのか? #JavaScript - Qiita
- そろそろなぜjQueryを使うのが難しいのかをちゃんとまとめようと思う。|榊原昌彦
- jQueryを終了する時が来ましたか?
jQueryがもういらなくなってきたという意見がある。
- Webブラウザー間の違いがなくなってきた。
- 標準のJavaScriptでできることが増えた。
上記2点が大きい。jQueryじゃないとできないことが大幅に減った。標準APIでこなしたほうがいいだろう。
ajaxのasync/awaitでの書換
$.ajax(jQuery.ajax)の非同期処理をasync awaitの入れ子なし同期処理で記述する #JavaScript - Qiita
ajaxを使っている関数の定義にasync。ajax関数の使用箇所にawait。これでうまくいく。
** * フルーツ名を取得する * * @param {string} fruitId */ async function getFruitName(fruitId) { const fruitRequest = {id: fruitId} const fruitResult = await ajaxGetFruit(fruitRequest); return fruitResult.name; } /** * フルーツのajax[GET]を実施する * * @param {object} request * @returns */ function ajaxGetFruit(request) { return $.ajax({ url: '/fruit/name', type: "GET", async: true, contentType: "application/json", data: JSON.stringify(request), dataType: "json", }).then( function (result) { // 正常終了 resolve(result); }, function () { // エラー reject(); } ) }
「jQuery.ajax() | jQuery API Documentation」にあるように、jquery 1.5から$.ajaxの返却値はPromiseの派生クラス。そのまま返却させて良い。
Nuxt.js
終端スラッシュありへのリダイレクト
Nuxt.jsにおける末尾スラッシュを統一する方法 #amplify - Qiita
// middleware/trailingSlash.js /** * 終端スラッシュありのURLにリダイレクトする。 * @param {Object} Nuxt.jsのContextオブジェクト。 */ export default ({ route, redirect }) => { if (route.path.endsWith('/')) { return } let to = route.path + '/' if (route.query) { to += '?' + Object.entries(route.query) .map((e) => e.join('=')) .join('&') } to += route.hash redirect(301, to) }
//へのアクセスエラー
- https://github.com/vuejs/vue-router/issues/2593
- https://github.com/nuxt/nuxt.js/issues/2020
けっきょく、serverMiddlewareは結合環境で機能せず、middlewareもルートの変化後に発動するため対応できなかった。
そのため、プラグインにして、router.beforeEachで変化前に書き換え処理を入れた。
// plugins/redirect.js export default ({ app }) => { app.router.beforeEach((to, from, next) => { // 二重スラッシュを一重スラッシュに変換する。 // 素直にnextでリダイレクトすると、一度もともとのtoのURLでDOMの更新に進んでエラーが出る。 // そのためnext(false)でtoは使わずにpushで履歴を差し替える。 if (/\/\/+/.test(to.path)) { next(false) app.router.push(to.path.replace(/\/\/+/g, '/')) } else { next() } }) }
Vue.js
Naming
【Vue】単一ファイルコンポーネントの命名規則まとめ【ファイル名から記法まで】 #Vue.js - Qiita
radioのbool
vuejs2 - Vue: Binding radio to boolean - Stack Overflow
v-bind:か:で型を合わせて代入する。stringにするとうまく認識されない。
IMEの入力制限
IME以外はformatterで処理して、IMEだけcompositionendで処理すればいい。
<template> <div role="group" class="bv-no-focus-ring"> <div class="form-group-text" :class="{ active: '' + value, 'is-invalid': error }" > <b-form-input :id="'input-text-' + _uid" type="text" :formatter="formatter" :value="value" @input="$emit('input', $event)" @compositionend="$emit('input', normalize($event.target.value))" @paste="$emit('input', paste($event))" /> <label :for="'input-text-' + _uid">{{ /[._]/.test(label) ? $t(label) : label }}</label> </div> <div :id="'input-live-feedback-' + _uid" class="invalid-feedback"> {{ $t(error) }} </div> </div> </template> <script> export default { props: { value: { type: String, default: '', required: true }, label: { type: String, default: '', required: true }, // ファームウェアとスケジュールにエラーのないフォームがある。 error: { type: String, default: '' }, }, methods: { /** * 入力内容の正規化を行う。 * @param {string} input - 入力文字列。 * @return {string} 正規化後文字列。 */ normalize(input) { // ASCII文字列以外は削除する。 return input.replace(/[^ -~]/g, '') }, /** * 入力フォームを整形する。 * @param {string} value - 入力文字列。 * @param {Object} event - イベントオブジェクト。 * @return {string} IME変換時は正規化後の文字列。それ以外は、compositionendで行うため、未変換文字列。 * IME変換時はcompositionendで入力を正規化し、それ以外はformatterで正規化する。 */ formatter(value, event) { return event.isComposing ? value : this.normalize(value) }, /** * クリップボードからの貼付時の文字列を処理する。 * @param {Object} event - イベントオブジェクト。 * @return {string} 処理後の文字列。 * @todo 入力の途中にカーソルを移動させて貼り付けた場合、貼り付け後、カーソルが末尾に移動してしまう。 * event.preventDefault()が原因と思われる。しかし、これの解決が難しい。 * event.target.selectionStartにカーソル位置を指定できるのだが、preventDefaultすると一瞬カーソルが末尾に飛ぶ。 */ paste(event) { event.preventDefault() const cb = (event.clipboardData || window.clipboardData).getData('text') const start = event.target.selectionStart return this.normalize( this.value.slice(0, start) + cb + this.value.slice(start) ) }, }, } </script>
<template> <div role="group" class="bv-no-focus-ring mb-3"> <div class="form-group-text" :class="{ active: '' + value, 'is-invalid': error }" > <b-form-input :id="'input-number-' + _uid" class="form-control" type="tel" autocomplete="off" maxlength="10" :formatter="formatter" :value="value" @input="$emit('input', $event)" @compositionend="$emit('input', normalize($event.target.value))" /> <label :for="'input-number-' + _uid">{{ $t(label) }}</label> </div> <div :id="'input-live-feedback-' + _uid" class="invalid-feedback"> {{ $t(error) }} </div> </div> </template> <script> export default { props: { value: { type: [String, Number], default: '', required: true }, error: { type: String, default: '', required: true }, label: { type: String, default: '', required: true }, }, methods: { /** * 入力内容の正規化を行う。 * @param {string} value - 入力文字列。 * @return {string} result - 正規化後文字列。 * @warn v-model.numberの修飾子を指定するとcompositionendでの変更が反映されない。 * そのため、.numberを使わず、この関数で型変換する。 */ normalize(value) { const result = parseFloat(value.replace(/[^0-9]/g, '')) return isNaN(result) ? '' : result }, /** * 入力フォームを整形する。 * @param {string} value - 入力文字列。 * @param {Object} event - イベントオブジェクト。 * @return {string} IME変換時は正規化後の文字列。それ以外は、compositionendで行うため、未変換文字列。 * IME変換時はcompositionendで入力を正規化し、それ以外はformatterで正規化する。 */ formatter(value, event) { return event.isComposing ? value : this.normalize(value) }, }, } </script>
error '<template>' cannot be keyed. Place the key on real elements instead vue/no-template-key
vue.js - Custom elements in iteration require 'v-bind:key' directives - Stack Overflow
ハイライト
https://forum.vuejs.org/t/highlight-in-html-a-new-object-in-javascript-array/38877/9
nextTickでやればいいか。
【Vue.js】検索文字などの特定文字を、マーカーでハイライト表示するコンポーネントを作った | SAGA.TXT
検索キーワードで検索対象をsplitして、key/value形式で順番に配列で配置する。
カスタムコンポーネントのv-bind
javascript - How to use v-bind in a custom component? - Stack Overflow