🐈
【音声ファイルアップロード機能】モーダル(コンポーネント)間のデータ受け渡し
headerから両方のモーダルを呼び出す仕様にしているため、BeforeMusicUploadModalからAfterMusicUploadModal.vueへ直接は渡せない
BeforeMusicUploadModal(子)からheader(親)にemitで値を渡して、header(親)からAfterMusicUploadModal(子)のpropsに渡す
nuxtでモーダル作成
BeforeMusicUploadModal.vue
<template>
<div id="overlay" v-show="showContent" @click.self="closeBeforeMusicUploadModal">
<div id="main-content">
<h2 class="title">音声ファイルのアップロード</h2>
<div class="drop_area"
@dragenter="dragEnter"
@dragleave="dragLeave"
@dragover.prevent
@drop.prevent="dropFile"
:class="{enter: isEnter}"
>
<p>クリックしてファイルを追加</p>
<p>最大100MB、形式: MP3, AAC</p>
{{files.file}}
</div>
<!-- <div class="drop_area" v-if="isEnter">
<p>ファイルを保持しています。</p>
{{ files.name }}
</div> -->
<div class="button-content">
<button class="cancel-btn" @click="closeBeforeMusicUploadModal">キャンセル</button>
<button class="disabled-btn" disabled>アップロード</button>
</div>
<!-- <div>
<ul>
<li v-for="(file, index) in files" :key="index">{{ file.name }}
</li>
</ul>
</div> -->
</div>
</div>
</template>
<script>
/* eslint-disable */
export default {
// ここからheader.vueにクリックイベント(openAfterMusicUploadModal)を渡す
transition: {
name: 'modal',
mode: 'out-in'
},
components: {
},
data () {
return {
showContent: false,
showContent2: false,
MusicFile: '',
isEnter: false,
files: [],
greet: 'Hello Vue.js!'
}
},
methods: {
openBeforeMusicUploadModal (){
this.$emit('openBeforeMusicUploadModal', this.showContent);
},
closeBeforeMusicUploadModal (){
this.$emit('closeBeforeMusicUploadModal', this.showContent);
},
closeAfterMusicUploadModal () {
this.showContent2 = false
},
// onMusicFileUploaded(e) {
// // event(=e)からMusicFileデータを取得する
// const musicFile = e.target.files[0]
// this.createMusicFile(musicFile)
// },
// createMusicFile(MusicFile) {
// const reader = new FileReader()
// // MusicFileをreaderにDataURLとしてattachする
// reader.readAsDataURL(MusicFile)
// // readAdDataURLが完了したあと実行される処理
// reader.onload = () => {
// this.submittedArticle.MusicFile = reader.result
// }
// },
dragEnter() {
// console.log('Enter Drop Area');
this.isEnter = true;
},
dragLeave() {
this.isEnter = false;
},
dragOver() {
console.log('DragOver')
},
dropFile() {
this.files = [...event.dataTransfer.files]
console.log(this.files[0].name)
// this.files.forEach(file => {
// let form = new FormData()
// form.append('file', file)
// this.$axios.post('http://localhost:8000//api/musicFileUpload', form).then(response => {
// console.log(response.data)
// }).catch(error => {
// console.log(error)
// })
// })
// this.$emit('closeBeforeMusicUploadModal', this.showContent);
console.log(this.showContent)
this.$emit('openAfterMusicUploadModal', this.showContent2);
console.log(this.showContent2)
this.isEnter = false;
}
},
}
</script>
AfterMusicUploadModal.vue
<template>
<div id="overlay" v-show="showContent2" @click.self="closeAfterMusicUploadModal">
<div id="main-content">
<h2 class="title">音声ファイルのアップロード</h2>
<div class="sections">
<div>
<h3>カバー画像</h3>
<div class="description">
<p>クリックして画像を追加</p>
<p>10MB以内 .jpg .png .heic に対応しています。</p>
</div>
</div>
<h3>タイトル</h3>
<div>
<p>{{ greet }}</p>
</div>
<input type="text" class="text-box">
<h3>ジャンル選択</h3>
<div class="cp_ipselect cp_sl01">
<select required>
<option value="" hidden class="aa">ジャンルを選択してください</option>
<option value="1">J-POP</option>
<option value="1">アニメ</option>
<option value="1">邦楽ヒップホップ/R&B/レゲエ</option>
<option value="1">邦楽ロック</option>
<option value="1">邦楽ダンス/エレクトロニカ</option>
<option value="1">K-POP/ワールド・ミュージック</option>
<option value="1">洋楽総合</option>
<option value="1">洋楽ポップス</option>
<option value="1">洋楽ヒップホップ/R&B/レゲエ</option>
<option value="1">洋楽ロック</option>
<option value="1">洋楽ダンス/エレクトロニカ</option>
<option value="1">歌謡曲/演歌</option>
<option value="1">ジャズ</option>
<option value="1">クラシック</option>
</select>
</div>
<h3>感情アイコン選択</h3>
<ul class="emotion">
<li class="joy">喜</li>
<li class="angry">怒</li>
<li class="sorrow">哀</li>
<li class="easy">楽</li>
</ul>
</div>
<div class="button-content">
<button class="cancel-btn" @click="closeAfterMusicUploadModal">キャンセル</button>
<button class="btn">アップロード</button>
</div>
</div>
</div>
</template>
<script>
/* eslint-disable */
export default {
props: ['greet'],
// props: {
// greet: {
// type: String,
// default: 'hogehoge'
// }
// },
data () {
return {
showContent2: false
}
},
methods: {
// openAfterMusicUploadModal (){
// this.$emit('openAfterMusicUploadModal', this.showContent2);
// },
closeAfterMusicUploadModal (){
this.$emit('closeAfterMusicUploadModal', this.showContent2);
}
},
}
</script>
```vue
呼び出しもと
headerAfterLogin.vue
```vue
<template>
<div>
<header class="header">
<NuxtLink to="/"><h1 class="logo">Sound Matching</h1></NuxtLink>
<nav class="nav">
<ul>
<li>検索</li>
<!-- <li>{{ $store.state.auth.user.name }}</li> -->
<button @click="logout">ログアウト</button>
<li><button class="btn" @click="openBeforeMusicUploadModal">アップロード</button></li>
</ul>
</nav>
</header>
<div>
<transition name="modal" mode="out-in">
<BeforeMusicUploadModal
v-show="showContent"
@click.self="closeBeforeMusicUploadModal"
@closeBeforeMusicUploadModal="closeBeforeMusicUploadModal"
@openAfterMusicUploadModal="openAfterMusicUploadModal"
></BeforeMusicUploadModal>
</transition>
</div>
<div>
<transition name="modal" mode="out-in">
<AfterMusicUploadModal
greet='Hello with props'
v-show="showContent2"
@click.self="closeAfterMusicUploadModal"
@closeAfterMusicUploadModal="closeAfterMusicUploadModal"
></AfterMusicUploadModal>
</transition>
</div>
</div>
</template>
<script>
import BeforeMusicUploadModal from '@/components/BeforeMusicUploadModal.vue'
import AfterMusicUploadModal from '@/components/AfterMusicUploadModal.vue'
export default {
transition: {
name: 'modal',
mode: 'out-in'
},
components: {
BeforeMusicUploadModal,
AfterMusicUploadModal
},
data () {
return {
showContent: false,
showContent2: false
}
},
methods: {
openBeforeMusicUploadModal () {
this.showContent = true
},
closeBeforeMusicUploadModal () {
this.showContent = false
},
openAfterMusicUploadModal () {
this.showContent = false
this.showContent2 = true
console.log(this.showContent)
console.log(this.showContent2)
},
closeAfterMusicUploadModal () {
this.showContent2 = false
},
logout() {
this.$auth.logout();
},
},
}
</script>
やること
呼び出す子コンポーネントを定義
<script>
import BeforeMusicUploadModal from '@/components/BeforeMusicUploadModal.vue'
import AfterMusicUploadModal from '@/components/AfterMusicUploadModal.vue'
export default {
transition: {
name: 'modal',
mode: 'out-in'
},
components: {
BeforeMusicUploadModal,
AfterMusicUploadModal
},
~~~
</script>
ここで呼び出してる
タグ内にemitされてきて実行するメソッドを記述する(@closeBeforeMusicUploadModal="closeBeforeMusicUploadModal"
とか)
各個要素で定義したメソッドがemitされてheader内で実行される
<div>
<transition name="modal" mode="out-in">
<BeforeMusicUploadModal
v-show="showContent"
@click.self="closeBeforeMusicUploadModal"
@closeBeforeMusicUploadModal="closeBeforeMusicUploadModal"
@openAfterMusicUploadModal="openAfterMusicUploadModal"
></BeforeMusicUploadModal>
</transition>
</div>
<div>
<transition name="modal" mode="out-in">
<AfterMusicUploadModal
greet='Hello with props'
v-show="showContent2"
@click.self="closeAfterMusicUploadModal"
@closeAfterMusicUploadModal="closeAfterMusicUploadModal"
></AfterMusicUploadModal>
</transition>
</div>
Discussion