【问题标题】:Sharing a state store object to child components in Vue (without Vuex)将状态存储对象共享给 Vue 中的子组件(没有 Vuex)
【发布时间】:2021-02-15 07:01:22
【问题描述】:

我正在尝试遵循 this 教程,了解如何使用存储模式在 Vue 组件之间共享状态。

在教程中,他们初始化了两个独立的 Vue 实例:

var vmA = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})

var vmB = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})

但是我在components 文件中使用在单独的.vue 文件中定义的组件,所以我没有任何地方可以指定data。我不能把它放在export default 块中,因为那里已经有一个data() 条目,例如在我的组件LeafletMap.vue 中:

<template>
    <!-- ref="map" is required or Leaflet-Draw throws TypeError: "_this.$parent.$parent.$refs.map is undefined"  -->
    <!-- See: https://github.com/hubertokf/vue2-leaflet-draw/issues/1#issuecomment-520572130 -->
  <l-map
      ref="map"
      v-if="showMap"
      :zoom="zoom"
      :center="center"
      :options="mapOptions"
      @update:center="centerUpdate"
      @update:zoom="zoomUpdate"
    >
      <l-draw-toolbar position="topright"/>
      <l-tile-layer
        :url="url"
        :attribution="attribution"
      />
    </l-map>
</template>

<script>

import { latLng } from "leaflet";
import { LMap, LTileLayer } from "vue2-leaflet";
import LDrawToolbar from 'vue2-leaflet-draw-toolbar';

export default {
  name: "LeafletMap",
  components: {
    LMap,
    LTileLayer,
    LDrawToolbar
  },
  data() {
    return {
      zoom: 8,
      center: latLng(8.6195, 0.8248),
      url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
      currentCenter: latLng(47.41322, -1.219482),
      showParagraph: false,
      mapOptions: {
        zoomSnap: 0.5
      },
      showMap: true
    };
  },
  methods: {
    zoomUpdate(zoom) {
      this.currentZoom = zoom;
    },
    centerUpdate(center) {
      this.currentCenter = center;
    }
  }
};
</script>

在我的 App.vue 中:

<template>
  <div id="app">
    <div id="sidebar-container">
      <Sidebar />
    </div>
    <div id="map-container">
      <LeafletMap />
    </div>
  </div>
</template>

<script>
// import LENIInterface from './components/LENIInterface.vue'
import LeafletMap from './components/LeafletMap.vue'
import Sidebar from './components/Sidebar.vue'

export default {
  name: 'xyz',
  components: {
    LeafletMap,
    Sidebar,
  }
}
</script>

在 main.js 中:

import Vue from 'vue'
import App from './App.vue'
import vuetify from '@/plugins/vuetify' // path to vuetify export

// Leaflet tiles are scrambled unless you add this import
// See https://stackoverflow.com/questions/58723390/vue-leaflet-map-tiles-in-wrong-order
import "leaflet/dist/leaflet.css";
// import "./assets/css/main.css";

Vue.config.productionTip = false

var store = {
  debug: true,
  state: {
    message: 'Hello!'
  },
  setMessageAction (newValue) {
    if (this.debug) console.log('setMessageAction triggered with', newValue)
    this.state.message = newValue
  },
  clearMessageAction () {
    if (this.debug) console.log('clearMessageAction triggered')
    this.state.message = ''
  }
}

new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  },
  vuetify,
  render: h => h(App),
}).$mount('#app')

那么当子组件像这样组织时,我怎样才能将这个状态存储对象传递给子组件呢?

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    只需创建一个名为 store.js 的文件:

    export default {
      state: {
        message: 'Hello!'
      },
      methods: {
        setMessageAction (newValue) {
          if (this.debug) console.log('setMessageAction triggered with', newValue)
          this.state.message = newValue
        },
        clearMessageAction () {
          if (this.debug) console.log('clearMessageAction triggered')
          this.state.message = ''
        }
      }
    }
    

    并将其导入您的 LeafletMap.vue:

    <script>
    
    import { latLng } from "leaflet";
    import { LMap, LTileLayer } from "vue2-leaflet";
    import LDrawToolbar from 'vue2-leaflet-draw-toolbar';
    import store from './stores/store.js';
    
    export default {
      name: "LeafletMap",
      components: {
        LMap,
        LTileLayer,
        LDrawToolbar
      },
      data() {
        return {
          zoom: 8,
          center: latLng(8.6195, 0.8248),
          url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
          attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
          currentCenter: latLng(47.41322, -1.219482),
          showParagraph: false,
          mapOptions: {
            zoomSnap: 0.5
          },
          showMap: true
          ...store.state
        };
      },
      methods: {
        zoomUpdate(zoom) {
          this.currentZoom = zoom;
        },
        centerUpdate(center) {
          this.currentCenter = center;
        }
        ...store.methods
      }
    };
    </script>
    

    【讨论】:

      猜你喜欢
      • 2018-10-21
      • 1970-01-01
      • 1970-01-01
      • 2018-08-26
      • 2020-06-21
      • 1970-01-01
      • 2021-07-28
      • 2018-10-02
      • 2019-12-19
      相关资源
      最近更新 更多