如何将Vue的v-model与服务端返回的初始数据进行绑定?
Vue SSR 初始服务端渲染数据绑定方案
不用额外发起HTTP请求拉取初始数据,完全可以直接复用服务端渲染返回的已有数据,具体实现有两种常用方案:
方案1:全局变量挂载(最常用)
- 服务端渲染页面时,将前10条商品数据序列化为转义后的JSON字符串,插入到页面的
<script>标签中,挂载到window全局对象上,示例代码:
这里对<script> window.__INITIAL_PRODUCT_DATA__ = <%= JSON.stringify(products).replace(/</g, '\\u003c') %> </script><做转义是为了避免JSON里的</script>字符串截断当前标签,引发页面报错。 - Vue实例初始化时,直接读取全局变量作为data中商品列表的初始值,完全符合官方要求的「初始值在data中声明」的规则:
- 选项式API写法:
export default { data() { return { productList: window.__INITIAL_PRODUCT_DATA__ || [] } }, mounted() { // 用完可以删除全局变量避免污染 delete window.__INITIAL_PRODUCT_DATA__ } }- Vue3 组合式API写法:
import { ref, onMounted } from 'vue' const productList = ref(window.__INITIAL_PRODUCT_DATA__ || []) onMounted(() => { delete window.__INITIAL_PRODUCT_DATA__ })
方案2:DOM自定义属性存储(无全局变量污染)
如果不想在全局挂载变量,可以把序列化后的JSON存到DOM元素的自定义属性中:
- 服务端渲染商品列表容器时,添加
data-initial属性存数据:<div id="product-list" data-initial="<%= JSON.stringify(products).replace(/"/g, '"') %>"> <!-- 服务端渲染的10条商品HTML --> </div> - Vue初始化时读取属性解析为初始值:
const productEl = document.querySelector('#product-list') const productList = ref(JSON.parse(productEl.dataset.initial) || [])
两种方案都完全符合Vue官方的规则:你是直接把初始值声明在了data/响应式变量中,并没有依赖DOM的原生属性值,所以不存在和v-model规则冲突的问题,不需要额外发起请求拉取初始数据。
内容的提问来源于stack exchange,提问作者Adelin
相关产品推荐
相关产品推荐

