Laravel/vueのちょっとした事の覚え書き。Laravel 8.xで作業した際の情報。
hrefでアプリのパスを使う
hrefでアプリのパスを引っ張ってきて使う方法。axios.defaults.baseURLを使う。
window.location.href = axios.defaults.baseURL + "subpath/search?kw=" + this.searchword;
resources/bootstrap.jsに追加。env変数からは上手く動かなかったので固定で入れている。
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.baseURL = '/subfolder/'; //process.env.MIX_BASE_URL;
phpからvueへ配列を渡す
json_encodeを使う
php側で一度encode
<SearchResult :results="{{ json_encode($results) }}"/>
vue側でデコード
this.resultdata = JSON.parse(JSON.stringify(this.results));
簡単なツールチップの使い方
ボタンとかマウスオーバーで説明が出るやつ。
//インストール
npm install v-tooltip --save
//追加
app.js
import VTooltip from 'v-tooltip'
//使い方
<button v-tooltip.left="'TOPにメッセージが表示されます'">TOP</button>
並べる
divを並べたい時
タイル状
class="flex px-2 items-start row"
横スクロール
class="flex px-2 items-start overflow-x-auto"
位置を固定にしてサイズを変更可能に
styleでfixedにしてページ内の位置を固定、clickすると幅を調整。
//html内
<div class="storebox" ref="storeb" id="storeb">
<span class="font-medium font-bold text-white" @click.prevent.stop="showhidestore()">{{ stbtext }}</span>
//関数
showhidestore(){
var stb = this.$refs.storeb;
if (this.stbtext == "小"){
stb.style.width = "100%";
this.stbtext = "大ボックス";
}else{
stb.style.width = "10%";
this.stbtext = "小";
}
}
//スタイルに追加
<style scoped>
.storebox {
background: rgba(255, 255, 255, 0.8);
position: fixed;
width: 100%;
bottom: 0;
right: 0;
z-index: 500;
transition: all 0.5s ease;
}
テキストを省略表示
「・・・」と省略して、クリックすると全部だしたり。縮小すると「…」、開くと「<<」の例。
//スクリプト
import truncate from "vue-truncate-collapsed";
export default {
components: {
truncate,
//html
<truncate clamp="..." :length="20" less="<<" :text="item.description"></truncate>
背景画像
背景に画像を表示。public/images/bkg/に画像ファイルを置いておく。
app.blade.phpにタグ追加
<body style="background-image: url('/appname/images/bkg/bkg.png')">
要素の親で class=”bg-transparent”して子で”bg-gray-400 bg-opacity-50″とかすると透過divが出来る。
背景画像配布サイト
https://www.toptal.com/designers/subtlepatterns/
複数appでcsrf tokenエラーが出る
複数のappを使っているとアプリ毎にtokenが異なり、csrf token mismatchと出る事がある。アプリ毎にtokenが異なったり、ログイン情報が共有化されていない時にアプリを移動して使っているとtokenが無効になる。
app_nameに日本語を入れているとセッション名が_sessionになるのでapp_nameに日本語を使っている場合はセッション名を別名で使う様にする。
config/session.phpのセッション名APP_NAMEベースからSESS_NAMEにして
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('SESS_NAME', 'laravel'), '_').'_session'
),
.envにSESS_NAME=を入れておく
CSRF Tokenの有効期限を変える
config/session.phpのlifetimeキーに設定があるので変更する。
https://teratail.com/questions/27003
下記サイトにページ側からリロード無しにtokenを更新するスクリプト例あり。
CSRFの期限切れ防止用にlaravel-caffeineと言うのもある。
https://github.com/GeneaLabs/laravel-caffeine
draggableで配列間移動
draggableで配列間をドラッグ移動した場合、@endが移動元しか呼ばれないので@sortのイベントを使うと良い。
Laravelのイベント情報
ESCキーをハンドリングする
キーイベントを監視し、キーコードで処理。
created() {
const onEscape = (e) => {
if (this.open && e.keyCode === 27) {
this.close()
}
}
document.addEventListener('keydown', onEscape)
this.$once('hook:destroyed', () => {
document.removeEventListener('keydown', onEscape)
})
},
https://github.com/adamwathan/vue-tailwind-examples/blob/master/src/components/Modal.vue#L51
カラーピッカー
色選択したい時に。vue-colorを使う。
npm install vue-color
//html
<compact-picker @input="updatecolor" v-model="colorpick" />>
//スクリプト
import compact from 'vue-color/src/components/Compact.vue';
import chrome from 'vue-color/src/components/Chrome.vue';
components:
'compact-picker': compact,
'chrome-picker': chrome,
console.log(this.colorpick);
var $rgb = this.colorpick.rgba.r + ", " + this.colorpick.rgba.g + ", " + this.colorpick.rgba.b;
var $rgba = "rgba(" + $rgb + ", 0.6)";
document.getElementById('basecolor').style.backgroundColor=$rgba;
https://github.com/xiaokaike/vue-color/issues/67
.envの変数をvueから使う
.envファイル内に頭にMIX_を付けて定義する。vueからはprocess.env.MIX_ で参照できる。
//.envに記述MIX_UNIQUE_ID=test
//vue内
var blockid_withapp = process.env.MIX_UNIQUE_ID + blockid;
複数のwhereを指定する
Laravelのeloquentで複数のwhereを指定する方法。
$query->where([
['column_1', '=', 'value_1'],
['column_2', '<>', 'value_2'],
[COLUMN, OPERATOR, VALUE],
...
])
//controller内例
$titem = mitem::where(['startdate' => $date, 'user_id' => $usr->user_id])->First();
controllerでcollectionにデータを動的追加
単に新規項目に値を代入するだけ。activestatusを追加する例。
$categorydata->activestatus = $categorydata->status;
vue間の通知
refで名前を付けてemitで通知する。
https://qiita.com/shibaHaya/items/55b8703f10f393d2ef7c
子viewへ通知する例
//タグにrefで名前を付けて
<xxxxx ref="luser">
//通知する時emit
this.$refs.luser.$emit('docheck');
//子vue側
mounted() {
this.$on('docheck', function() {this.checknewdata()});
laravel-mixエラー
The Mix manifest does not exist. と言うエラーが出る場合インストールをやり直す。
npm install laravel-mix@latest npm install
ページに個別にサブタイトルを付ける
layoutにtitleを追加
<title>{{ config('app.name') }} @yield('title')</title>
各ページで好きなサブタイトルを入れる
//固定
@section('title', '個別のページタイトル')
//変数から
@section('title')
| {{ $subject->name }}
@endsection
表示が更新されない
変数を変更しても反映されず、他の変数を更新すると反映される場合、キーを追加して更新させる。updatekeyを追加し、変数更新時これも更新する。
//html
<button
:key="updatekey"
//スクリプト
data(){
return {
updatekey: 0,
//method内更新をかけたい時
this.updatekey += 1;
https://michaelnthiessen.com/force-re-render/
複数のポップアップメニューの競合
子vueで this.$refs.ctxMenuItem. の様にして開くと、親で複数のctxMenuItemがあると競合してしまう。動的に個別にidを入れる。
//メニュー表示の基準位置用div
<div :id="'newbaseref'+uniqueid">
//基準位置とかメニューにユニークIDを追加
var cvs = document.getElementById('newbaseref'+cid);
this.$refs['ctxMenuItem'+uid].showMenu(event, uid, window.pageXOffset+cvs.getBoundingClientRect().left, event.pageY-cvs.offsetTop);
ページからユーザーIDを取得
ページのスクリプトからユーザーのIDを取得する。
//routeにインターフェイスを追加
Route::get('user/id', '\App\Http\Controllers\HomeController@userid')->name('userid');
//コントローラー側でIDを返す関数追加
public function userid()
{
return Auth::id();
}
//スクリプトで動的取得
axios
.get("user/id")
.then((response) => {
this.userid = response.data;
})
.catch((error) => {
console.log(error);
});
定期的に更新が無いかサーバー問い合わせする
intervalで一定時間毎にサーバーに更新が無いか問い合わせる。データ更新時「全体の更新時間」のデータを更新する様にして、その時間をチェックすれば更新時間のデータをチェックするだけで良い。更新があればデータを取得しページを最新データに更新する。
5秒毎に問い合わせる例。
data
return() {
updated: "",
mounted(){
this.checknewdata();
this.autofetch = setInterval(() => {this.checknewdata()}, 5000);
checknewdata(){
axios
.get("item/updated/"+this.itemid)
.then((response) => {
var newupdate = JSON.parse(JSON.stringify(response.data));
if (newupdate !== this.updated){
this.getnewdata();
}
this.updated = JSON.parse(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
},
getnewdata(){
axios
.get("file/listitem/"+this.itemid)
.then((response) => {
this.fileitems = JSON.parse(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
},