久久精品国产99国产精品免费看_中文成人在线_日本在线播放视频_精品国产一区二区三区在线观看

第三節:Vue3 開發WordPress設置選項 - 從篩選功能研究前后臺數據交互

本節從WordPress 中拿到用戶列表數據,并通過Vue3渲染在頁面上,我們還修改了保存選項的接口,以便保存數組類型的數據

承接上文,我們制作了一個簡單的,帶有兩個輸入框和一個保存按鈕的設置選項,現在,他已經能實現了最基礎的填寫信息并保存到 WordPress 后臺,供PHP調用選項值的功能。

現在,我們更進一步,為其添加人員篩選功能,我們制作一個下列框,從中通過用戶名進行選擇,并將選擇好的用戶 ID 通過數組提供給后端使用。大概流程如下

第三節:Vue3 開發WordPress設置選項 - 從篩選功能研究前后臺數據交互

最終效果如下

第三節:Vue3 開發WordPress設置選項 - 從篩選功能研究前后臺數據交互

準備用戶數據

一般的網站用戶量較大,大部分都是“訂閱者”,為了減少傳輸數據壓力,我們在獲取用戶數據時將其排除掉
為了將拿到數據方便給 JS 使用,降低 JS 使用數據難度,我們將其整理成如下結構

第三節:Vue3 開發WordPress設置選項 - 從篩選功能研究前后臺數據交互

vue-spa.php 文件底部添加以下代碼

//整理并提供用戶信息
function vuespa_get_user_meat()
{
    //獲取所有角色
    $editable_roles = wp_roles()->roles;
    $roles = array_keys($editable_roles);
    //獲取除了'subscriber'(訂閱者)角色之外的所有角色的用戶數據
    $subscriber_key = array_search('subscriber', $roles, true);
    if (false !== $subscriber_key) {
        $roles = array_slice($roles, 0, $subscriber_key);
    }

    $users = get_users(array('role__in' => $roles));

    //轉為關聯數組
    $user_data = array_map(function ($user) {
        return [
            'id'   => $user->ID,
            'name' => $user->display_name,
        ];
    }, $users);

    return $user_data;
}

您可以參考此方法,做出分類篩選、文章篩選、標簽篩選等篩選功能,只需按結構提供數據即可。

傳遞用戶數據

我們通過 PHP 將數據傳給 JS ,以供使用,我們修改 vue-spa.php 文件中的 vuespa_data() 函數,改為以下內容

function vuespa_data()
{
    $person = [
        "str" => "Hello, world! - Npcink",
        "num" => 25,
        "city" => [1, 2, 3, 4, 5],
        "user" => vuespa_get_user_meat(),
    ];
    return $person;
}

刷新菜單頁面,我們就能看到如上圖的效果。

JS 準備頁面

JS 中拿到傳來的數據,需要將其渲染至頁面上,修改index.js為以下內容

//vite/dist/index.js
console.log(dataLocal.data.user);
const App = {
  setup() {


    //存儲傳來的值
    const siteData = dataLocal.data;

    //存儲選項值
    const datas = Vue.reactive({
      dataOne: "",
      dataTwo: "",
      dataName: [],
    });

//獲取數據
    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;
          datas.dataName = data.dataName;
        })
        .catch((error) => {
          window.alert("連接服務器失敗或后臺讀取出錯!數據讀取失敗");
          console.log(error);
        });
    };
    //省略部分代碼



    return { datas, siteData, vuespa_update_option };
  },
  template: `
  文本框1:<input type="text" v-model="datas.dataOne"><br/>
  文本框2:<input type="text" v-model="datas.dataTwo"><hr/>

  用戶選擇:<select v-model="datas.dataName" multiple>
  <option v-for="option in siteData.user" :key="option.id" :value="option.id">
      {{ option.name }}
  </option>
</select>
<p>你選擇了:{{ datas.dataName }}</p><br/>
按住command(control)按鍵即可進行多選<hr/>
    <button class="button button-primary" @click="vuespa_update_option">保存</button>`,
};

Vue.createApp(App).mount("#vuespa");

為了方便大家看出不同,我省略了部分未修改的代碼,其詳細內容,可見上一節。
主要內容如下

  • 新建變量 siteData 存儲傳來的數據
  • 新建數組變量 dataName 存儲選中數組
  • 在獲取數據中,通過 datas.dataName = data.dataName;拿到默認值

修改保存接口

原有的保存接口無法識別數組,若您此時修改選中的值并點擊保存按鈕,刷新頁面后會丟失選中的值。

修改 interface.php 文章的保存選項功能函數 update_option_by_RestAPI() 為以下內容

