kato24265
@kato24265

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

vue.jsの更新時のちらつきについて

解決したいこと

Vue.jsの画面が切り替わるタイミング、または
更新時に動画ファイルとpdf表示のフレームが一瞬表示される
ちらつき現象を直したいです。

div class="preview"〜の部分で、
添付ファイルのプレビュー画面を表示しておりまして、
動画ファイルか、PDFかをv-ifで判断しているのですが、
ちらつく要因が分からず、解決方法分かりましたら、
ご教示いただけますと幸いです。

該当するソースコード

<div class="preview" v-if="news.file_data.mp4 != ''">
         <video controls controlsList="nodownload" oncontextmenu="return false;" v-bind:src="news.file_data.mp4"></video>
                        </div>
                        <div class="preview" v-if="news.file_data.pdf != ''">
                            <iframe width="100%" height="100%" v-bind:src="news.file_data.pdf"></iframe>
                        </div>
                    </div>
                </div>
                <div class="delivery_date_box">
                    <p>ニュース配信予約日時</p>
                    <input v-bind:value="news.post_date | dateFormat" v-on:input="inputEvent" type="datetime-local" required />
                </div>
            </div>
            <div class="news_edit_btns">
                <router-link :to="{name: 'AdminNewsList'}">戻る</router-link>
                <div class="news_edit_right_btns">
                    <button class="red_btn" v-on:click="delte_notice">削除</button>
                    <button class="green_btn" v-on:click="fileUpload">内容確認</button>
                </div>
            </div>
        </form>
    </div>

<script>
import moment from 'moment'
import axios from 'axios'
export default {
    data () {
        return {
            fileInfo: '',
            err_catch: false,
            news_data: '',
            news_files:'',
            news_filename:'',
            url_protcol: 'http://',
            domain: 
            url_mount_path: '/rest/get_notice_detail/',
            url_delete_path: '/rest/delete_notice/',
            url_upload_path: '/rest/upload_file/',
            height: "100px"
        }
    },
    mounted () {
        this.axios
        .post(this.url_protcol + this.domain + this.url_mount_path + this.$route.query.id + '/',{},{
            headers: {
                    "Content-Type": "application/json", 
                    "Authorization": this.$store.state.userToken 
                }
        })
        .then(response => {
            this.news_data = response.data
            this.news.notice_title = this.news_data.title
            this.news.notice_text = this.news_data.body
            this.news.post_date = this.news_data.post_date
            this.news.notice_id = this.news_data.notice_id
            this.news_files = {"mp4":this.news_data.attach_file_mp4,"pdf":this.news_data.attach_file_pdf,"file_name":""}
            this.news.file_data = this.news_files
        }),
        this.resize();
    },



自分で試したこと

div class="preview"の欄にv-cloakを追記しましたが、マスタッシュ構文を使用していない為、効果はありませんでした。
以下の2文を削除すると、ちらつきは解消されたのですが、プレビュー機能もなくなってしまう。

 <video controls controlsList="nodownload" oncontextmenu="return false;" v-bind:src="news.file_data.mp4">
 </video>
<iframe width="100%" height="100%" v-bind:src="news.file_data.pdf"></iframe>
0

2Answer

v-if="!!news.file_data.mp4 == true"

取り急ぎ、とかにしてみてはいかがでしょう?

理由は、newsオブジェクトに値が入る前に評価されている為だと推察されます。
ちらつく->一瞬trueで評価される理由は、以下の理由が現時点で濃厚な様に思えます。
Screenshot from 2022-04-20 18-49-13.png

1Like

Comments

  1. @kato24265

    Questioner

    ありがとうございます。
    上記適応したところ、動画とPDF表示のちらつきが解消されました。

    もう一点、編集画面で登録後に、再編集の為に上記の画面を開いた際に、
    PDFとMP4だけでなく、全体的に初期画面が一瞬表示されることがが分かりました。

    大変お手数なのですが、要因と対処方法が分かりそうでしたらご教示いただけますと幸いです。

    ちらつく部分

    <input v-model="news.notice_title" placeholder="タイトルを入力してください。" maxlength="50" type="text" required />


    <textarea v-model="news.notice_text" placeholder="本文を入力してください。" maxlength="250" type="text" required ref="area" :style="styles"></textarea>


    <div class="delivery_date_box">
    <p>ニュース配信予約日時</p>
    <input v-bind:value="news.post_date | dateFormat" v-on:input="inputEvent" type="datetime-local" required />
    </div>



    <div class="news_edit_btns">
    <router-link :to="{name: 'AdminNewsList'}">戻る</router-link>
    <div class="news_edit_right_btns">
    <button class="red_btn" v-on:click="delte_notice">削除</button>
    <button class="green_btn" v-on:click="fileUpload">内容確認</button>
    </div>

moutedでnewsオブジェクトを取得していると思うのですが、moutedは一度DOMが描写された後に処理が走ります。つまり、mounted内の処理でajax通信している間、初期表示がされます。

もしDOM操作をしないのであれば、createdやbreforeMount等に変更してはいかがでしょうか?
https://johobase.com/vue-js-life-cycle-hooks-v3/
https://qiita.com/tanoken729b/items/5770d4c620163a25ad21

あとちょっと気になったのは、mouted内でデータを取得するのにpostを使っていますが、getが適当なのでは?
この辺りも参考になるので一読してみてはいかがでしょうか?
https://qiita.com/kanataxa/items/522efb74421255f0e0a1

1Like

Comments

  1. @kato24265

    Questioner

    ご丁寧に度々、ご教示いただきまして誠にありがとうございます。
    また、資料の方もありがとうございます。
    私がまだまだ初心者の身でして、下記の部分を変更してみたのですが、
    初期描写が解消されないようでした。

    そもそも、適用場所が合っているのかも判断ができなく、
    もし、間違っていたり、その他で解決方法ありそうでしたら、
    その際には、ご教示いただけますと幸いでございます。

    ① createdに変更
      
    動作 : 変わらず初期画面表示がちらつく。

    created() {
    this.axios
    .post(this.url_protcol + this.domain + this.url_mount_path + this.$route.query.id + '/',{},{
    headers: {
    "Content-Type": "application/json",
    "Authorization": this.$store.state.userToken
    }
    })

    ② beforeMounに変更

    動作: 初期画面表示のみになる。

    beforeMoun() {
    this.axios
    .post(this.url_protcol + this.domain + this.url_mount_path + this.$route.query.id + '/',{},{
    headers: {
    "Content-Type": "application/json",
    "Authorization": this.$store.state.userToken
    }
    })

    ③ post → getに変更

     動作 : 初期表示のみになる。
  2. >beforeMoun

    tが抜けていませんか?
  3. @kato24265

    Questioner

    ご返信ありがとうございます。
    すみません。上記への記載抜けでした。
    ソースの方にはbeforeMountと記載していたのですが、
    解消されずのようです。

Your answer might help someone💌