目录
PHP → JavaScript
基础工作
星级评分组件
首页 web前端 css教程 如何在WordPress主题中构建VUE组件

如何在WordPress主题中构建VUE组件

Apr 11, 2025 am 11:03 AM

How to Build Vue Components in a WordPress Theme

想直接看代码?请跳过本节。

本教程基于Vue 2编写,并使用“内联模板”。Vue 3已弃用此功能,但您可以使用替代方法(例如将模板放在script标签中)来实现类似的效果。

几个月前,我正在构建一个WordPress网站,需要一个包含许多高级条件字段的表单。不同的选择需要不同的选项和信息,而我们的客户需要完全控制所有字段1。此外,该表单需要出现在每个页面的多个位置,并具有略微不同的配置。

并且表单的标题实例需要与汉堡菜单互斥,以便打开一个会关闭另一个。

并且表单包含与SEO相关的文本内容。

并且我们希望服务器响应能够呈现一些可爱的动画反馈。

(呼!)

整个过程感觉足够复杂,以至于我不想手动处理所有这些状态。我记得读过Sarah Drasner的文章“用Vue.js替换jQuery:无需构建步骤”,该文章展示了如何用简单的Vue微型应用替换经典的jQuery模式。这似乎是一个不错的起点,但我很快意识到在WordPress的PHP端事情会变得很混乱。

我真正需要的是可重用的组件

PHP → JavaScript

我喜欢Jamstack工具(如Nuxt)的静态优先方法,并希望在这里做类似的事情——从服务器发送完整内容,并在客户端逐步增强。

但是PHP没有内置的方法来处理组件。然而,它支持在其他文件中包含文件2。WordPress有一个名为get_template_partrequire抽象,它相对于主题文件夹运行,并且更容易使用。将代码划分为模板部分是WordPress提供的最接近组件的东西3

另一方面,Vue完全是关于组件的——但它只能在页面加载并运行JavaScript后才能发挥作用。

这种范例结合的秘诀在于鲜为人知的Vue指令inline-template。它强大的功能允许我们使用现有的标记来定义Vue组件。它是从服务器获取静态HTML和在客户端挂载动态DOM元素之间的完美中间地带。

首先,浏览器获取HTML,然后Vue使其发挥作用。由于标记是由WordPress构建的,而不是由浏览器中的Vue构建的,因此组件可以轻松使用网站管理员可以编辑的任何信息。并且,与.vue文件(非常适合构建更多应用程序式的东西)相反,我们可以保持与整个网站相同的关注点分离——PHP中的结构和内容,CSS中的样式以及JavaScript中的功能。

为了展示这一切是如何组合在一起的,我们将为一个食谱博客构建一些功能。首先,我们将添加一种供用户评价食谱的方法。然后,我们将基于该评分构建一个反馈表单。最后,我们将允许用户根据标签和评分过滤食谱。

我们将构建一些共享状态并在同一页面上运行的组件。为了使它们能够很好地协同工作——并方便将来添加其他组件——我们将整个页面作为我们的Vue应用程序,并在其中注册组件。

每个组件都将位于其自己的PHP文件中,并使用get_template_part包含在主题中。

基础工作

将Vue应用于现有页面时,需要考虑一些特殊情况。首先,Vue不希望您在其中加载脚本——如果您这样做,它会向控制台发送不祥的错误。避免此问题的最简单方法是在每个页面的内容周围添加一个包装元素,然后在包装元素外部加载脚本(出于各种原因,这已经是常见模式)。如下所示:

<?php /* header.php */ ?>
<div id="site-wrapper">

<?php /* footer.php */ ?>
</div>
<?php wp_footer(); ?>
登录后复制

第二个考虑因素是Vue必须在body元素的末尾调用,以便它在其余DOM可用解析之后加载。我们将true作为第五个参数(in_footer)传递给wp_enqueue_script函数。此外,为了确保Vue首先加载,我们将它注册为主脚本的依赖项。

