第三節: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://m.kartiktrivedi.com
    Description: 將vue構建的頁面嵌入WordPress 中并產生交互
    Author: Muze
    Author URI: http://m.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");
    
    教程

    第二節:Vue3 開發WordPress設置選項- 從輸入框開始,配置基礎設置選項

    2023-6-27 22:29:00

    教程

    第四節:Vue3 開發WordPress設置選項 - 添加圖片上傳功能

    2023-6-28 22:02:00

    ??
    Npcink上的部份代碼及教程來源于互聯網,僅供網友學習交流,若您喜歡本文可附上原文鏈接隨意轉載。
    無意侵害您的權益,請發送郵件至 1355471563#qq.com 或點擊右側 私信:Muze 反饋,我們將盡快處理。
    0 條回復 A文章作者 M管理員
      暫無討論,說說你的看法吧
    ?
    個人中心
    購物車
    優惠劵
    今日簽到
    有新私信 私信列表
    搜索
    主站蜘蛛池模板: 精品国产福利在线观看一区| 亚洲国产专区一区| 麻豆视频一区二区三区| 人成精品视频三区二区一区 | 亚洲蜜芽在线精品一区| 日韩一区二区三区在线精品| 亚洲AV成人精品一区二区三区| 亚洲乱码一区二区三区在线观看| 日韩一区二区在线观看| 国产91精品一区| 国产精品亚洲一区二区麻豆| 亚洲一区中文字幕久久| 国产一区二区内射最近更新| 亚洲日本一区二区三区在线不卡| 在线一区二区三区| 亚洲AV无码一区二区三区性色| 无码囯产精品一区二区免费 | 中文字幕一区二区区免| 波多野结衣一区二区三区88| 日本人的色道www免费一区| 国产乱码精品一区二区三区香蕉| 精品视频一区二区三三区四区| 国产精品丝袜一区二区三区| 国产激情无码一区二区app| 精品成人av一区二区三区| 亚洲日本一区二区三区在线不卡| 日韩一区二区三区视频久久| 国产免费播放一区二区| 国产精品被窝福利一区 | 日本不卡在线一区二区三区视频 | 九九无码人妻一区二区三区| 中文字幕乱码亚洲精品一区| 一本大道在线无码一区| 亚洲日韩中文字幕一区| 在线观看中文字幕一区| 日韩十八禁一区二区久久| 国产精品女同一区二区久久| 国产品无码一区二区三区在线蜜桃 | 国产精品无码一区二区三区免费| 精品一区二区三区视频| 国产精品资源一区二区|