Programing

Vue momentjs 타임스탬프에서 실시간으로 상대 시간 업데이트

c10106 2022. 3. 21. 08:44
반응형

Vue momentjs 타임스탬프에서 실시간으로 상대 시간 업데이트

포럼 앱을 만들고 있는데, v-for와 함께 모든 댓글이 모멘트j로 언제 올라갔는지 보여주고 싶은데 문제는 렌더가 '몇 초 전'에서 절대 바뀌지 않는다는 것이다.질문에서 응답은 기본적으로 구성 요소가 생성되는 간격을 사용하여 내가 원하는 것을 달성하는 것으로 나타난다.

  created() {
    setInterval(() => {
      this.messages = this.messages.map(m => {
        m.ago = moment(m.time).fromNow();
        return m;
      });
    }, 1000);
  }

하지만 그것 때문에 나는 vuex에서 직접 데이터를 가져왔기 때문에 내 코드와 솔루션을 통합하는 방법을 이해하지 못한다.

여긴 내 가게야

export default new Vuex.Store({
  state: {
    comments: [],
  },
  mutations: {
    loadComments: (state, comments) => {
      state.comments = comments;
    },
  },
  actions: {
    loadComments: async (context) => {
      let snapshot = await db
        .collection("comments")
        .orderBy("timestamp")
        .get();
      const comments = [];
      snapshot.forEach((doc) => {
        let appData = doc.data();
        appData.id = doc.id;
        appData.timestamp = moment()
          .startOf(doc.data().timestamp)
          .fromNow();
        comments.push(appData);
      });
      context.commit("loadComments", comments);
    },
  },
});

그리고 이건 내 대본이야.

import { db, fb } from "../firebase";
import { mapState } from "vuex";

export default {
  name: "Forum",
  data() {
    return {
      commentText: null,
    };
  },
  mounted() {
    this.getComment();
  },
  methods: {
    getComment() {
      this.$store.dispatch("loadComments");
    },
    async sendComment() {
      await db
        .collection("comments")
        .add({
          content: this.commentText,
          author: this.name,
          timestamp: Date.now()
        });
      this.commentText = null;
      this.getComment();
    }
  },
  created() {
    let user = fb.auth().currentUser;
    this.name = user.displayName;
  },
  computed: mapState(["comments"])
};

이 모든 논리를 하나의 구성 요소로 추상화하여 날짜를 표시하는 것이 가장 좋으며, 그 다음 코드 경계를 넘어 업데이트를 유발할 필요가 있다.언제든지 쉽게 날짜 렌더링 논리를 변경할 수 있도록 모든 날짜 렌더링 코드를 최대한 최소화하십시오.

날짜 자체는 데이터지만, 그 날짜의 시각적 표현은 그렇지 않다.그래서 나는 Vuex 매장에 포맷된 날짜를 저장하지 않을 것이다.

구성 요소 생성<from-now>어느 정도 시간이 걸리는 것은date소품으로 그리고 순간의 시간을 이용하여 날짜를 렌더링하다.fromNow. 주기적으로 업데이트(매분마다)도 한다.컴포넌트인 만큼 사용자가 마우스를 올려놓으면 정확한 시간을 알 수 있도록 전체 날짜를 툴팁으로 표시할 수 있다.

const components = new Set();

// Force update every component at the same time periodically
setInterval(() => {
  for (const comp of components) {
    comp.$forceUpdate();
  }
}, 60 * 1000);

Vue.component('FromNow', {
  template: '<span :title="title">{{ text }}</span>',
  props: ['date'],
  
  created() {
    components.add(this);
  },
  
  destroyed() {
    components.remove(this);
  },
  
  computed: {
    text() {
      return moment(this.date).fromNow();
    },
    
    title() {
      return moment(this.date).format('dddd, MMMM Do YYYY, h:mm:ss a');
    },
  },
});

new Vue({
  el: '#app',
  
  data: {
    // Test various seconds ago from now
    dates: [5, 60, 60 * 5, 60 * 60].map(sec => moment().subtract(sec, 'seconds')),
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

<div id="app">
  <p v-for="date of dates">
    <from-now :date="date"></from-now>
  </p>
</div>

단순함을 위해서<from-now>상대적인 날짜만 표시한다.나는 이것과 비슷한 구성요소를 사용하지만 좀 더 범용적이다.그것은 시간이 걸린다.format날짜를 표시할 방법을 선택할 수 있는 소품(상대 시간일 수 있음 또는 순간이 수락하는 특정 날짜 형식일 수 있음)

다른 작업을 추가하고 매 초마다 작업을 전송하십시오.

 mutations: {
    loadComments: (state, comments) => {
      state.comments = comments;
    },
   update:(state)=>{
    state.comments=state.comments.map(comment=>{
     comment.ago= moment()
          .startOf(comment.timestamp)
          .fromNow();
        return comment;
     });
   }
  },
 actions: {
  updateComments(context){
   context.commit('update')
   },  
  loadComments: async (context) => {
    ....

그리고

 created() {
    let user = fb.auth().currentUser;
    this.name = user.displayName;
 setInterval(() => {
      this.$store.dispatch("updateComments");
    }, 1000);
  },

참조URL: https://stackoverflow.com/questions/61297093/vue-momentjs-update-relative-time-in-real-time-from-timestamp

반응형