书接上回,我们使用 Vue3 技术撰写前端,为了与后台进行交互,包括从前端加载的开始获取初始设置数据等,都需要从 PHP 中获取数据,但我们开发的项目打包后,只有 JS 文件,因此,开发的第一件事就是解决 PHP 传值给 JS 的问题。
为了方便我们的功能实现,我们开发一个简单的插件。简单介绍下软件环境,都是三平台通用的,大家能都用
- 编辑器:Visual Studio Code
- 环境:Local
目标
通过 PHP,将所需数据传给 JS 文件,并在 JS 文件中打印出来。
准备环境
VS Code 下载后安装使用即可。
Local 下载安装后,可点击左下角“+”按钮,一路默认选择,填写站点名称即可.
创建后,如下所示,
左侧列表选择自己创建的站点,
- 点击 Go to site folder 进入站点文件夹,选择 app → public 即可看到站点根目录文件
- 点击 WP Admin 即可进入站点后台
我们先在 WordPress 站点的wp-content/plugins
目录下新建文件夹 vue-spa ,我们在这里撰写代码,实现我们的功能。
准备插件信息并启用
现在,我们在 vue-spa 文件夹下添加新文件“vue-spa.php”文件,写入以下内容
//vue-spa.php
<?php
/*
Plugin Name: Vue - SPA
Plugin URI: https://www.npc.ink
Description: 将vue构建的页面嵌入WordPress 中并产生交互
Author: Muze
Author URI: https://www.npc.ink
Version: 1.0.0
*/
分别代表:
- 插件名
- 插件介绍网址
- 插件功能介绍
- 插件作者
- 插件作者介绍网站
- 插件版本
现在,我们的插件准备好了,点击 WP Admin 即可进入站点后台,进入插件页面,选择 Vue - SPA 插件启用吧
准备菜单
为了验证我们准备的数据,需要一个地方来展示,方便验证,就做个菜单出来。承接上文,添加以下代码
//创建一个菜单
function vuespa_create_menu_page()
{
add_menu_page(
'VueSpa选项', // 此菜单对应页面上显示的标题
'VueSpa', // 要为此实际菜单项显示的文本
'administrator', // 哪种类型的用户可以看到此菜单
'vuespa_id', // 此菜单项的唯一ID(即段塞)
'vuespa_menu_page_display', // 呈现此页面的菜单时要调用的函数的名称
'dashicons-admin-customizer', //图标 - 默认图标
'500.1', //位置
);
} // end vuespa_create_menu_page
add_action('admin_menu', 'vuespa_create_menu_page');
//菜单回调 - 展示的内容
function vuespa_menu_page_display()
{
?>
<!--在默认WordPress“包装”容器中创建标题-->
<div class="wrap">
<!--标题-->
<h2><?php echo esc_html(get_admin_page_title()); ?></h2>
<!--提供Vue挂载点-->
<div id="vuespa">此内容将在挂载Vue后被替换</div>
</div>
<?php
} // vuespa_menu_page_display
代码的用途我放注释了,大家可以看看,主要作用是,在 WordPress 后台创建一个菜单,并展示一段话。
- 其中的 class 样式
class="wrap"
是 WordPress 自带的,有利于页面的一致性。 - 其中的图标,可在本节的开始提供的网址中获取,是 WordPress 的自带图标
现在,我们刷新 WordPress 后台,可以找到 VueSpa 菜单,点击打开即可。
若没有此菜单,请检查是否启用了 Vue - SPA 插件
准备JS文件接收数据
为了确定 PHP 传给 JS 的数据是成功的,我们需要在 JS 文件中进行验证。
我们在插件文件夹下新建文件夹 vite 和 dist 文件夹,并新建 index.js 和index.css 文件,结构类似这样
vue-spa/vite/dist/index.js
vue-spa/vite/dist/index.css
index.js 写入以下代码
//vite/dist/index.js
alert("我加载啦 - Npcink")
index.css 暂时不写
现在,我们需要在 vue-spa.php 文件中载入 index.js 文件,我们在 vue-spa.php 文件中添加以下代码
//载入所需 JS 和 CSS 资源
function vuespa_load_vues($hook)
{
//判断当前页面是否是指定页面,是则继续加载
if ('toplevel_page_vuespa_id' != $hook) {
return;
}
//版本号
$ver = '52';
//加载到页面顶部
wp_enqueue_style('vite', plugin_dir_url(__FILE__) . 'vite/dist/index.css', array(), $ver, false);
wp_enqueue_script('vite', plugin_dir_url(__FILE__) . 'vite/dist/index.js', array(), $ver, false);
}
//样式加载到后台
add_action('admin_enqueue_scripts', 'vuespa_load_vues');
现在,我们只有打开 VueSpa 菜单才会有弹窗。此时,我们就加载了 JS 文件。
准备数据
我们通过PHP准备数据,在JS文件中通过弹窗显示出来。
我们在 vue-spa.php 页面底部添加以下代码准备数据
//准备待传输的数据
function vuespa_data()
{
$person = [
"str" => "Hello, world!",
"num" => 25,
"city" => [1, 2, 3, 4, 5],
];
return $person;
}
为了看到数据是否做好,我们修改下菜单回调函数 vuespa_menu_page_display()
,先用PHP将数据展示看看
//菜单回调 - 展示的内容
function vuespa_menu_page_display()
{
?>
<!--在默认WordPress“包装”容器中创建标题-->
<div class="wrap">
<!--标题-->
<h2><?php echo esc_html(get_admin_page_title()); ?></h2>
<!--提供Vue挂载点-->
<div id="vuespa">此内容将在挂载Vue后被替换</div>
</div>
<?php
//展示准备的数据
echo "<pre>";
print_r(vuespa_data());
echo "</pre>";
} // vuespa_menu_page_display
效果如下:
数据展示正常,
传递数据
传递数据,我们要用到 wp_localize_script()
函数,修改我们载入JS的函数 vuespa_load_vues()
//载入所需 JS 和 CSS 资源 并传递数据
function vuespa_load_vues($hook)
{
//判断当前页面是否是指定页面,是则继续加载
if ('toplevel_page_vuespa_id' != $hook) {
return;
}
//版本号
$ver = '52';
//加载到页面顶部
wp_enqueue_style('vite', plugin_dir_url(__FILE__) . 'vite/dist/index.css', array(), $ver, false);
wp_enqueue_script('vite', plugin_dir_url(__FILE__) . 'vite/dist/index.js', array(), $ver, false);
$pf_api_translation_array = array(
'route' => esc_url_raw(rest_url()), //路由
'nonce' => wp_create_nonce('wp_rest'), //验证标记
'data' => vuespa_data(), //自定义数据
);
wp_localize_script('vite', 'dataLocal', $pf_api_translation_array); //传给vite项目
}
//样式加载到后台
add_action('admin_enqueue_scripts', 'vuespa_load_vues');
再修改我们的 index.js 文件,将拿到的数据打印出来
//vite/dist/index.js
console.table(dataLocal);
在WordPress 中,点击VueSpa菜单,使用浏览器的开发者工具,即可在控制台中看到传递的数据
其中,各个数据的用途可见注释
'route' => esc_url_raw(rest_url()), //路由
'nonce' => wp_create_nonce('wp_rest'), //验证标记
'data' => vuespa_data(), //自定义数据
nonce: "82711b7680"
route: "http://localhost:10004/wp-json/"
- 我们通过传来的路由,知道要发出 POST 请求的网址
- 我们通过传来的验证标记,在发出 POST 请求时进行身份验证
- 我们通过传来的data数据,在 JS 文件中进行进一步的操作
补充
vue-spa.php 本节完整代码
<?php
/*
Plugin Name: Vue - SPA
Plugin URI: https://www.npc.ink
Description: 将vue构建的页面嵌入WordPress 中并产生交互
Author: Muze
Author URI: https://www.npc.ink
Version: 1.0.0
*/
//创建一个菜单
function vuespa_create_menu_page()
{
add_menu_page(
'VueSpa选项', // 此菜单对应页面上显示的标题
'VueSpa', // 要为此实际菜单项显示的文本
'administrator', // 哪种类型的用户可以看到此菜单
'vuespa_id', // 此菜单项的唯一ID(即段塞)
'vuespa_menu_page_display', // 呈现此页面的菜单时要调用的函数的名称
'dashicons-admin-customizer', //图标 - 默认图标
'500.1', //位置
);
} // end vuespa_create_menu_page
add_action('admin_menu', 'vuespa_create_menu_page');
//菜单回调 - 展示的内容
function vuespa_menu_page_display()
{
?>
<!--在默认WordPress“包装”容器中创建标题-->
<div class="wrap">
<!--标题-->
<h2><?php echo esc_html(get_admin_page_title()); ?></h2>
<!--提供Vue挂载点-->
<div id="vuespa">此内容将在挂载Vue后被替换</div>
</div>
<?php
//展示准备的数据
echo "<pre>";
print_r(vuespa_data());
echo "</pre>";
} // vuespa_menu_page_display
//载入所需 JS 和 CSS 资源 并传递数据
function vuespa_load_vues($hook)
{
//判断当前页面是否是指定页面,是则继续加载
if ('toplevel_page_vuespa_id' != $hook) {
return;
}
//版本号
$ver = '52';
//加载到页面顶部
wp_enqueue_style('vite', plugin_dir_url(__FILE__) . 'vite/dist/index.css', array(), $ver, false);
wp_enqueue_script('vite', plugin_dir_url(__FILE__) . 'vite/dist/index.js', array(), $ver, false);
$pf_api_translation_array = array(
'route' => esc_url_raw(rest_url()), //路由
'nonce' => wp_create_nonce('wp_rest'), //验证标记
'data' => vuespa_data(), //自定义数据
);
wp_localize_script('vite', 'dataLocal', $pf_api_translation_array); //传给vite项目
}
//样式加载到后台
add_action('admin_enqueue_scripts', 'vuespa_load_vues');
//准备待传输的数据
function vuespa_data()
{
$person = [
"str" => "Hello, world! - Npcink",
"num" => 25,
"city" => [1, 2, 3, 4, 5],
];
return $person;
}
获取hook变量
若您想知道当前页面的hook变量,可在 vue-spa.php 页面底部添加以下代码获取
function wpdocs_myselective_css_or_js($hook)
{
echo '<h1 style="color: crimson;text-align: center;">' . esc_html($hook) . '</h1>';
}
//获取当前页面hook
add_action('admin_enqueue_scripts', 'wpdocs_myselective_css_or_js');