有没有办法获取一次 json 文件并像全局变量一样在 vue3 中的任何地方使用它?

is there a way to get a json file once and use it anywhere in vue3 like global variables?

我一直在寻找一种在组件中获取 json 文件并在同一组件和其他组件上使用它的方法,就像您对全局变量的处理方式一样。

我看过 (它会在我在模板中使用它之后设置变量,所以它会在控制台中显示一个未分配的变量错误) 但它不起作用 我也看过 vue3 文档,但没有找到任何有用的东西。

所以我没找到,只能在每个组件中发送请求。

showHome.vue:

<script>
import axios from 'axios';
export default {
  created(){
    axios.get("http://api.mjbn.ir/post")
  .then((response) => {
    this.getposts = response.data;
    });
  },
  data: function () {
    return {
      postsearch: "",
      post: true,
      product: true,
      getposts: this.getposts,
    };
  },
  methods: {
    showReq(input0, input1) {
      this.post = input0;
      this.product = input1;
    },
    btnActive(input0) {
      if ((input0 == "post") & (this.post == true) & (this.product == false)) {
        return true;
      } else if ((input0 == "product") & (this.product == true) & (this.post == false)) {
        return true;
      } else if ((input0 == "all") & (this.post == true) & (this.product == true)){
        return true;
      } else {
        return false;
      }
    },
    showRes(input0) {
      if ((input0 == "post") & (this.post == true)) {
        return true;
      } else if ((input0 == "product") & (this.product == true)) {
        return true;
      } else if ((input0 == "all") & (this.post == true) & (this.product == true)){
        return true;
      } else {
        return false;
      }
    },
    postCount(){
      const posts = this.getposts
      let count = 0;
      if (this.post == true & this.product == true){
        return this.getposts.length;
      } else if (this.post == true & this.product == false){
        for (let index = 0; index < posts.length; index++) {
          const element = posts[index];
          if (element.type == 'post') {
            count++;            
          }
        }
        return count;
      } else if (this.post == false & this.product == true){
        for (let index = 0; index < posts.length; index++) {
          const element = posts[index];
          if (element.type == 'product') {
            count++;            
          }        
        }
        return count;
      }
      return "...";
    },
  },
};
</script>
<template>
        <div class="col-12 mt-5">
          <div class="row">
            <div v-for="getpost in getposts" v-show="showRes(getpost.type)" :key="getpost.id" class="col-4">
              <router-link :to="{ name: 'post', params: { id: getpost.id } }">
                <div class="col-6 mx-auto align-self-center">
                  <img
                    :src="getpost.img"
                    :alt="getpost.title"
                    class="img-fluid img-thumbnail"
                  />
                  <h5 class="text-center my-3">{{ getpost.title }}</h5>
                </div>
              </router-link>
            </div>
          </div>
        </div>
</template>

showPosts.vue:

<template>
  <!-- Post -->
  <div v-for="getpost in getposts" v-show="getpost.type == link" :key="getpost.id" class="col-8 my-3 mx-auto blog-post">
    <router-link
      :to="{ name: link, params: { id: getpost.id } }"
      style="color: #f8f8f2"
    >
      <div class="col-2 float-start">
        <img
          :src="getpost.img"
          :alt="getpost.title"
          class="img-fluid img-thumbnail"
        />
      </div>

      <div class="col-10 float-end">
        <div class="col-10 ms-4 me-4">
          <h2>{{ getpost.title }}</h2>

          <figure class="figure figure-caption">{{ getpost.date }}</figure>
        </div>

        <div class="col-10 ms-4 me-4">
          <p>{{ getpost.summerry }}</p>
        </div>
      </div>
    </router-link>
  </div>
</template>
<script>
import axios from 'axios';
export default {
  created() {
    axios.get('http://api.mjbn.ir/post')
    .then(response => { this.getposts =  response.data})
  },
  data: function () {
    return {
      getposts: this.getposts,
      link: "post",
    };
  },
};
</script>

main.js:

import "./assets/css/bootstrap.rtl.min.css";
import "./assets/css/main.css";
import { createApp } from "vue";
import { createWebHashHistory, createRouter } from "vue-router";
import showAbout from "./components/showAbout.vue";
import showBlog from "./components/showBlog.vue";
import showHome from "./components/showHome.vue";
import showLoading from "./components/showLoading.vue";
import showPage from "./components/showPage.vue";
import showHeader from "./components/showHeader.vue";
import showPost from "./components/showPost.vue";
import showPosts from "./components/showPosts.vue";
import showContact from "./components/showContact.vue";

// Routes
const routes = [
  {
    path: "/",
    component: showHeader,
    children: [
      { path: "", component: showHome,},
      { path: "/contact", component: showContact },
      { path: "/about", component: showAbout },
    ],
  },
  {
    path: "/blog",
    component: showBlog,
    children: [
      { path: "", component: showPosts },
      { path: "/blog/:id", name: "post", component: showPost },
    ],
  },
  { path: "/loading", component: showLoading },
];

// Router
const router = createRouter({
  history: createWebHashHistory(),
  routes: routes,
});

// App
const app = createApp(showPage);
app.use(router);
app.mount("#app");

感谢 connexo and estus flask in the comments. i've come to know that there is something called vuex,它将为您完成这项工作。 这是语法。

main.js:

import { createApp } from "vue";
import { createStore } from "vuex";
import showPage from "./components/showPage.vue";

// Store
const store = createStore({
  state() {
    return {
      getjson: null,
    };
  },
  mutations: {
    getfile(state) {
      axios
        .get("https://jsonplaceholder.typicode.com/todos/1")
        .then((response) => {
          if (state.getjson == null) {
            state.getjson = response.data;
          }
        });
    },
  },
});

// App
const app = createApp(showPage);
app.use(store);
app.mount("#app");

在组件中:

<template>
<!-- run setposts before using getjson -->
  {{this.setposts()}}
  {{this.$store.state.getjson}}
</template>
<script>
export default {
  methods:{
    setposts(){
      this.$store.commit("getfile");
    }
  }
};
</script>