基于Alpine.js的WordPress文章筛选报错:filterPosts未定义
WordPress文章筛选功能报错修复
报错原因及修复方案
1. Uncaught ReferenceError: posts is not defined
- 问题根源:
fetchPosts方法中使用了未初始化的offset属性,导致AJAX请求参数异常,后端返回错误,最终前端无法正确赋值posts变量。 - 修复:在Alpine数据对象中添加
offset: 0初始化偏移量,同时切换分类时重置偏移量避免分页混乱。
2. Alpine Expression Error: filterPosts is not defined
- 问题根源:Alpine数据组件的命名与内部方法名同为
filterPosts,导致命名冲突,Alpine无法正确识别方法;同时按钮的点击事件上下文需确保指向组件内方法。 - 修复:将Alpine数据组件重命名为
postFilter(避免与方法名冲突),并更新对应x-data的引用。
完整修改后代码
模板文件(test.php)
<?php /* Template Name: test */ ?> <html> <head> <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> <script> Alpine.data("postFilter", (adminURL) => ({ posts: "", limit: 10, offset: 0, // 初始化offset属性 category: null, showDefault: true, showFiltered: false, filterPosts(id) { this.showDefault = false; this.showFiltered = true; this.category = id; this.offset = 0; // 切换分类时重置偏移量 this.fetchPosts(); }, fetchPosts() { var formData = new FormData(); formData.append("action", "filterPosts"); formData.append("offset", this.offset); formData.append("limit", this.limit); if (this.category) { formData.append("category", this.category); } fetch(adminURL, { method: "POST", body: formData, }) .then((res) => res.json()) .then((res) => { this.posts = res.posts; }); }, })); </script> </head> <body> <h1 x-data="{ message: 'I ❤️ Alpine' }" x-text="message"></h1> <div class="flex items-start gap-8 alignwide mt-32" x-data="postFilter('<?php echo admin_url('admin-ajax.php'); ?>')"> <!-- Category Filter Sidebar --> <aside class="w-1/4"> <p class="text-xl font-medium">Categories</p> <?php $categories = get_categories(); if ( ! empty( $categories ) ) : ?> <ul class="list-none px-0"> <?php foreach ( $categories as $category ) : // Skip "Uncategorized" category if ($category->name == 'Uncategorized') continue; ?> <li :class="category == <?php echo $category->term_id; ?> ? 'bg-slate-100' : ''" class="hover:bg-slate-100 my-1 px-4 py-2 -ml-4 rounded-md"> <button @click="filterPosts(<?= $category->term_id; ?>)" class="text-xl text-slate-800 w-full text-left"> <?= esc_html( $category->name ); ?></button> </li> <?php endforeach; ?> </ul> <?php endif; ?> </aside> <!-- Posts Column --> <div class="w-3/4"> <!-- Default posts query --> <div class="grid grid-cols-2 gap-6" x-show.important="showDefault"> <?php $query_args = array( 'posts_per_page' => 10, 'post_status' => 'publish', 'post_type' => 'post' ); $the_query = new WP_Query($query_args); if ($the_query->have_posts()) : while ($the_query->have_posts()) : $the_query->the_post(); ?> <div> <?php if ( has_post_thumbnail() ) { the_post_thumbnail( 'full', array( 'class' => 'm-0' ) ); }?> <p class="text-xl font-medium mt-2"><?php the_title(); ?></p> </div> <?php endwhile; wp_reset_postdata(); endif; ?> </div> </div> <!-- Filtered posts --> <div x-show.important="showFiltered" class="grid grid-cols-2 gap-6" x-html="posts"></div> </div> </body> </html>
后端AJAX处理(添加到主题functions.php)
// 注册AJAX动作 add_action('wp_ajax_filterPosts', 'filter_posts_callback'); add_action('wp_ajax_nopriv_filterPosts', 'filter_posts_callback'); function filter_posts_callback() { // 获取请求参数 $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0; $limit = isset($_POST['limit']) ? intval($_POST['limit']) : 10; $category = isset($_POST['category']) ? intval($_POST['category']) : null; // 构建WP查询参数 $args = array( 'posts_per_page' => $limit, 'offset' => $offset, 'post_status' => 'publish', 'post_type' => 'post' ); // 如果有分类ID,添加分类筛选条件 if ($category) { $args['category__in'] = array($category); } $query = new WP_Query($args); $output = ''; // 生成帖子HTML if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); $output .= '<div>'; if (has_post_thumbnail()) { $output .= get_the_post_thumbnail(get_the_ID(), 'full', array('class' => 'm-0')); } $output .= '<p class="text-xl font-medium mt-2">' . get_the_title() . '</p>'; $output .= '</div>'; } wp_reset_postdata(); } // 返回JSON响应 wp_send_json_success(array('posts' => $output)); }
额外优化说明
- 给默认帖子的容器添加了
x-show.important="showDefault",切换分类后会自动隐藏默认帖子列表,只显示筛选后的内容; - 切换分类时重置
offset为0,确保每次筛选都从第一页开始展示。
内容的提问来源于stack exchange,提问作者Beep
相关产品推荐
相关产品推荐