//保存Option
function update_option_by_RestAPI($data)
{
    //判斷是否是管理員
    if (current_user_can('manage_options')) {
        //轉為JSON對象 - 重點,這里沒有true,是轉為對象
        $dataArray = json_decode($data->get_body());
        //存儲結果
        $result = new stdClass();

        //循環保存選項
        foreach ($dataArray as $option_name => $value) {

            //判斷,是否為對象
            if (is_object($value)) {
                //是非空數組,循環保存值
                foreach ($value as $arr => $data) {
                    //更新值    
                    update_option($arr, $data);
                }
            } else {
                //不是對象,則表示只有一個選項需要保存。
                update_option($option_name, $value);
            }
            $result->$option_name = $value;
        }

        //返回成功信息
        return new WP_REST_Response(array(
            'success' => true,
            'message' => "已保存!"
        ), 200);
    } else {
        //返回失敗信息
        return new WP_Error('save_error', '保存失敗!', array('status' => 500));
    }
}

此函數的功能可見注釋,現在,刷新頁面,在下列列表中進行篩選,然后點擊保存按鈕,刷新頁面,可看到值是正常保存的,

使用

此時,您可以使用 get_option 在PHP中拿到選項中的值,正如上一節中提到的。

echo get_option('dataName');

注意,這會展示數組ID

總結

這一節我們添加了下拉列表多選功能,并沒有解決上一節提到的問題,不要急,我發現目前展示功能類型很方便,我準備在展示完所有常見功能類型后,再去解決上一節提到的問題。

文件代碼

vue-spa.php

<?php
/*
Plugin Name: Vue - SPA 
Plugin URI: http://www.kartiktrivedi.com
Description: 將vue構建的頁面嵌入WordPress 中并產生交互
Author: Muze
Author URI: http://www.kartiktrivedi.com
Version: 1.0.0
*/


//接口
require_once plugin_dir_path(__FILE__) . 'interface.php';
//創建一個菜單
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后被替換{{data}}</div>
    </div>



<?php

    //展示準備的數據
    echo "<pre>";
    print_r(vuespa_data());
    echo "</pre>";

    echo "<h3>調用選項值</h3>";
    echo get_option('dataOne');
    echo "<br/>";
    echo get_option('dataTwo');
} // vuespa_menu_page_display



//載入所需 JS 和 CSS 資源 并傳遞數據
function vuespa_load_vues($hook)
{
    //判斷當前頁面是否是指定頁面,是則繼續加載
    if ('toplevel_page_vuespa_id' != $hook) {
        return;
    }
    //版本號
    $ver = '53';
    //加載到頁面頂部
    wp_enqueue_style('vite', plugin_dir_url(__FILE__) . 'vite/dist/index.css', array(), $ver, false);
    //加載到頁面底部
    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()),     //路由
        '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],
        "user" => vuespa_get_user_meat(),
    ];
    return $person;
}


//整理并提供用戶信息
function vuespa_get_user_meat()
{
    //獲取所有角色
    $editable_roles = wp_roles()->roles;
    $roles = array_keys($editable_roles);
    //獲取除了'subscriber'(訂閱者)角色之外的所有角色的用戶數據
    $subscriber_key = array_search('subscriber', $roles, true);
    if (false !== $subscriber_key) {
        $roles = array_slice($roles, 0, $subscriber_key);
    }

    $users = get_users(array('role__in' => $roles));

    //轉為關聯數組
    $user_data = array_map(function ($user) {
        return [
            'id'   => $user->ID,
            'name' => $user->display_name,
        ];
    }, $users);

    return $user_data;
}

interface.php

<?php
//interface.php
//接口文件
function vuespa_create_api()
{
    register_rest_route('pf/v1', '/get_option/', array( // 完整命名空間為:/wp-json/pf/v1/
        'methods' => 'POST',
        'callback' => 'get_option_by_RestAPI',
    ));
    register_rest_route('pf/v1', '/update_option/', array( // 完整命名空間為:/wp-json/pf/v1/
        'methods' => 'POST',
        'callback' => 'update_option_by_RestAPI',
        'permission_callback' => function () {
            return current_user_can('manage_options'); // 只有管理員才有權限修改
        },
    ));
}
add_action('rest_api_init', 'vuespa_create_api');


//讀取Option
//僅支持一對一的數據請求
function get_option_by_RestAPI($data)
{
    //將傳遞數據轉成數組類型
    $dataArray = json_decode($data->get_body(), true);
    //新建數組
    $return = array();
    //循環獲取對應選項ID的值,并將其存儲在對應關聯數組中,若拿不到值,則為空
    foreach ($dataArray as $option_name => $value) {
        $return[$option_name] = get_option($option_name) ? get_option($option_name) : "";
    }
    return $return;
}