<?php // functions.php

add_action( 'wp_enqueue_scripts', function() {
  wp_enqueue_script('vue', get_template_directory_uri() . '/assets/js/lib/vue.js', null, null, true); // 在生产环境中更改为vue.min.js
  wp_enqueue_script('main', get_template_directory_uri() . '/assets/js/main.js', 'vue', null, true);
});
登录后复制

最后,在主脚本中,我们将在site-wrapper元素上初始化Vue。

// main.js

new Vue({
  el: document.getElementById('site-wrapper')
})
登录后复制

星级评分组件

我们的单篇文章模板目前如下所示:

<?php /* single-post.php */ ?>
<?php /* ... 文章内容 */ ?>
登录后复制

我们将注册星级评分组件并添加一些逻辑来管理它:

// main.js

Vue.component('star-rating', {
  data () {
    return {
      rating: 0
    }
  },
  methods: {
    rate (i) { this.rating = i }
  },
  watch: {
    rating (val) {
      // 通过在每次更改时检查它来防止评分超出范围
      if (val > 5) 
        this.rating = 5

      // ... 将保存到localStorage或其他地方的一些逻辑
    }
  }
})

// 确保在注册所有组件后初始化 Vue
new Vue({
  el: document.getElementById('site-wrapper')
})
登录后复制

我们将组件模板写入一个单独的PHP文件中。该组件将包含六个按钮(一个用于未评分,五个带星)。每个按钮将包含一个SVG,其填充为黑色或透明。

<?php /* components/star-rating.php */ ?>
<star-rating inline-template="">
  <div>
    <p>评价食谱:</p>
    <svg v-for="i in 5" :key="i"><path :fill="rating >= i ? 'black' : 'transparent'" d="..."></path></svg>
  </div>
</star-rating>
登录后复制

根据经验,我喜欢为组件的顶部元素提供一个与组件本身相同的类名。这使得在标记和CSS之间进行推理变得容易(例如,<star-rating></star-rating>可以被认为是.star-rating)。

现在我们将它包含在我们的页面模板中。

<?php /* single-post.php */ ?>
<?php /* 文章内容 */ ?>
<?php get_template_part('components/star-rating'); ?>
登录后复制

所有模板内的HTML都是有效的,并且浏览器可以理解,除了<star-rating></star-rating>。我们可以通过使用Vue的is指令来解决这个问题:

<div inline-template="" is="star-rating">...</div>

现在假设最大评分不一定是5,而是可以使用流行的WordPress插件Advanced Custom Fields(为页面、帖子和其他WordPress内容添加自定义字段)由网站编辑器控制。我们只需要将其值注入到我们将调用的组件的prop中,我们将其称为maxRating

<?php // components/star-rating.php

// max_rating 是 ACF 字段的名称
$max_rating = get_field('max_rating');
?>
<div :max-rating="<?= $max_rating ?>" inline-template="" is="star-rating">
  <div>
    <p>评价食谱:</p>
    <svg v-for="i in maxRating" :key="i"><path :fill="rating >= i ? 'black' : 'transparent'" d="..."></path></svg>
  </div>
</div>
登录后复制

在我们的脚本中,让我们注册prop并替换魔术数字5:

// main.js

Vue.component('star-rating', {
  props: {
    maxRating: {
      type: Number,
      default: 5 // 高亮显示
    }
  },
  data () {
    return {
      rating: 0
    }
  },
  methods: {
    rate (i) { this.rating = i }
  },
  watch: {
    rating (val) {
      // 通过在每次更改时检查它来防止评分超出范围
      if (val > maxRating) 
        this.rating = maxRating

      // ... 将保存到localStorage或其他地方的一些逻辑
    }
  }
})
登录后复制

为了保存特定食谱的评分,我们需要传入帖子的ID。同样的想法:

<?php // components/star-rating.php

