vue2.x 没有代码提示问题(Vetur)

532 阅读2分钟

vscode中vue项目来回切换的时候没有代码提示的问题

//vue2.x 使用插件Vetur
//vue3.x 使用Volor(vue official)

Vetur

  1. 如果不设置相关信息,不能识别template模板中定义方法,属性,计算属性
  2. 自定义全局组件没有代码提示
  3. Vue原型上挂载的方法熟悉没有代码提示

解决方法

  1. 创建vetur.config.js文件(可以解决全局组件问题)
// @ts-nocheck
// vetur.config.js
// /** @type {import('vls').VeturConfig} */
const { readdirSync } = require('fs');
const path = require('path');
const componentPath = path.join(__dirname, './src/components')
const components = readdirSync(componentPath)
module.exports = {
  projects: [
    {
      root: './',
      package: './package.json',
      jsconfig: './jsconfig.json',
      // **optional** default: `[]`
      // Register globally Vue component glob.
      // If you set it, you can get completion by that components.
      // It is relative to root property.
      // Notice: It won't actually do it. You need to use `require.context` or `Vue.component`
      globalComponents: [
        './src/components/**/*.vue',
        // {
        //   // Component name
        //   name: 'ProTable',
        //   // Component file path, please use '/'.
        //   path: './src/components/ProTable/index.vue'
        // }
      ].concat(components.map(name => {
        return {
          // Component name
          name,
          // Component file path, please use '/'.
          path: `./src/components/${name}/index.vue`
        }

      })),
    }
  ]
}

  1. 创建 global.d.ts 声明文件 (src/types/global.d.ts)
import { FunctionalComponentOptions } from 'vue'

interface DictItem {
  dictCode: string
  dictType: string
  dictName: string
  dictSort: number
  dictLabel: string
  dictValue: string
  label: string
  value: string
  dictValueRef: string
  status: string
  remark?: any
}
/**
 * 一个泛型接口,根据输入参数动态生成属性
 * @template T 属性名的类型,由输入参数决定
 */
type IRes<T extends string> = {
  [P in T]: DictItem[]
}

/**
 * 一个异步函数,接受字符串或字符串数组作为参数,并返回对应的 IRes 类型结果
 * @param {string | string[]} key - 输入参数,可以是单个字符串或字符串数组
 * @param {boolean} retrieve - 是否强制重新获取
 * @returns {Promise<IRes<T>>} 返回一个 Promise,解析为 IRes 类型的对象,其中属性名与输入参数相对应
 * @example
 * ```javascript
 * // 如果调用 useDict('test'),将返回 Promise<{ test: any[] }>
 * // 如果调用 useDict(['test1', 'test2']),将返回 Promise<{ test1: any[], test2: any[] }>
 * ```
 */
export function useDict<T extends string>(key: T | T[], retrieve: boolean): Promise<IRes<T>>

/**函数式组件 */
export function functionComponent(props: FunctionalComponentOptions): FunctionalComponentOptions

/**随机颜色 */
export function randomColor(type: string | number): string

/**
 * @description              计算表格高度
 * @param searchHeight       搜索区域高度
 * @param btnsHeight         操作按钮的高度
 * @param paginationHeigh    分页区域高度
 */
export function calTableHeight(searchHeight?: number, btnsHeight?: number, paginationHeigh?: number): number

/**
 * @description    复制文本到剪贴板
 * @param text
 */
export function useCopy(text: string | number): void

/**
 * @description    处理千分符显示
 * @param text
 */
export function thousand(text: string | number): string

/**
 * @description     设置统计日期的默认值
 * @param {*} type  类型 'day' 日   'month' '月'
 */
export function setStatisticsDefautTime(type: 'day' | 'month'): [string, string]

/**
 * @description 图片预览
 * @param url 图片地址
 */
export function viewImage(url: string): [string, string]

