在JSF Facelets中使用VueJS属性前缀报错的解决方法咨询
解决JSF Facelets中Vue指令的命名空间错误问题
我之前在JSF里整合Vue的时候也碰到过一模一样的问题,Facelets基于XML语法,所有带前缀的属性都必须绑定对应的命名空间,Vue的v-系列指令自然逃不过这个检查。你试过的passthrough命名空间没用,大概率是因为Facelets的passthrough机制对带冒号的属性支持不太友好,咱们换两种靠谱的方案来解决:
方案一:自定义Vue命名空间
最简单的方式就是给Vue的v-前缀声明一个自定义命名空间,不需要真实存在的URL,只要XML解析器认可就行。修改你的页面头部:
<html xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:v="urn:vue"> <!-- 新增Vue命名空间 -->
然后把Vue指令的前缀换成v:,比如:
<todo-item v:for="item in groceryList" v:bind:todo="item" v:key="item.id"></todo-item>
这样XML解析器会认为v:是合法的命名空间前缀,不会再报错,而Vue在渲染的时候依然能正确识别这些指令——因为它是直接操作DOM属性,不管XML的命名空间声明。
方案二:把Vue模板放到脚本标签里
如果不想折腾命名空间,更稳妥的方式是把Vue的模板内容放在<script type="text/x-template">中,这样Facelets的XML解析器会把它当作纯文本内容,不会解析里面的Vue指令:
<h:body> <!-- 挂载Vue的容器 --> <div id="app"></div> <!-- Vue模板 --> <script type="text/x-template" id="todo-template"> <todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id"></todo-item> </script> <!-- Vue实例代码 --> <h:outputScript> new Vue({ el: '#app', template: '#todo-template', data: { groceryList: [/* 你的数据 */] }, components: { 'todo-item': { /* 组件定义 */ } } }) </h:outputScript> </h:body>
这种方式彻底避开了Facelets的XML检查,因为模板内容在脚本标签里,不会被当作HTML元素解析。
为什么你之前的passthrough方案没用?
JSF的xmlns:p="http://xmlns.jcp.org/jsf/passthrough"命名空间是用来把属性直接传递给HTML元素的,但它只支持单一的属性名,比如p:class,对于v-bind:todo这种带冒号的复合属性名,Facelets的解析器无法正确识别,所以会失效。
内容的提问来源于stack exchange,提问作者Bjørn Stenfeldt
相关产品推荐
相关产品推荐

