-
Input boxes store and modify option values -
The Save button is used to save the option values
Process introduction
Back end preparation
-
Read the option interface and get the initial value of the option at the beginning of the page -
Save option interface, click Save button to save options
//Interface document function vuespa_create_api() { Register_rest_route ('pf/v1 ','/get_option/', array (//The full namespace is:/wp-json/pf/v1/ 'methods' => 'POST', 'callback' => 'get_option_by_RestAPI', )); Register_rest_route ('pf/v1 ','/update_option/', array (//The full namespace is:/wp-json/pf/v1/ 'methods' => 'POST', 'callback' => 'update_option_by_RestAPI', 'permission_callback' => function () { return current_user_can('manage_options'); // Only administrators have permission to modify }, )); } add_action('rest_api_init', 'vuespa_create_api');
Read option interface
//Read Option //Only one-to-one data requests are supported function get_option_by_RestAPI($data) { //Convert the passed data to array type $dataArray = json_decode($data->get_body(), true); //New Array $return = array(); //Loop to obtain the value of the corresponding option ID and store it in the corresponding associative array. If the value cannot be obtained, it is empty foreach ($dataArray as $option_name => $value) { $return[$option_name] = get_option($option_name) ? get_option($option_name) : ""; } return $return; }
Save Option Interface
//Save Option //One to one saving function update_option_by_RestAPI($data) { //Judge whether it is an administrator if (current_user_can('manage_options')) { //Convert the passed data to array type $dataArray = json_decode($data->get_body(), true); //Cycle Save Options foreach ($dataArray as $option_name => $value) { update_option($option_name, $value); } //Return success message return new WP_REST_Response(array( 'success' => true, 'message '=>"Saved!" ), 200); } else { //Return failure information Return new WP_Error ('save_error ','save failed!', array('status' => 500)); } }
introduce
//Interface require_once plugin_dir_path(__FILE__) . ' interface.php';
Front end preparation
Load Resource
//Load the required JS and CSS resources and transfer data function vuespa_load_vues($hook) { //Judge whether the current page is the specified page. If yes, continue loading if ('toplevel_page_vuespa_id' != $ hook) { return; } //Version No $ver = '53'; //Load to top of page wp_enqueue_style('vite', plugin_dir_url(__FILE__) . ' vite/dist/index.css', array(), $ver, false); //Load to bottom of page wp_enqueue_script('vue', ' https://unpkg.com/vue @3/dist/vue.global.js', array(), $ver, true); wp_enqueue_script('axios', ' https://unpkg.com/axios/dist/axios.min.js ', array(), $ver, true); wp_enqueue_script('vite', plugin_dir_url(__FILE__) . ' vite/dist/index.js', array(), $ver, true); $pf_api_translation_array = array( 'route'=>esc_url_raw (rest_url()),//Route 'nonce'=>wp_create_once ('wp_rest '),//Verification mark 'data '=>vuespa_data(),//user-defined data ); wp_localize_script('vite', 'dataLocal', $pf_api_translation_array); // Transfer to vite project } //Load style to background add_action('admin_enqueue_scripts', 'vuespa_load_vues');
Prepare input boxes and buttons
//vite/dist/index.js const App = { setup() { //Initial value const datas = Vue.reactive({ dataOne: "", dataTwo: "", }); //Get Data const vuespa_get_option = () => { axios .post(dataLocal.route + "pf/v1/get_option", datas, { headers: { "X-WP-Nonce": dataLocal.nonce, "Content-Type": "application/json", }, }) .then((response) => { const data = response.data; datas.dataOne = data.dataOne; datas.dataTwo = data.dataTwo; }) .catch((error) => { Window.alert ("Failed to connect to the server or background reading error! Data reading failed"); console.log(error); }); }; //Save Data const vuespa_update_option = () => { axios .post(dataLocal.route + "pf/v1/update_option", datas, { headers: { "X-WP-Nonce": dataLocal.nonce, }, }) .then((response) => { Alert ("saved successfully"); }) .catch((error) => { Alert ("Failed to save"); console.log(error); }); }; //Page initial loading Vue.onMounted(() => { Console.log ("Simple"); vuespa_get_option(); }); return { datas, vuespa_update_option }; }, template: 'Text box 1:<input type="text" v-model="data. dataOne"><br/>Text box 2:<input type="text" v-model="data. dataTwo"><hr/><button class="button button primary" @ click="vuespa_update_option">Save</button>', }; Vue.createApp(App).mount("#vuespa");
-
Created a responsive variable data -
Created a data acquisition function vuespa_get_option() After splicing the URLs from the previous section, send a post request and pass in the verification information in the header. -
Created a function to save data vuespa_update_option() , similar to the above function -
We load at the beginning of the page vuespa_get_option() Function to take the obtained value as the default value of the input box -
We provide two input boxes and a button through the template of vue3, -
The value of input is bound to the variable of data in both directions, and the click event of button is bound vuespa_get_option() Function to save data
Wordpress caches some JS files. It is recommended that you modify the function every time you modify the JS file
vuespa_load_vues() Version number information in
Principle analysis
call
Echo "<h3>Call option value</h3>"; echo get_option('dataOne'); echo "<br/>"; echo get_option('dataTwo');
Complete code
vue-spa.php
<? php /* Plugin Name: Vue - SPA Plugin URI: https://www.npc.ink Description: Embed the page built by vue into WordPress and generate interaction Author: Muze Author URI: https://www.npc.ink Version: 1.0.0 */ //Interface require_once plugin_dir_path(__FILE__) . ' interface.php'; //Create a menu function vuespa_create_menu_page() { add_menu_page( 'VueSpa option',//This menu corresponds to the title displayed on the page 'VueSpa',//The text to be displayed for this actual menu item 'administrator',//which type of user can see this menu 'vuespa_id',//The unique ID of this menu item (i.e. slug) 'vuespa_menu_page_display',//Name of the function to be called when presenting the menu of this page 'dashicons admin customizer ',//icon - default icon '500.1',//Location ); } // end vuespa_create_menu_page add_action('admin_menu', 'vuespa_create_menu_page'); //Menu callback - displayed content function vuespa_menu_page_display() { ?> <!-- Create a title in the default WordPress "wrapper" container --> <div class="wrap"> <!-- Title --> <h2><? php echo esc_html(get_admin_page_title()); ?></ h2> <!-- Provide Vue mount point --> <div id="vuespa">This content will be replaced after mounting Vue {{data}}</div> </div> <? php //Show prepared data echo "<pre>"; print_r(vuespa_data()); echo "</pre>"; Echo "<h3>Call option value</h3>"; echo get_option('dataOne'); echo "<br/>"; echo get_option('dataTwo'); } // vuespa_menu_page_display //Load the required JS and CSS resources and transfer data function vuespa_load_vues($hook) { //Judge whether the current page is the specified page. If yes, continue loading if ('toplevel_page_vuespa_id' != $ hook) { return; } //Version No $ver = '53'; //Load to top of page wp_enqueue_style('vite', plugin_dir_url(__FILE__) . ' vite/dist/index.css', array(), $ver, false); //Load to bottom of page wp_enqueue_script('vue', ' https://unpkg.com/vue @3/dist/vue.global.js', array(), $ver, true); wp_enqueue_script('axios', ' https://unpkg.com/axios/dist/axios.min.js ', array(), $ver, true); wp_enqueue_script('vite', plugin_dir_url(__FILE__) . ' vite/dist/index.js', array(), $ver, true); $pf_api_translation_array = array( 'route'=>esc_url_raw (rest_url()),//Route 'nonce'=>wp_create_once ('wp_rest '),//Verification mark 'data '=>vuespa_data(),//user-defined data ); wp_localize_script('vite', 'dataLocal', $pf_api_translation_array); // Transfer to vite project } //Load style to background add_action('admin_enqueue_scripts', 'vuespa_load_vues'); //Prepare the data to be transmitted function vuespa_data() { $person = [ "str" => "Hello, world! - Npcink", "num" => 25, "city" => [1, 2, 3, 4, 5], ]; return $person; }
interface.php
<? php //interface.php //Interface document function vuespa_create_api() { Register_rest_route ('pf/v1 ','/get_option/', array (//The full namespace is:/wp-json/pf/v1/ 'methods' => 'POST', 'callback' => 'get_option_by_RestAPI', )); Register_rest_route ('pf/v1 ','/update_option/', array (//The full namespace is:/wp-json/pf/v1/ 'methods' => 'POST', 'callback' => 'update_option_by_RestAPI', 'permission_callback' => function () { return current_user_can('manage_options'); // Only administrators have permission to modify }, )); } add_action('rest_api_init', 'vuespa_create_api'); //Read Option //Only one-to-one data requests are supported function get_option_by_RestAPI($data) { //Convert the passed data to array type $dataArray = json_decode($data->get_body(), true); //New Array $return = array(); //Loop to obtain the value of the corresponding option ID and store it in the corresponding associative array. If the value cannot be obtained, it is empty foreach ($dataArray as $option_name => $value) { $return[$option_name] = get_option($option_name) ? get_option($option_name) : ""; } return $return; } //Save Option //One to one saving function update_option_by_RestAPI($data) { //Judge whether it is an administrator if (current_user_can('manage_options')) { //Convert the passed data to array type $dataArray = json_decode($data->get_body(), true); //Cycle Save Options foreach ($dataArray as $option_name => $value) { update_option($option_name, $value); } //Return success message return new WP_REST_Response(array( 'success' => true, 'message '=>"Saved!" ), 200); } else { //Return failure information Return new WP_Error ('save_error ','save failed!', array('status' => 500)); } }
index.js
//vite/dist/index.js const App = { setup() { //Initial value const datas = Vue.reactive({ dataOne: "", dataTwo: "", }); //Get Data const vuespa_get_option = () => { axios .post(dataLocal.route + "pf/v1/get_option", datas, { headers: { "X-WP-Nonce": dataLocal.nonce, "Content-Type": "application/json", }, }) .then((response) => { const data = response.data; datas.dataOne = data.dataOne; datas.dataTwo = data.dataTwo; }) .catch((error) => { Window.alert ("Failed to connect to the server or background reading error! Data reading failed"); console.log(error); }); }; //Save Data const vuespa_update_option = () => { axios .post(dataLocal.route + "pf/v1/update_option", datas, { headers: { "X-WP-Nonce": dataLocal.nonce, }, }) .then((response) => { Alert ("saved successfully"); }) .catch((error) => { Alert ("Failed to save"); console.log(error); }); }; //Page initial loading Vue.onMounted(() => { Console.log ("Simple"); vuespa_get_option(); }); return { datas, vuespa_update_option }; }, template: 'Text box 1:<input type="text" v-model="data. dataOne"><br/>Text box 2:<input type="text" v-model="data. dataTwo"><hr/><button class="button button primary" @ click="vuespa_update_option">Save</button>', }; Vue.createApp(App).mount("#vuespa");
problem
-
Only one-to-one data can be obtained. In some complex scenarios, this data structure is unfriendly -
At present, Vue3 and Axios files are loaded manually. The loading is slow, which causes the pages to load well. The option content is slightly delayed, flickering, and the experience is not good -
For simple functions, the giant vue3 is loaded, and many functions of vue3 are useless. -
There is no such function as personnel filtering, article filtering and classification filtering, which can interact with WordPress,