Vue 3 SPA。 Select 发出 lang 并且 contentStore 不会仅在移动设备中更新内容

问题描述 投票:0回答:1

Vite 4.2 和 TypeScript 5.02 上的 Vue 3 SPA。

点击选择发出 lang.value 并且在父组件 App.vue contentStore 中应该更新内容。在我的 Linux Ubuntu 桌面上完美运行的典型事物。在 Firefox 和 Chrome devtools 中同样完美,当我模拟任何移动设备 - iOS 或 Android 时也是如此。 但是,当部署在 Hostinger 上时,它不会在任何 Android 或 iOS 设备上切换语言。你可以在这里看到https://rybnikov.online.

这是我的 App.vue:

<script setup lang="ts">
import { RouterView } from 'vue-router'
import { useWindowSize } from '@vueuse/core'
import { ref, defineAsyncComponent, onUpdated } from 'vue'
import { useContentStore } from './stores/content'
import socialMedia from './data/social.json'

const contentStore = useContentStore()
const lang = ref(localStorage.getItem('lang') || navigator.language.slice(0, 2))
const social = Object.assign(socialMedia)
const LayoutDesktop = defineAsyncComponent(() => import('@/layouts/LayoutDesktop.vue'))
const LayoutMobile = defineAsyncComponent(() => import('@/layouts/LayoutMobile.vue'))
const NavigationDesktop = defineAsyncComponent(() => import('@/components/NavigationDesktop.vue'))
const NavigationMobile = defineAsyncComponent(() => import('@/components/NavigationMobile.vue'))
const BodyMobile = defineAsyncComponent(() => import('@/components/BodyMobile.vue'))
const FooterMobile = defineAsyncComponent(() => import('@/components/FooterMobile.vue'))
const FooterDesktop = defineAsyncComponent(() => import('@/components/FooterDesktop.vue'))
const { width } = useWindowSize()
const setLang = (newLang: string) => {
  lang.value = newLang
  localStorage.setItem('lang', lang.value)
  contentStore.setContent(lang.value)
}
onUpdated(() => {
  contentStore.setContent(lang.value)
  contentStore.getContent
})
</script>

<template>
  <LayoutMobile v-if="width < 769">
    <template #header>
      <NavigationMobile @changeLang="setLang" />
    </template>
    <template #default>
      <BodyMobile :content="contentStore.getContent" />
    </template>
    <template #footer>
      <FooterMobile :lang="lang" :social="social" />
    </template>
  </LayoutMobile>
  <LayoutDesktop v-else>
    <template #header>
      <NavigationDesktop @changeLang="setLang" />
    </template>
    <template #asideLeft>
      <h1></h1>
    </template>
    <template #default>
      <RouterView :content="contentStore.getContent" />
    </template>
    <template #asideRight>
      <h1></h1>
    </template>
    <template #footer>
      <FooterDesktop :lang="lang" :social="social" />
    </template>
  </LayoutDesktop>
</template>

这是我的 NavigationLanguageSelect.vue

<script setup lang="ts">
import langSelection from '@/data/lang.json'

const emit = defineEmits<{ (e: 'changeLang', lang: string): void }>()
const langs = Object.assign(langSelection)
</script>
<template>
  <div>
    <select class="p-1 text-sm rounded-lg text-gray-700">
      <option
        class="block px-4 py-2 hover:bg-gray-100"
        v-for="language in langs"
        :key="language.text"
        @click="emit('changeLang', language.value)"
        @select="emit('changeLang', language.value)"
      >
        {{ language.flag }} {{ language.text }}
      </option>
    </select>
  </div>
</template>

这里是 package.json

{
  "name": "oleg",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "dev": "vite",
    "build": "run-p type-check build-only",
    "preview": "vite preview",
    "build-only": "vite build",
    "type-check": "vue-tsc --noEmit",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
    "format": "prettier --write src/"
  },
  "dependencies": {
    "@vueuse/core": "^9.13.0",
    "pinia": "^2.0.32",
    "vue": "^3.2.47",
    "vue-router": "^4.1.6"
  },
  "devDependencies": {
    "@rushstack/eslint-patch": "^1.2.0",
    "@types/node": "^18.14.2",
    "@vitejs/plugin-vue": "^4.0.0",
    "@vue/eslint-config-prettier": "^7.1.0",
    "@vue/eslint-config-typescript": "^11.0.2",
    "@vue/tsconfig": "^0.1.3",
    "autoprefixer": "^10.4.14",
    "eslint": "^8.34.0",
    "eslint-plugin-vue": "^9.9.0",
    "npm-run-all": "^4.1.5",
    "postcss": "^8.4.21",
    "prettier": "^2.8.4",
    "tailwindcss": "^3.3.0",
    "typescript": "^5.0.2",
    "vite": "^4.2.0",
    "vue-tsc": "^1.2.0"
  }
}

请告知上述代码在任何移动设备上失败的性质。

我试过使用 onMounted、onUpdated 钩子、pinia 的 storeToRefs,但看起来 select 元素本身有一些问题。

typescript vue.js vuejs3 html-select pinia
1个回答
0
投票

问题实际上在于我尝试将 < select > 与 Vue v-for 指令一起使用的方式。 V 模型以及很可能类似的运算符在 < option > 标签内不起作用,必须在 < select > 本身内使用。然而,奇怪的是,整个事情都在桌面上运行并且没有抛出任何错误,即使这种情况有据可查

尽管如此,这是最终代码。希望它能帮助有类似问题的人。

  1. 我不得不在我的 NavigationLanguageSelect.vue 中添加一个引用语言
import { ref } from 'vue'

const lang = ref(localStorage.getItem('lang') || navigator.language.slice(0, 2))
  1. 我使用 v-model 来引用
    lang
    和选定的选项,并在更改时发出 lang:
    <select
      @change="emit('changeLang', lang)"
      v-model="lang"
      class="p-1 text-sm rounded-lg text-gray-700"
    >
      <option class="block px-4 py-2 hover:bg-gray-100" disabled>
        {{ currentFlag }} {{ currentText }}
      </option>
      <option
        class="block px-4 py-2 hover:bg-gray-100"
        v-for="language in langs"
        :key="language.text"
        :value="language.value"
      >
        {{ language.flag }} {{ language.text }}
      </option>
    </select>
© www.soinside.com 2019 - 2024. All rights reserved.