在使用PHP框架(本文以ThinkPHP為例)進行頁面開發的時候,經常遇到需要將控制器方法中的模板變數代入到頁面JS內操作的情況,常見的方式如:
let admin={:json_encode($admin)}, //$admin是php数组 level={$level}; console.log(admin, level);
登入後複製
這種方式確實是可以取到值的,只是存在幾個問題
- 模板變數的語法放在js中,編輯器會報語法錯誤
- 當採用編輯器的自動格式化功能時,模板變數的宣告結構會被破壞,從而影響了自動格式化程式碼功能的使用
- 不夠美觀
在實務上比較推薦的方式是:將範本變數存到特定的節點中,然後由全域方法將其轉成全域的變量,最後需要用到這些變數的方法再讀取這些全域變數。下面以一個完整的模板為例:
<!DOCTYPE html> <html lang ="en"> <head> <meta charset="UTF-8"> <title>PHP框架中JS优雅获取模板变量的方式</title> <style> /* 通用的模板数据存放标签,视觉不可见 */ .data-box { display: none; } </style> </head> <body> <!-- 页面内容 --> <h2>Hi,结果请看console</h2> <!-- 数据存储节点,可以同时存在多个data属性 --> <!-- 如果模板变量是数组,须先转成json字符串(如$admin) --> <div class="data-box" data-admin='{:json_encode($admin)}' data-level='{$level}'></div> <script> /* 获取数据的操作 */ /* 初始化页面渲染时传过来的js变量 */ let dataContainerElem = document.querySelector('.data-box'), data = dataContainerElem ? dataContainerElem.dataset : {}, dataBox = {}; //模板变量容器,`.data-box`类选择器所在的所有`data`属性值集合 Object.keys(data).forEach(function (key) { dataBox[key] = data[key]; if (isJsonString(data[key])) dataBox[key] = JSON.parse(data[key]); //是json格式的字串才转对象 }); /** * 判断字串是否属于json字串 */ function isJsonString(str) { let flag = false; if (typeof str != 'string') return flag; try { JSON.parse(str); flag = true; } catch (e) {} return flag; } </script> <script> /* 使用数据 */ //所有保存到数据节点的变量都成为`dataBox`对象的属性 console.log(dataBox.admin, dataBox.level); </script> </body> </html>
登入後複製
實際開發中,我會將這裡的css和獲取資料的js操作放置在全域的母模板中,然後具體的子模板只要繼承了母模板就可以使用該功能,方便程式碼的複用。
推薦:《最新的10個thinkphp影片教學》