通过Slim接收数组后如何将数据传递给Vue组件并对接Vuex?
实现步骤
1. 调整Slim模板的数据注入方式
你当前直接传值给子组件的方式只能让组件内部拿到数据,要接入Vuex的话,首先要把后端的@regions数据先注入到全局Vue实例可访问的位置,暂时不用直接传给子组件:
// 在你挂载Vue根实例的Slim模板中,先把后端数据挂载到window对象,注意要转成合法JSON javascript: window.serverData = { regions: #{raw @regions.to_json} } // 组件调用暂时可以去掉prop传值,后续直接从Vuex取数据 regions-list
2. 配置Vuex核心逻辑
在Vuex的store文件中定义对应的状态、修改方法、读取入口:
// store/index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { regions: [] // 定义存储地区数组的状态位 }, mutations: { // 定义同步修改state的唯一入口 SET_REGIONS(state, payload) { state.regions = payload } }, actions: { // 封装初始化数据的动作,方便后续扩展异步校验、预处理逻辑 initRegions({ commit }, regions) { commit('SET_REGIONS', regions) } }, getters: { // 封装状态读取方法,方便各组件调用 allRegions: state => state.regions } })
3. 根实例初始化时存入Vuex
在Vue入口文件中,拿到挂载在window上的后端数据,调用Vuex的action完成状态初始化:
// main.js Vue项目入口文件 import Vue from 'vue' import store from './store' import RegionsList from './components/RegionsList.vue' document.addEventListener('DOMContentLoaded', () => { // 页面加载完成后先把后端数据存入Vuex if (window.serverData?.regions) { store.dispatch('initRegions', window.serverData.regions) } new Vue({ store, // 把store注入全局Vue实例 components: { RegionsList } }).$mount('#app') })
4. 子组件从Vuex读取数据
regions-list组件不需要再通过prop接收数据,直接映射Vuex的getter即可使用:
<!-- RegionsList.vue 组件代码 --> <template> <ul> <li v-for="region in allRegions" :key="region.id"> {{ region.name }} </li> </ul> </template> <script> import { mapGetters } from 'vuex' export default { computed: { // 把Vuex的getter映射为组件的计算属性 ...mapGetters(['allRegions']) } } </script>
注意事项
- Slim模板里输出JSON必须加
raw,否则Rails会自动转义HTML特殊字符,导致JSON格式解析失败 - 后续如果需要修改regions数组,不要直接修改组件内的
allRegions,必须通过提交mutation的方式修改Vuex的state,保证单向数据流 - 如果你的Vue只挂载在单个页面而非全局SPA,只需要在对应页面的模板里注入
window.serverData即可,不会影响其他页面
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

