Post

[Vue] 게시글 등록

$emit 사용 시
emits: [‘write’]
등록을 안했더니 계속 에러가 남..!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
(App.vue)

<template>
  <div class="header">
    <h1 class="logo"><a href="#" title="vue-stagram"></a></h1>
    <div class="header-button-left">
      <a href="#" v-if="tab==1 || tab==2" @click="tab=0">Cancel</a>
    </div>
    <div class="header-button-right">
      <a href="#" v-if="tab==1" @click="tab=2">Next</a>
      <a href="#" v-if="tab==2" @click="publish">Write</a>
    </div>
  </div>

  <Container :post="post" :tab="tab" :uploadImage="uploadImage" @write=" n => uploadText=n " />
  <button @click="more();" type="button" class="btn_more" v-if="tab==0">더보기</button>

  
  <div class="footer">
    <div class="file_wrap" v-if="tab==0">
      <input type="file" id="file" class="inputfile" accept="image/*" multiple @change="upload">
      <label for="file" class="input-plus" title="이미지 업로드"></label>
    </div>
  </div>

</template>

<script>
import post from './assets/data.js'
import Container from './components/Container.vue'
import axios from 'axios'

export default {
  name:'App',
  data(){
    return {
      post : post,
      get: 0,
      tab: 0,
      uploadImage: '',
      uploadText: '',
    }
  },
  methods: {
    publish(){
      const newPost = {
        name: "aluvy",
        userImage: "./img/profile1.jpg",
        postImage: this.uploadImage,
        likes: 0,
        date: "May 15",
        liked: false,
        content: this.uploadText,
        filter: "perpetua"
      };
      this.post.unshift(newPost);
      this.tab = 0;
    },
    upload(e){
      const file = e.target.files;  // 업로드한 파일이 담겨있음
      const type = "image";

      if( file[0].type.indexOf(type) == -1 ){   // 문자열이 존재하지 않으면 -1 리턴
        alert("이미지만 업로드 해주세요.");
        return;
      }

      const url = URL.createObjectURL(file[0]); // 업로드한 파일의 임시 URL
      this.tab = 1;
      this.uploadImage = url;

    },
    more(){
      if( this.get > 1 ){

        const btn_more = document.querySelector(".btn_more");
        const p = document.createElement("p");
        p.innerText = "게시물이 없습니다.";
        p.classList.add("no_post");
        btn_more.after(p);
        btn_more.remove();

        return;
      }
      axios.get(`https://codingapple1.github.io/vue/more${this.get}.json`)
      .then( result => {
        this.post.push(result.data);
        this.get++;
      })
      .catch( error =>{
        // 요청 실패 시
        console.log(error);
      })
    }
  },
  components:{
    Container,
  }
}
</script>

<style>
@import './assets/css/style.css';


.header {height:4.4rem; background:#fff; position:sticky; top:0; display:flex; align-items:center; justify-content:space-between; color:#333; box-sizing:border-box; padding:0 1.6rem; border-bottom:1px solid #ddd;}
.header .logo{position:absolute; left:50%; top:0; height:100%; transform:translateX(-50%);}
.header .logo a{display:block; width:10.3rem; height:100%; background:url(./assets/img/logo.svg) 0 1rem no-repeat; background-size:100% auto;}

.btn_more{display:block; width:calc(100% - 3.2rem); height:4.2rem; border-radius:0.5rem; border:1px solid #ddd; margin:2rem auto 1rem;}
.no_post{text-align:center; padding:9rem 1.6rem; font-size:1.4rem; color:#999;}


.footer {position:sticky; bottom:0; background:#000; text-align:center;}

.file_wrap{position:relative;}
.file_wrap .inputfile {position:absolute; left:0; top:0; width:1px; height:1px; overflow:hidden; padding:0; margin:0; border:0;  clip:rect(1px, 1px, 1px, 1px); clip-path:inset(50%); word-break:initial; word-wrap:initial; z-index:-1;}
.input-plus {display:inline-block; width:4rem; height:4rem; cursor:pointer; background:url(./assets/img/ico_camera.svg) 50% 50% no-repeat; background-size:2.4rem;}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
(Container.vue)

<template>
  <div v-if="tab==0">
    <Post v-for="(a,i) in post" :key="i" :post="a" :idx="i" />
  </div>

  <div v-if="tab==1">
    <!-- <Filter :uploadImage="uploadImage" /> -->
    <div class="filter">
        <div class="upload-image" :style="{ backgroundImage : `url(${uploadImage})` }"></div>
        <div class="filters">
        <ul>
            <li class="filter-1"></li>
            <li class="filter-1"></li>
            <li class="filter-1"></li>
            <li class="filter-1"></li>
            <li class="filter-1"></li>
        </ul>
        </div>
    </div>

  </div>
  
  <div v-if="tab==2">
    <!-- <Write :uploadImage="uploadImage" @write="console.log( 'container', $event )" /> -->
    <div class="writer">
        <div class="upload-image" :style="{ backgroundImage : `url(${uploadImage})` }"></div>
        <div class="write">
            <textarea class="write-box" @change="sendText">write!</textarea>
        </div>
    </div>

  </div>

</template>

<script>
import Post from '../components/Post.vue'
// import Filter from '../components/Filter.vue'
// import Write from '../components/Write.vue'

export default {
  name: 'compContainer',
  data(){
    return {
      
    }
  },
  props: {
    post: Object,
    tab: Number,
    uploadImage: String,
  },
  components: {
    Post,
    // Filter,
    // Write,
  },
  emits: ['write'],
  methods: {
    sendText(e){
      this.$emit('write', e.target.value);
    }  
  },
}
</script>

<style>
.upload-image{padding-bottom:100%; background-size:cover; background-position:center;}
.filters{overflow-x:scroll; white-space:nowrap;}
.filter-1 {width:100px; height:100px; background-color:cornflowerblue; margin:10px 10px 10px auto; padding:8px; display:inline-block; color :white; background-size:cover;}
.filters::-webkit-scrollbar {height:5px;}
.filters::-webkit-scrollbar-track {background:#f1f1f1;}
.filters::-webkit-scrollbar-thumb {background:#888; border-radius:5px;}
.filters::-webkit-scrollbar-thumb:hover {background:#555;}
.write-box {border:none; width:90%; height:100px; padding:15px; margin:auto; display:block; outline:none;}
</style>
This post is licensed under CC BY 4.0 by the author.