vue3.jsでWordPressを無限スクロールするコードを書いた話.

2024.09.21

Logging

おはようございます.長いので説明は省きますが、これは生成AIと自分との合作みたいなコードです.一度目の指示では上手くコードを生成してくれなかったので何度か壁打ちみたいなことをしました.尚、WordPressと言ってもREST APIとかいうのを使用した奴です.WordPress側でREST APIを有効にしないと上手く機能しませんのであしからず🙇.

そして、このコードはスマホとPCではスクロール位置が違うようになっているサイト用の専用コードです.なので、普通のレスポンシブ対応サイトだったら判断部分を削除してbody対応のコードだけで無限スクロールが可能になります.

因みにこんな事をしなくてもv3-infinite-loadingのライブラリが合ったりします.それを使用するともっと効率的なコードが書けるみたいだけども、自分はvue初心者さんなのでこんな感じになってます.

          <div id='app' class="page">
            <?php if (have_posts()):?>
                <div v-for="post in posts" :key="post.id" class="blogpage">
                  <h3>{{ post.title.rendered }}</h3>
                  <p> {{ formattedDate(post.date) }}</p>
                  <p v-html="post.content.rendered"></p>
                </div>
            <?php endif; ?>                
          </div>    
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/moment@2.30.1/min/moment.min.js"></script>
<script src="<?= get_template_directory_uri() ?>/asset/Infinity.js?<?=time()?>" type="module" ></script>
import { ref, onMounted, onUnmounted, createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';

createApp({
    setup() {

        const posts = ref([]);
        const page = ref(1);
        const loading = ref(false);
        const hasMore = ref(true);

        onMounted(async () => {
            await fetchPosts();

            if (window.innerWidth < 600) {
                window.addEventListener('scroll', handleScroll);
            } else {
                document.querySelector('#app').addEventListener('scroll', handleScroll);
            }

        });

        onUnmounted(() => {
            if (window.innerWidth < 600) {
                document.documentElement.removeEventListener('scroll', handleScroll);
            } else {
                document.querySelector('#app').removeEventListener('scroll', handleScroll);
            }
        });
        const formattedDate = (dateString) => {
            return moment(dateString).format('YYYY年MM月DD日');
        };

        const fetchPosts = async () => {
            if (loading.value || !hasMore.value) return;

            loading.value = true;
            try {
                const response = await axios.get(`/wp-json/wp/v2/posts?page=${page.value}`);
                if (response?.data?.length) {
                    posts.value = [...posts.value, ...response.data];
                    page.value++;
                    hasMore.value = true;
                }else{
                    hasMore.value = false;
                }

            } catch (error) {
                //console.error(error);
            } finally {
                loading.value = false;
            }
        };

        const handleScroll = async () => {
            let scrollHeight = null;
            let clientHeight = null;
            let scrollTop = null;

            if (window.innerWidth < 600) {
                scrollHeight = document.documentElement.scrollHeight;
                clientHeight = document.documentElement.clientHeight;
                scrollTop = document.documentElement.scrollTop;

            } else {
                scrollHeight = document.querySelector('#app').scrollHeight;
                clientHeight = document.querySelector('#app').clientHeight;
                scrollTop = document.querySelector('#app').scrollTop;
            }

            if (scrollTop + clientHeight >= scrollHeight - 100 && hasMore.value) {
                await fetchPosts();
            }
        };
        return { posts, page, loading, hasMore, fetchPosts, handleScroll, formattedDate };
    }

}).mount('#app')

明日へ続く.

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

addEventListener, asset, async, catch, createApp, dateString, document.querySelector, finally, formattedDate, handleScroll, loading.value, mount, onMounted, onUnmounted, removeEventListener, response, response.data, setup, window.addEventListener, window.innerWidth,

VirtualBoxで共有フォルダ設定とApacheが表示されるまで。

2020.11.29

Logging

前処理としてこのコマンドを打つ。

yum -y groupinstall "Development Tools"
yum -y update kernel
yum -y install kernel-devel kernel-headers gcc gcc-c++

起動したらメニューから[デバイス]-[Guest Additions CDイメージの挿入]

mount /dev/cdrom /mnt
cd /mnt
./VBoxLinuxAdditions.run

reboot
cd /var/www/
ln -s マウント先 sf_html
gpasswd -a oreore vboxsf
gpasswd -a apache vboxsf

mount -t vboxsf -o dmode=0755,fmode=0755 (共有名) (マウント先)

reboot

Apacheのconfig設定ではリンク先はシンボルリンクを参照させとこう、これでリブートさせて完了やねん。さてこれで理解できたら、あなたは凄いです。これは単なるメモ書き記載なので、わからないと思います。

なので、参考にしたサイトのリンクを貼っときます。
http://itemy.net/?p=1355
https://www.codelab.jp/blog/?p=2587

これらでおそらく大体の人が理解できたと思います。

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

-o, -s, -t, -y, 0755, A`, Additions, Apache, cd, cdrom, dev, Development, dmode, fmode, gcc, gcc-c, gpasswd, groupinstall, Guest, html, install, kernel, kernel-devel, kernel-headers, ln, mnt, mount, oreore, quot, reboot, run, SF, Tools, UPDATE, var, VBoxLinuxAdditions, vboxsf, virtualBOX, www, yum, イメージ, コマンド, デバイス, フォルダ, マウント, メニュー, 共有, 前処理, 挿入, 表示, 設定, 起動,