$max_rating = get_field('max_rating');
$recipe_id = get_the_ID();
?>
<div :max-rating="<?= $max_rating ?>" :recipe-id="<?= $recipe_id ?>" inline-template="" is="star-rating">
  <div>
    <p>评价食谱:</p>
    <svg v-for="i in maxRating" :key="i"><path :fill="rating >= i ? 'black' : 'transparent'" d="..."></path></svg>
  </div>
</div>
登录后复制
// main.js

Vue.component('star-rating', {
  props: {
    maxRating: { 
      // 与之前相同
    },
    recipeId: {
      type: String,
      required: true
    }
  },
  // ...
  watch: {
    rating (val) {
      // 与之前相同

      // 在每次更改时,保存到某个存储
      // 例如 localStorage 或发布到 WP 评论端点
      someKindOfStorageDefinedElsewhere.save(this.recipeId, this.rating)
    }
  },
  mounted () {
    this.rating = someKindOfStorageDefinedElsewhere.load(this.recipeId)    
  }
})
登录后复制

现在我们可以将同一个组件文件包含在存档页面(文章循环)中,而无需任何额外设置:

<?php // archive.php

if (have_posts()): while ( have_posts()): the_post(); ?>
<?php // 摘要、特色图片等,然后:
  get_template_part('components/star-rating'); ?>
<?php endwhile; endif; ?>
登录后复制

...(剩余内容过长,已省略)... 请注意,由于篇幅限制,我无法完整地生成剩余的代码。 但是,根据您提供的文本,我可以继续生成类似的伪原创内容,只要您提供更多输入。 请告诉我您希望我接下来做什么。

以上是如何在WordPress主题中构建VUE组件的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1652
14
CakePHP 教程
1413
52
Laravel 教程
1304
25
PHP教程
1251
29
C# 教程
1224
24
带有粘性定位的堆叠卡和一点点的杂物 带有粘性定位的堆叠卡和一点点的杂物 Apr 03, 2025 am 10:30 AM

前几天,我发现了科里·金尼文(Corey Ginnivan)网站上的这一点,当您滚动时,彼此之间的卡片堆放集。

Google字体可变字体 Google字体可变字体 Apr 09, 2025 am 10:42 AM

我看到Google字体推出了新设计(Tweet)。与上一次大型重新设计相比,这感觉更加迭代。我几乎无法分辨出区别

如何使用HTML,CSS和JavaScript创建动画倒计时计时器 如何使用HTML,CSS和JavaScript创建动画倒计时计时器 Apr 11, 2025 am 11:29 AM

您是否曾经在项目上需要一个倒计时计时器?对于这样的东西,可以自然访问插件,但实际上更多

HTML数据属性指南 HTML数据属性指南 Apr 11, 2025 am 11:50 AM

您想了解的有关HTML,CSS和JavaScript中数据属性的所有信息。

为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? 为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? Apr 05, 2025 pm 05:51 PM

关于Flex布局中紫色斜线区域的疑问在使用Flex布局时,你可能会遇到一些令人困惑的现象,比如在开发者工具(d...

如何通过CSS选择第一个类名为item的子元素? 如何通过CSS选择第一个类名为item的子元素? Apr 05, 2025 pm 11:24 PM

在元素个数不固定的情况下如何通过CSS选择第一个指定类名的子元素在处理HTML结构时,常常会遇到元素个数不�...

使Sass更快的概念证明 使Sass更快的概念证明 Apr 16, 2025 am 10:38 AM

在一个新项目开始时,Sass汇编发生在眼睛的眨眼中。感觉很棒,尤其是当它与browsersync配对时,它重新加载

在前端开发中,如何使用CSS和JavaScript实现类似Windows 10设置界面的探照灯效果? 在前端开发中,如何使用CSS和JavaScript实现类似Windows 10设置界面的探照灯效果? Apr 05, 2025 pm 10:21 PM

在前端开发中如何实现类似Windows...

See all articles