투고(그림, 비망록) by vue3+firebase(store,firestore) 비망록

44629 단어 FirebaseVue.jstech

개시하다


투고용 제작 화면과 투고 리스트를 표시하는 화면을 만들었다.
그림이 포함되어 있기 때문에store(그림등록)와firestore를 사용합니다.
나는 이것이 기초 위에서 응용할 수 있다고 생각한다.
디자인을 고려하지 않았습니다.

컨디션

  • vue3
  • firebase v9
    참조 링크
    storage : https://modularfirebase.web.app/common-use-cases/storage/
    firestore : https://firebase.google.com/docs/firestore/quickstart?hl=ja
  • typescript
  • 완성



    폴더 구성



    firestore 구성



    용례


    주로 Firebase이기 때문에 작은 상자를 만들지 않습니다.
  • 신규 발언
  • 발언 목록 가져오기
  • 코드(환경 구조 부분 제외)


    첫 페이지(상위 구성 요소)


    top.vue
    <template>
    <div class="ly_top">
      <h1>投稿</h1>
      <div class="ly_top_inner">
        <div v-if="displayList">
          <button @click="toCreate">新規作成</button>
        </div>
        <div v-else>
          <button @click="toList">戻る</button>
        </div>
    
        <div v-if="displayList">
          <list></list>
        </div>
        <div v-if="displayCreate">
          <create></create>
        </div>
      </div>
    </div>
    </template>
    <script lang="ts">
    import { ref } from 'vue'
    import create from './create.vue'
    import list from './list.vue'
    export default({
      components:{
        create,
        list
      },
      setup() {
        const displayList = ref<boolean>(true)
        const displayCreate = ref<boolean>(false)
    
        const toCreate=()=>{
          displayList.value = false
          displayCreate.value = true
        }
        const toList=()=>{
          displayList.value = true
          displayCreate.value = false
        }
    
        return{
          displayList,
          displayCreate,
          toCreate,
          toList
        }
        
      },
    })
    </script>
    <style lang="scss">
      h1{
        padding:15px;
        background-color:blue;
        color:white;
      }
      .ly_top_inner{
        max-width: 1000px;
        margin:auto;
      }
    </style>
    

    발언 제작 섹션(서브어셈블리)


    create.vue
    <template>
      <h2>作成</h2>
      <div class="ly_input">
        <div class="ly_input_inner">
          タイトル:<input type="text" v-model="title"><br>
        </div>
        <div class="ly_input_inner">
          メモ:<input type="text" v-model="memo"><br>
        </div>
        <div class="ly_input_inner">
          画像:<input type="file" accept="image/jpeg,image/png,image/gif" @change="uploadFile">  
        </div>
        <button @click="create">登録</button>
      </div>
    </template>
    <script lang="ts">
    import { defineComponent,ref } from 'vue'
    import { createFirebase} from './firebase'
    
    export default defineComponent({
      setup() {
        const title = ref<string>()
        const memo = ref<string>()
        const fileData =ref<string>()
    
        const uploadFile = (event:any)=>{
          fileData.value = event.target.files[0]
        }
        const create=()=>{
          if(!title.value || !memo.value || !fileData.value ){
            alert ('すべて入力してください。')
            return
          }
          createFirebase(title.value,memo.value,fileData.value)
        }
        return{
          create,
          title,
          memo,
          uploadFile,
          fileData
        }
      },
    })
    </script>
    <style lang="scss">
    h2{
      border-left:10px solid blue;
      padding-left:5px; ;
    }
    
    .ly_input{
      padding:10px;
      max-width: 900px;
      margin:auto;
    }
    .ly_input_inner{
      margin:10px;
    }
    </style>
    

    발언 목록 섹션(서브어셈블리)


    list.vue
    <template>
      <h2>リスト</h2>
      <div class="ly_article">
        <div class="ly_article_inner"  v-for="article in articles" :key="article">
          <div class="bl_article">{{ article.title }}</div>
          <div class="bl_article"><img :src=article.filePath></div>
          <div class="bl_article">{{ article.memo }}</div>
        </div>
      </div>
    </template>
    <script>
    import { defineComponent, onMounted ,ref } from 'vue'
    import { fetchFirebase } from './firebase'
    
    export default defineComponent({
      setup() {
        const articles =ref()
        onMounted(()=>{
          fetchFirebase()
            .then((data)=>{
              articles.value = data
            })
        })
        return{
          articles
        }    
      },
    })
    </script>
    <style lang="scss">
    h2{
      border-left:10px solid blue;
      padding-left:5px; ;
    }
    .ly_article{
      display: flex;
      flex-wrap: wrap;
      padding:10px;
      max-width: 1000px;
      margin:auto;
      .ly_article_inner{
        flex:0 0 250px;
        padding: 20px;
        margin:5px;
        background-color: rgb(197, 197, 243);
      }
      .bl_article{
        text-align: center;
      }
      
    }
    </style>
    
    

    Firebase 작업 섹션

  • 등록(create Firebase)
  • 데이터 취득(fetchFirebase)
    ・・ Firestore에서 이미지를 가져옵니다.등록 시 이미지 path를 Firestore에 저장
  • firebase.ts
    import { getFirestore, addDoc,collection,serverTimestamp, getDocs } from "firebase/firestore";
    import { getDownloadURL, getStorage, ref, uploadBytesResumable } from "firebase/storage";
    
    export const createFirebase=(title:string,memo:string,fileData:any)=>{
      const metadata={
        contentType: 'image/jpeg',
      }
      const storage = getStorage();
      const imageRef = ref(storage, '/' + title);
      uploadBytesResumable(imageRef, fileData, metadata)
        .then((snapshot) => {
          getDownloadURL(snapshot.ref)
            .then((url) => {
              addDoc(collection(getFirestore(), "articles"), {
                title: title,
                memo: memo,
                filePath : url,
                createDate: serverTimestamp()
              })
                .then(()=>{
                  console.log('success')
                })
                .catch((e)=>{
                  console.log('fail',e)
                })
            });
        })
        .catch((error) => {
          console.error('Upload failed', error);
        });
    }
    
    export const fetchFirebase=async()=>{
      const data:Array<any>=[]
      const querySnapshot = await getDocs(collection(getFirestore(), "articles"))
      querySnapshot.forEach((doc) => {
        // doc.data() is never undefined for query doc snapshots
        data.push(doc.data())
      })
      return data
    }
    
    이상입니다.

    좋은 웹페이지 즐겨찾기