如何在CDN引入的Vue中访问Spring Boot控制器存入Model的属性
Thymeleaf + CDN引入Vue场景下读取Spring Boot Model值的实现方案
核心逻辑
Thymeleaf是跑在服务端的渲染引擎,会把Controller塞到Model里的值替换成实际的静态HTML内容,等页面返回到浏览器的时候,所有模板表达式已经被替换完成了。通过CDN引入的Vue是跑在浏览器端的脚本,根本接触不到服务端的Model对象,只能拿到渲染完成后落地在页面上的静态内容。
你之前在created钩子拿不到值,本质是两个认知偏差:
- 搞反了服务端渲染、前端脚本执行、Vue生命周期的先后顺序
- 搞错了Vue生命周期里DOM的可访问时机
具体实现步骤
步骤1:将Model值渲染为可被前端读取的静态内容
两种常用的无侵入渲染方式,选一种即可:
- 隐藏DOM节点存储(最稳妥,不受Thymeleaf解析规则限制)
直接在页面任意位置加不影响展示的隐藏节点,通过Thymeleaf的th:attr把Model值写到DOM的自定义属性上:<div id="server-model-data" th:attr="data-count=${count},data-word-search=${wordSearch}" style="display: none;" ></div> - JS内联变量渲染(更简洁,需要开启Thymeleaf的JS行内解析)
给script标签加th:inline="javascript"属性,让Thymeleaf能够解析JS块内的模板表达式:<script th:inline="javascript"> // 模板表达式会在服务端被替换为实际值,后面的0和{}是JS执行时的默认兜底值 const initialCount = /*[[${count}]]*/ 0; const initialWordSearch = /*[[${wordSearch}]]*/ {}; </script>
步骤2:在Vue初始化时将值绑定到data中
这里要避开你之前踩的坑:
created钩子触发时,Vue实例仅完成了自身的初始化,尚未完成DOM挂载,此时直接调用DOM API读页面元素会报“元素不存在”的错误- 不要把Vue初始化代码写在渲染值的DOM节点前面,否则DOM未加载完成时无法读到内容
针对隐藏DOM节点的实现,正确的初始化写法如下:
// 等待浏览器完成整个页面的DOM渲染后,再初始化Vue document.addEventListener('DOMContentLoaded', () => { // 读取之前渲染好的静态值 const modelEl = document.getElementById('server-model-data'); const count = Number(modelEl.dataset.count); // 注意做类型转换,DOM属性存的都是字符串 const wordSearch = JSON.parse(modelEl.dataset.wordSearch); // 对象类型要做反序列化 new Vue({ el: '#app', data: { // 直接把读到的服务端值赋给Vue的data变量 count: count, wordSearch: wordSearch }, created() { // 此时已经完成赋值,created钩子中可以直接正常使用这些变量 console.log('服务端传入的count值:', this.count) }, mounted() { // 如果不想提前读DOM,也可以在mounted钩子中读取,该阶段已经完成DOM挂载 // const count = Number(document.getElementById('server-model-data').dataset.count) // this.count = count } }) })
如果是用JS内联变量的实现,初始化逻辑更简单,直接在DOMContentLoaded回调里把预定义的initialCount、initialWordSearch赋值给Vue的data即可。
常见踩坑提醒
- 很多人直接在普通script标签里写Thymeleaf表达式,忘了给script加
th:inline="javascript"属性——Thymeleaf默认根本不解析JS块里的内容,表达式会原封不动留在页面上,前端拿到的就是一串模板字符,根本不是实际值 - 从DOM的自定义属性里取到的所有值都是字符串类型,别直接拿字符串做数字计算,对象类型也要手动
JSON.parse,不然很容易出现数据绑定异常 - 别在
created钩子里直接去document.querySelector找页面上的静态元素:这个阶段Vue刚把自己的实例初始化完,还没把根节点挂到页面DOM上,找啥都是null
内容的提问来源于stack exchange,提问作者anaweila
相关产品推荐
相关产品推荐

