本文发表于 1565 天前,其中的信息可能已经事过境迁
文章摘要
加载中...|
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结 投诉

defineComponent 的作用

defineComponent 主要用于 TypeScript 的类型推导。

如果直接使用 export default {},TypeScript 可能会将 {} 视为普通对象。而使用 export default defineComponent({}),则可以正确地推导组件选项的类型。通俗来说,在 TypeScript 环境下开发 Vue 组件,使用 defineComponent 是最佳实践。

Vue 3 使用 Element Plus

安装与配置按需引入

首先安装 Element Plus 和自动导入插件:

bash
npm install element-plus
npm install -D unplugin-vue-components

然后修改 vue.config.js(Vue CLI 项目):

javascript
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')

module.exports = {
  // 注意:修改 webpack 配置需要放在 configureWebpack 中
  configureWebpack: {
    plugins: [
      Components({
        resolvers: [ElementPlusResolver()],
      }),
    ],
  }
}

常见报错Invalid options in vue.config.js: "plugins" is not allowed原因plugins 属性不能直接放在 vue.config.js 根对象下,必须包裹在 configureWebpack 中。

配置完成后,项目中即可直接使用 Element Plus 组件,无需在 main.js 中再次导入。

配置 HTML 标题

如果需要动态修改 index.html 中的标题(使用 htmlWebpackPlugin.options.title),可以在 vue.config.js 中使用 chainWebpack 进行修改:

javascript
module.exports = {
  chainWebpack: config => {
    config
      .plugin('html')
      .tap(args => {
        args[0].title = '你的自定义标题'
        return args
      })
  }
}

Style Scoped

<style> 标签上添加 scoped 属性,可以确保样式只作用于当前组件,实现样式隔离。

html
<style scoped>
/* 仅当前组件生效 */
</style>

Vue 3 添加全局方法

在 Vue 3 中,不再使用 Vue.prototype 挂载全局方法,而是通过 app.config.globalProperties

挂载(main.js):

javascript
import { createApp } from 'vue'
import App from './App.vue'
import axios from 'axios'
import { ElMessage } from 'element-plus'

const app = createApp(App)

// 挂载全局方法
app.config.globalProperties.$http = axios
app.config.globalProperties.$message = ElMessage

app.mount('#app')

使用(组件内 setup):

javascript
import { getCurrentInstance } from 'vue'

export default {
  setup() {
    const { proxy } = getCurrentInstance()
    
    // 调用全局方法
    proxy.$http.get(...)
    proxy.$message.success(...)
  }
}

Vue 3 表单验证

Vue 3 中获取 ref 实例的方式发生了变化,不再使用 this.$refs

javascript
import { getCurrentInstance } from 'vue'

export default {
  setup() {
    const { proxy } = getCurrentInstance()
    
    const submitForm = () => {
      // 这里的 proxy 相当于 Vue 2 中的 this
      proxy.$refs.formRef.validate((valid) => {
        console.log(valid)
      })
    }
    
    return { submitForm }
  }
}

Axios POST 请求数据格式问题

Axios 默认发送的数据格式是 JSON (application/json)。如果后端需要 application/x-www-form-urlencoded 格式,会导致参数接收失败。

解决方案:使用 qs 模块在请求拦截器中序列化数据。

javascript
import axios from 'axios'
import qs from 'qs'

// 请求拦截器
axios.interceptors.request.use(config => {
  // 将 data 转换为查询字符串格式
  if (config.method === 'post') {
     config.data = qs.stringify(config.data)
  }
  return config
})

Vue Router 路由传参

在 Vue 3 中,useRouteruseRoute 是两个不同的 Hook:

  • useRouter():返回 router 实例,用于执行路由跳转(相当于 this.$router)。
  • useRoute():返回当前路由对象,用于获取参数(相当于 this.$route)。

路由跳转(传参):

javascript
import { useRouter } from "vue-router";

const router = useRouter();
router.push({
  path: '/pc/articleList',
  // 使用 query 传参
  query: {
    cate_id_son: data.cate_id_son
  }
});

接收参数:

javascript
import { useRoute } from "vue-router";

const route = useRoute();
console.log(route.query); // 获取参数

Vue 3 watchEffect

watchEffect 类似于 React 的 useEffect。它会立即执行传入的函数,并响应式追踪其依赖,并在依赖变更时重新运行该函数。

javascript
import { watchEffect } from 'vue'

watchEffect(async () => {
  // 页面加载时会立即执行一次
  // 当 route.query.sname 发生变化时,也会触发重新执行
  const { data: { data: res } } = await proxy.$http.get('/user/subjectfiles?sname=' + route.query.sname)
  data.Listdata = res
})
赞赏博主