//保存Option
function update_option_by_RestAPI($data)
{

    //判斷是否是管理員
    if (current_user_can('manage_options')) {
        //轉為JSON對象 - 重點,這里沒有true,是轉為對象
        $dataArray = json_decode($data->get_body());
        //存儲結果
        $result = new stdClass();

        //循環保存選項
        foreach ($dataArray as $option_name => $value) {

            //判斷,是否為對象
            if (is_object($value)) {
                //是非空數組,循環保存值
                foreach ($value as $arr => $data) {
                    //更新值    
                    update_option($arr, $data);
                }
            } else {
                //不是對象,則表示只有一個選項需要保存。
                update_option($option_name, $value);
            }
            $result->$option_name = $value;
        }

        //返回成功信息
        return new WP_REST_Response(array(
            'success' => true,
            'message' => "已保存!"
        ), 200);
    } else {
        //返回失敗信息
        return new WP_Error('save_error', '保存失敗!', array('status' => 500));
    }
}

index.js

//vite/dist/index.js
console.log(dataLocal.data.user);
const App = {
  setup() {
    

    //存儲傳來的值
    const siteData = dataLocal.data;

    //存儲選項值
    const datas = Vue.reactive({
      dataOne: "",
      dataTwo: "",
      dataName: [],
    });

    //獲取數據
    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;
          datas.dataName = data.dataName;
        })
        .catch((error) => {
          window.alert("連接服務器失敗或后臺讀取出錯!數據讀取失敗");
          console.log(error);
        });
    };

    //保存數據
    const vuespa_update_option = () => {
      axios
        .post(dataLocal.route + "pf/v1/update_option", datas, {
          headers: {
            "X-WP-Nonce": dataLocal.nonce,
          },
        })
        .then((response) => {
          alert("保存成功");
        })
        .catch((error) => {
          alert("保存失敗");
          console.log(error);
        });
    };

    //頁面初始加載
    Vue.onMounted(() => {
      console.log("簡簡單單");
      vuespa_get_option();
    });

    return { datas, siteData, vuespa_update_option };
  },
  template: `
  文本框1:<input type="text" v-model="datas.dataOne"><br/>
  文本框2:<input type="text" v-model="datas.dataTwo"><hr/>
  
  用戶選擇:<select v-model="datas.dataName" multiple>
  <option v-for="option in siteData.user" :key="option.id" :value="option.id">
      {{ option.name }}
  </option>
</select>
<p>你選擇了:{{ datas.dataName }}</p><br/>
按住command(control)按鍵即可進行多選<hr/>
    <button class="button button-primary" @click="vuespa_update_option">保存</button>`,
};

Vue.createApp(App).mount("#vuespa");

