【问题标题】:How to fix defineExpose method not defined in Vue3如何修复 Vue3 中未定义的 defineExpose 方法
【发布时间】:2022-12-09 09:39:58
【问题描述】:

我正在尝试将方法从孩子传递给父母。但是不知何故defineExpose() 方法不起作用。你能指导我做错什么吗?

如果你需要更多细节,那么你可以参考我的previous question

<script setup lang="ts">
import { useHead } from '@vueuse/head'

import { pageTitle } from '/@src/state/sidebarLayoutState'

pageTitle.value = 'Saved Topical'
useHead({
  title: 'Saved Topical',
})

defineExpose({
  
})
</script>
{
  "name": "vuero",
  "version": "1.2.1",
  "private": "true",
  "license": "MIT",
  "scripts": {
    "dev": "vite",
    "dev:force": "vite --force",
    "preview": "vite preview",
    "build": "vite build",
    "lint": "run-s lint:doc:fix lint:eslint:fix lint:stylelint:fix lint:prettier:fix",
    "lint:prettier": "prettier --check \"./src/**/*.(ts|vue|css|scss)\"",
    "lint:prettier:fix": "prettier --write \"./src/**/*.(ts|vue|css|scss)\"",
    "lint:eslint": "eslint --ext .ts,.vue ./src",
    "lint:eslint:fix": "eslint --fix --ext .ts,.vue ./src",
    "lint:stylelint": "stylelint ./src/**/*.{vue,css,scss}",
    "lint:stylelint:fix": "stylelint ./src/**/*.{vue,css,scss} --fix",
    "lint:doc:fix": "run-s lint:doc:fix:*",
    "lint:doc:fix:eslint": "eslint --fix --ext .md ./documentation",
    "lint:doc:fix:prettier": "prettier --write \"./documentation/**/*.(md)\"",
    "test": "run-p test:lint",
    "test:tsc": "vue-tsc --noEmit",
    "test:lint": "run-p lint:eslint lint:stylelint lint:prettier",
    "e2e": "cypress run"
  },
  "dependencies": {
    "@ckeditor/ckeditor5-build-classic": "28.0.0",
    "@ckeditor/ckeditor5-vue": "2.0.1",
    "@iconify/iconify": "2.0.2",
    "@mapbox/mapbox-gl-geocoder": "4.7.1",
    "@popperjs/core": "2.9.2",
    "@vueform/multiselect": "1.5.0",
    "@vueform/slider": "1.0.5",
    "@vuelidate/core": "^2.0.0-alpha.41",
    "@vuelidate/validators": "^2.0.0-alpha.29",
    "@vueuse/core": "5.0.3",
    "@vueuse/head": "0.6.0",
    "apexcharts": "3.27.1",
    "axios": "^0.22.0",
    "billboard.js": "3.0.3",
    "bulma": "0.9.3",
    "dayjs": "1.10.5",
    "dragula": "3.7.3",
    "dropzone": "5.9.2",
    "filepond": "4.28.2",
    "filepond-plugin-file-validate-size": "2.2.4",
    "filepond-plugin-file-validate-type": "1.2.6",
    "filepond-plugin-image-crop": "2.0.6",
    "filepond-plugin-image-edit": "1.6.3",
    "filepond-plugin-image-exif-orientation": "1.0.11",
    "filepond-plugin-image-preview": "4.6.6",
    "filepond-plugin-image-resize": "2.0.10",
    "filepond-plugin-image-transform": "3.7.6",
    "firebase": "^9.6.2",
    "imask": "6.0.7",
    "mapbox-gl": "2.3.0",
    "markdown-it-emoji": "2.0.0",
    "notyf": "3.10.0",
    "nprogress": "0.2.0",
    "photoswipe": "4.1.3",
    "simple-datatables": "3.0.2",
    "simplebar": "6.0.0-beta.10",
    "simplebar-vue": "2.0.0-beta.10",
    "sweet-modal-vue": "^2.0.0",
    "tiny-slider": "2.9.3",
    "tippy.js": "6.3.1",
    "trim-newlines": "^4.0.2",
    "tslib": "2.3.0",
    "v-calendar": "3.0.0-alpha.4",
    "vue": "3.0.11",
    "vue-i18n": "9.1.4",
    "vue-js-modal": "^2.0.1",
    "vue-router": "4.0.6",
    "vue-scrollto": "2.20.0",
    "vue-tippy": "6.0.0-alpha.29",
    "vue3-apexcharts": "1.4.0",
    "xmodal-vue": "^1.0.5"
  },
  "devDependencies": {
    "@iconify/json": "1.1.358",
    "@intlify/vite-plugin-vue-i18n": "2.2.1",
    "@types/dragula": "3.7.0",
    "@types/mapbox__mapbox-gl-geocoder": "^4.7.0",
    "@types/mapbox-gl": "^2.3.0",
    "@types/markdown-it": "12.0.2",
    "@types/node": "15.12.4",
    "@types/nprogress": "0.2.0",
    "@types/prismjs": "1.16.5",
    "@types/simplebar": "5.3.3",
    "@typescript-eslint/eslint-plugin": "4.27.0",
    "@typescript-eslint/parser": "4.27.0",
    "@vitejs/plugin-vue": "1.2.3",
    "@vue/compiler-sfc": "3.1.1",
    "cross-env": "7.0.3",
    "cypress": "7.5.0",
    "eslint": "7.29.0",
    "eslint-config-prettier": "8.3.0",
    "eslint-plugin-md": "1.0.19",
    "eslint-plugin-prettier-vue": "3.1.0",
    "eslint-plugin-vue": "7.11.1",
    "gray-matter": "4.0.3",
    "lint-staged": "11.0.0",
    "markdown-it": "12.0.6",
    "markdown-it-anchor": "8.0.3",
    "npm-run-all": "4.1.5",
    "plyr": "3.6.8",
    "prettier": "2.3.1",
    "prismjs": "^1.25.0",
    "rimraf": "3.0.2",
    "rollup": "2.52.1",
    "sass": "1.32.13",
    "stylelint": "^14.2.0",
    "stylelint-config-prettier": "8.0.2",
    "stylelint-config-standard": "^24.0.0",
    "stylelint-scss": "^4.1.0",
    "typescript": "4.3.4",
    "vite": "2.3.8",
    "vite-imagetools": "3.6.8",
    "vite-plugin-components": "0.11.2",
    "vite-plugin-fonts": "0.2.2",
    "vite-plugin-imagemin": "^0.1.0",
    "vite-plugin-pages": "0.13.2",
    "vite-plugin-purge-icons": "0.7.0",
    "vite-plugin-pwa": "0.8.1",
    "vite-plugin-radar": "0.2.0",
    "vue-tsc": "^0.3.0",
    "yorkie": "2.0.0"
  },
  "gitHooks": {
    "pre-commit": "lint-staged"
  },
  "lint-staged": {
    "*.ts": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.scss": [
      "stylelint",
      "prettier --write"
    ],
    "*.md": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.vue": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

任何解决方案表示赞赏!

【问题讨论】:

  • 看起来你的编辑器不知道 Vue3
  • @robertklep 当我在浏览器中编译时出现同样的问题。现在,您对浏览器有何看法?
  • 所有其他方法都工作正常,只有这个方法显示错误。
  • defineExpose() 在 Vue3 组件中对我来说很好(但仅在 &lt;script setup&gt; 中有效),所以也许您需要显示更多上下文。另外,请发布实际代码而不是图像。
  • 看来您正在使用 veture 扩展。 Volar 是官方的 vue3 vscode 扩展,它也支持打字稿。 marketplace.visualstudio.com/items?itemName=Vue.volar。您还可以包含父组件代码吗?

标签: javascript typescript vuejs3 vite


【解决方案1】:

与 Vue 3 有同样的问题。更新我的TypeScript版本4.5.5 到版本4.9.3 神奇地修复了它。显然,较旧的 TypeScript 版本不理解 defineExpose 之类的编译器宏。

而且为了消除 ESLint 错误,我必须在它前面加上前缀(如提到的 @stefan):

// eslint-disable-next-line no-undef
defineExpose({  });

【讨论】:

【解决方案2】:

如果您在 VS Code 中使用 Veture,请为您的项目工作区禁用它并改用 Volar

【讨论】:

    【解决方案3】:

    更新

    vue 版本必须是 3.1.3 或更高版本,因为那是引入 defineExpose 的时候。

    https://github.com/vuejs/core/blob/main/CHANGELOG.md#313-2021-07-01


    我不确定您的代码有什么问题,因为您正在添加 defineExpose。 试试这个代码(我改变了几个变量,因为我的本地设置中没有它们):

    父母观

    <script setup lang="ts">
    import { ref } from 'vue';
    import { Notyf } from 'notyf';
    import Child from './Child.vue';
    
    const addNewPaper = ref();
    const notyf = new Notyf();
    
    const successSave = () => {
      addNewPaper.value.savePaper();
      notyf.success('Your paper has been successfully created!');
    };
    </script>
    <template #content>
      <input type="button" @click="successSave" value="Save" />
      <Child ref="addNewPaper"></Child>
    </template>
    

    儿童.vue

    <script setup lang="ts">
    import { Notyf } from 'notyf';
    import { computed, defineProps, reactive, ref } from 'vue';
    
    const companySize = ref('');
    const businessType = ref('');
    const productToDemo = ref('');
    const date = ref(new Date());
    
    const initialState = reactive({
      subject: '',
      paper: '',
      marks: '',
    });
    
    const notyf = new Notyf();
    
    const props = defineProps({
      subjects: { required: true },
    });
    
    const savePaper = () => {
      notyf.success('Paper saved successfully');
    };
    
    defineExpose({
      savePaper,
    });
    </script>
    
    {
      "name": "vuero",
      "version": "1.2.1",
      "private": "true",
      "license": "MIT",
      "scripts": {
        "dev": "vite",
        "dev:force": "vite --force",
        "preview": "vite preview",
        "build": "vite build",
        "lint": "run-s lint:doc:fix lint:eslint:fix lint:stylelint:fix lint:prettier:fix",
        "lint:prettier": "prettier --check "./src/**/*.(ts|vue|css|scss)"",
        "lint:prettier:fix": "prettier --write "./src/**/*.(ts|vue|css|scss)"",
        "lint:eslint": "eslint --ext .ts,.vue ./src",
        "lint:eslint:fix": "eslint --fix --ext .ts,.vue ./src",
        "lint:stylelint": "stylelint ./src/**/*.{vue,css,scss}",
        "lint:stylelint:fix": "stylelint ./src/**/*.{vue,css,scss} --fix",
        "lint:doc:fix": "run-s lint:doc:fix:*",
        "lint:doc:fix:eslint": "eslint --fix --ext .md ./documentation",
        "lint:doc:fix:prettier": "prettier --write "./documentation/**/*.(md)"",
        "test": "run-p test:lint",
        "test:tsc": "vue-tsc --noEmit",
        "test:lint": "run-p lint:eslint lint:stylelint lint:prettier",
        "e2e": "cypress run"
      },
      "dependencies": {
        "@ckeditor/ckeditor5-build-classic": "28.0.0",
        "@ckeditor/ckeditor5-vue": "2.0.1",
        "@iconify/iconify": "2.0.2",
        "@mapbox/mapbox-gl-geocoder": "4.7.1",
        "@popperjs/core": "2.9.2",
        "@vueform/multiselect": "1.5.0",
        "@vueform/slider": "1.0.5",
        "@vuelidate/core": "^2.0.0-alpha.41",
        "@vuelidate/validators": "^2.0.0-alpha.29",
        "@vueuse/core": "5.0.3",
        "@vueuse/head": "0.6.0",
        "apexcharts": "3.27.1",
        "axios": "^0.22.0",
        "billboard.js": "3.0.3",
        "bulma": "0.9.3",
        "dayjs": "1.10.5",
        "dragula": "3.7.3",
        "dropzone": "5.9.2",
        "filepond": "4.28.2",
        "filepond-plugin-file-validate-size": "2.2.4",
        "filepond-plugin-file-validate-type": "1.2.6",
        "filepond-plugin-image-crop": "2.0.6",
        "filepond-plugin-image-edit": "1.6.3",
        "filepond-plugin-image-exif-orientation": "1.0.11",
        "filepond-plugin-image-preview": "4.6.6",
        "filepond-plugin-image-resize": "2.0.10",
        "filepond-plugin-image-transform": "3.7.6",
        "firebase": "^9.6.2",
        "imask": "6.0.7",
        "mapbox-gl": "2.3.0",
        "markdown-it-emoji": "2.0.0",
        "notyf": "3.10.0",
        "nprogress": "0.2.0",
        "photoswipe": "4.1.3",
        "simple-datatables": "3.0.2",
        "simplebar": "6.0.0-beta.10",
        "simplebar-vue": "2.0.0-beta.10",
        "sweet-modal-vue": "^2.0.0",
        "tiny-slider": "2.9.3",
        "tippy.js": "6.3.1",
        "trim-newlines": "^4.0.2",
        "tslib": "2.3.0",
        "v-calendar": "3.0.0-alpha.4",
        "vue": "3.0.11",
        "vue-i18n": "9.1.4",
        "vue-js-modal": "^2.0.1",
        "vue-router": "4.0.6",
        "vue-scrollto": "2.20.0",
        "vue-tippy": "6.0.0-alpha.29",
        "vue3-apexcharts": "1.4.0",
        "xmodal-vue": "^1.0.5"
      },
      "devDependencies": {
        "@iconify/json": "1.1.358",
        "@intlify/vite-plugin-vue-i18n": "2.2.1",
        "@types/dragula": "3.7.0",
        "@types/mapbox__mapbox-gl-geocoder": "^4.7.0",
        "@types/mapbox-gl": "^2.3.0",
        "@types/markdown-it": "12.0.2",
        "@types/node": "15.12.4",
        "@types/nprogress": "0.2.0",
        "@types/prismjs": "1.16.5",
        "@types/simplebar": "5.3.3",
        "@typescript-eslint/eslint-plugin": "4.27.0",
        "@typescript-eslint/parser": "4.27.0",
        "@vitejs/plugin-vue": "1.2.3",
        "@vue/compiler-sfc": "3.1.1",
        "cross-env": "7.0.3",
        "cypress": "7.5.0",
        "eslint": "7.29.0",
        "eslint-config-prettier": "8.3.0",
        "eslint-plugin-md": "1.0.19",
        "eslint-plugin-prettier-vue": "3.1.0",
        "eslint-plugin-vue": "7.11.1",
        "gray-matter": "4.0.3",
        "lint-staged": "11.0.0",
        "markdown-it": "12.0.6",
        "markdown-it-anchor": "8.0.3",
        "npm-run-all": "4.1.5",
        "plyr": "3.6.8",
        "prettier": "2.3.1",
        "prismjs": "^1.25.0",
        "rimraf": "3.0.2",
        "rollup": "2.52.1",
        "sass": "1.32.13",
        "stylelint": "^14.2.0",
        "stylelint-config-prettier": "8.0.2",
        "stylelint-config-standard": "^24.0.0",
        "stylelint-scss": "^4.1.0",
        "typescript": "4.3.4",
        "vite": "2.3.8",
        "vite-imagetools": "3.6.8",
        "vite-plugin-components": "0.11.2",
        "vite-plugin-fonts": "0.2.2",
        "vite-plugin-imagemin": "^0.1.0",
        "vite-plugin-pages": "0.13.2",
        "vite-plugin-purge-icons": "0.7.0",
        "vite-plugin-pwa": "0.8.1",
        "vite-plugin-radar": "0.2.0",
        "vue-tsc": "^0.3.0",
        "yorkie": "2.0.0"
      },
      "gitHooks": {
        "pre-commit": "lint-staged"
      },
      "lint-staged": {
        "*.ts": [
          "eslint --fix",
          "prettier --write"
        ],
        "*.scss": [
          "stylelint",
          "prettier --write"
        ],
        "*.md": [
          "eslint --fix",
          "prettier --write"
        ],
        "*.vue": [
          "eslint --fix",
          "prettier --write"
        ]
      }
    }
    
    

    【讨论】:

    • 我真的很困惑。所有其他方法都工作正常。为什么 defineExpose 不起作用?
    • 你在浏览器中收到错误吗?您的 package.json 依赖项和 devdependencies 是什么?
    • 是的,它在浏览器中显示错误。包含 package.json 文件。请检查
    • 你的 vue 版本太旧了。更新到最新的。 defineExpose 是在 3.1.3 github.com/vuejs/core/blob/main/CHANGELOG.md#313-2021-07-01 中添加的
    【解决方案4】:

    似乎是一个 eslint 问题。 defineExpose上方可以加评论:

    // eslint-disable-next-line no-undef
    defineExpose({  })
    

    或者单击将鼠标悬停在 defineExpose 上时显示的快速修复按钮。

    【讨论】:

      猜你喜欢
      • 2018-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多