/**
 * @description 根据选择的语言设置 el-table-column的 width
 * @param {*} cn 中
 * @param {*} jp 日
 * @param {*} en 英
 */
export function calWidth(cn: number, jp: number, en: number): number

/**
 * @description 统计el-table
 * @param {*} param summary-method 默认参数
 * @param {*} needSumFieldList 需要进行统计的字段
 * @param {*} sumText 	合计行第一列的文本
 * @param {*} offset 	偏移 第几个显示
 */
export function handleSum(param: object, needSumFieldList: string[], sumText?: string, offset?: number): any[]

declare global {
  interface Window {
    // $t(key: IKey): string

  }
}

type AnyObject = Record<string, any>
//vetur中声明全局属性方法
type IKey = keyof typeof import('@/language/lang/zn')['default']
declare module '*.vue' {
  import Vue from 'vue'
  export default Vue
}

declare module 'vue/types/vue' {
  interface Vue {
    $t(key: IKey): string
    $hasPermission: (permission: string) => boolean
    $randomColor: typeof randomColor
    $viewImage: typeof viewImage
    /**
     * @description        点击表格的某一项,设置该项的高亮
     * @param row          点击的表格项
     * @param clickedRows
     *
     * @example
     * ```vue
     * <template>
     *   <el-table
     *     :data="tableData"
     *     [@]row-click="(row) => $rowClick(row, clickedRows)"
     *     :row-class-name="({ row }) => $tableRowClassName(row, clickedRows)"
     *
     *   >
     *   </el-table>
     * </template>
     * <script>
     * export default {
     *   data() {
     *     return {
     *       clickedRows: []
     *     }
     *   }
     * }
     * </script>
     * ```
     * @returns
     */
    $rowClick: (row: AnyObject, clickedRows: string[]) => void
    $tableRowClassName: (row: AnyObject, clickedRows: string[]) => '' | 'clicked-row'
    calTableHeight: typeof calTableHeight
    functionComponent: typeof functionComponent
    useCopy: typeof useCopy
    thousand: typeof thousand
    setStatisticsDefautTime: typeof setStatisticsDefautTime
    /**
     * 首字母大写
     */
    firstToUpper: (str?: string) => string
    /**
     * 重置表格排序
     */
    resetSortQuery: (column?: AnyObject) => void
    /**
     * @description   设置表格排序字段升序/降序
     * @param column
     * @param value   升序/降序
     * @returns
     */
    setSortQuery: (column: AnyObject, value: 'asc' | 'desc') => void
    /**
     * @description   设置表格排序图标升序/降序的样式
     * @param column
     * @param value   升序/降序 图标
     * @returns
     */
    setSortIconStyle: (column: AnyObject, value: 'asc' | 'desc') => { color: string }

    calWidth: typeof calWidth
    handleSum: typeof handleSum
  }
}
// filter 不支持


  1. .vscode配置文件
在当前目录下创建 .vscode文件夹并添加文件
//extensions.json
{
  "recommendations": ["octref.vetur"],
  "unwantedRecommendations": ["Vue.volar"]
}

//settings.json
{
  "vetur.experimental.templateInterpolationService": true,
  "vetur.validation.template": true,
  "vetur.completion.tagCasing": "initial",
  "vetur.languageFeatures.codeActions": true,
  "vetur.languageFeatures.semanticTokens": true,
  "vetur.validation.interpolation": true
}

这样勉强可以实现代码提示

其他问题

  • vue2项目建议手动关闭voloar插件,启用Vetur
  • vue文件 全局filter没有代码提示
  • 使用computed属性如果不定义计算属性的返回类型,整个vue文件都会报错
computed: {
    /**
     * @returns {string}
     */
    pageStyle() {
      return {
        '--item-width': `${this.searchFormItemWidth}px`,
      }
    },
    /**
     * @returns {string}
     */
    style() {
      return {
        marginRight: `5px`,
      }
    },
  },