給TA贊賞
共{{data.count}}人
人已贊賞
??
Npcink上的部份代碼及教程來源于互聯網,僅供網友學習交流,若您喜歡本文可附上原文鏈接隨意轉載。
無意侵害您的權益,請發送郵件至 1355471563#qq.com 或點擊右側 私信:Muze 反饋,我們將盡快處理。
?
購物車
優惠劵
搜索
久久精品国产99国产精品免费看_中文成人在线_日本在线播放视频_精品国产一区二区三区在线观看

    9000px;">

      成人国产视频在线观看| 亚洲天堂成人网| 丰满亚洲少妇av| 麻豆91在线观看| 午夜欧美2019年伦理| 一区二区三区 在线观看视频| 久久精品一区四区| 久久久蜜臀国产一区二区| 精品久久久久久无| 蜜桃av一区二区三区电影| 亚洲欧洲韩国日本视频| 免费视频最近日韩| 亚洲综合区在线| 亚洲高清不卡在线| 久久机这里只有精品| 免费高清成人在线| 国产乱国产乱300精品| 欧美精品免费视频| 久久久久久黄色| 岛国精品在线播放| 成人免费毛片高清视频| 成人黄色777网| 丰满放荡岳乱妇91ww| 日本乱码高清不卡字幕| 久草中文综合在线| ●精品国产综合乱码久久久久| 国产午夜精品一区二区| 欧美韩日一区二区三区| 综合亚洲深深色噜噜狠狠网站| 亚洲精品中文字幕在线观看| 视频一区视频二区中文| 极品销魂美女一区二区三区| 成人午夜精品在线| 欧美午夜精品电影| 日韩欧美国产一区二区在线播放| 久久综合九色综合欧美就去吻| 国产精品乱码妇女bbbb| 一个色妞综合视频在线观看| 日韩福利电影在线| 成人免费毛片aaaaa**| 欧美午夜精品电影| 国产视频一区二区三区在线观看| 日韩午夜激情视频| 欧美日韩www| 91丨九色丨黑人外教| 欧美日韩一区二区三区四区五区| 欧美成人一区二区三区在线观看| 中文字幕第一区| 午夜av一区二区三区| 国产成人自拍网| 欧美日韩国产另类不卡| 中文字幕欧美区| 婷婷激情综合网| eeuss鲁片一区二区三区| 欧美一区二区三区喷汁尤物| 1000精品久久久久久久久| 亚洲五码中文字幕| 国产在线精品国自产拍免费| 91精品91久久久中77777| 久久久久久亚洲综合| 亚洲一二三区不卡| 成人免费不卡视频| 久久福利资源站| 成人黄色片在线观看| 亚洲国产精品一区二区久久恐怖片| 日本视频中文字幕一区二区三区| www.欧美日韩| 精品国产免费人成在线观看| 亚洲一区二区高清| 本田岬高潮一区二区三区| 精品国产一区二区精华| 午夜精品福利一区二区蜜股av| 成人黄页在线观看| 亚洲精品一区二区三区蜜桃下载| 亚洲福利一区二区| 日本高清免费不卡视频| 日韩美女啊v在线免费观看| 粉嫩一区二区三区在线看| 日韩女优电影在线观看| 日韩av一级片| 欧美精品一二三区| 亚洲成人av一区| 欧美视频精品在线| 亚洲高清视频在线| 欧美三级中文字| 天天综合天天做天天综合| 56国语精品自产拍在线观看| 日韩在线一区二区三区| 欧美一区二区三区性视频| 麻豆高清免费国产一区| 日韩精品一区二| 国产a级毛片一区| 国产精品成人一区二区三区夜夜夜| 成人精品视频一区| 亚洲日本在线观看| 欧美午夜精品一区| 五月天亚洲婷婷| 日韩一级完整毛片| 国产乱码精品一品二品| 国产精品天美传媒| 91免费版pro下载短视频| 亚洲欧美日韩国产成人精品影院| 一本一本久久a久久精品综合麻豆| 一区二区三区在线免费| 欧美日韩国产电影| 久88久久88久久久| 最新国产精品久久精品| 欧美亚洲国产bt| 久久国产精品区| 国产精品久久久久久久第一福利 | 国产一区二区在线视频| 久久久综合九色合综国产精品| 成人激情免费网站| 日日夜夜精品视频天天综合网| 正在播放一区二区| 国产成人精品一区二区三区四区 | 中文av一区二区| 91尤物视频在线观看| 天天免费综合色| 国产精品沙发午睡系列990531| 欧美中文字幕一区| 国产在线麻豆精品观看| 亚洲一级二级三级在线免费观看| 日韩欧美成人午夜| 粉嫩aⅴ一区二区三区四区五区| 亚洲美女免费在线| 久久欧美中文字幕| 欧美午夜理伦三级在线观看| 国产成人午夜精品影院观看视频| 天天综合网天天综合色| 1000精品久久久久久久久| 精品欧美一区二区在线观看| 91网站视频在线观看| 激情av综合网| 日韩精品一级二级| 一区二区三区资源| 国产三级精品在线| 欧美精三区欧美精三区| 91女厕偷拍女厕偷拍高清| 精久久久久久久久久久| 亚洲成av人片观看| 一区二区三区在线视频免费观看| 欧美激情一区二区三区| 精品国产一区二区三区四区四| 欧美色视频在线观看| bt欧美亚洲午夜电影天堂| 丁香婷婷综合色啪| 国产激情视频一区二区三区欧美 | 一本大道久久a久久精品综合| 国产在线视视频有精品| 日韩激情一二三区| 天堂一区二区在线免费观看| 亚洲综合一区二区| 中文字幕亚洲在| 中文字幕欧美一区| 国产精品网站在线观看| 国产亚洲成av人在线观看导航| 日韩精品中文字幕一区二区三区 | 精品成人私密视频| 欧美一区二区三区免费在线看| 在线中文字幕一区二区| 91蝌蚪porny| 91浏览器在线视频| 色婷婷综合久久久| 91久久精品一区二区二区| 99久久精品免费看国产| av不卡免费在线观看| 91亚洲午夜精品久久久久久| 国产91露脸合集magnet| 成人av在线一区二区三区| 成人免费毛片高清视频| 91蜜桃视频在线| 欧美视频三区在线播放| 欧美日韩一级视频| 欧美一区在线视频| 精品福利视频一区二区三区| 26uuu欧美| 国产精品久久福利| 国产精品不卡一区二区三区| 亚洲美女在线一区| 天堂成人免费av电影一区| 麻豆精品一区二区av白丝在线| 狠狠色丁香久久婷婷综| 国产不卡在线播放| 在线看国产一区| 日韩免费高清视频| 国产视频一区在线播放| 一区二区三区四区中文字幕| 日韩电影免费一区| 高清在线观看日韩| 欧美私人免费视频| 日韩一级黄色大片| 国产精品久久久久久久久图文区 | 国产成人在线看| 99热国产精品| 91精品国产一区二区三区香蕉| 精品国产第一区二区三区观看体验| 国产亚洲欧美一级| 亚洲1区2区3区4区| 成人国产精品免费网站|