Web开发日志

Vue篇

关于Slot

Slot,即“插槽”,是Vue的一个很重要的功能。通过插槽,可以将其他的组件“插入”到当前组件的某个槽位。这个机制的优点,就是在保留了子组件的控制的同时,也给父组件保留了一定的内容控制权。比如elementUI,它的很多功能都提供了slot来让我们插入自定义的内容。

用法

它的用法很简单,分两部分。

  1. 组件
1
2
3
...
<slot name="component-a" :param1="123"></slot>
...
  1. 父组件
1
2
3
4
5
<Component>
<template #component-a="{ param_1 }">
{{ param_1 }}
</template>
</Component>

上面是完整示例,一个具名作用域插槽。它将子组件的一个参数param1通过解构赋值,回传到了父组件的形参param_1中,并在其中渲染出了它的值。同时,父组件将这部分template中的内容传入了子组件中,和子组件的其他部分内容一同渲染。

Vue-router

历史模式的问题

Vue-router支持多种历史模式。现在较为常用的一种就是HTML5模式。该模式下,浏览器显示的链接和正常的url一致,非常漂亮。但是需要后端路由的配置,否则会出现刷新页面出现404的问题。

除了HTML5模式,还有一种历史模式,叫做hash模式。它会在url中添加一个#来解决这个问题:#后面的部分在刷新时不会被后端认为是任何后端路由,因此也就不存在刷新后出现404的问题。

这一部分的配置在createRouter()的参数中进行配置:

1
2
3
4
5
6
7
8
9
import { createRouter, createWebHashHistory, createWebHistory } from "vue-router";

export default createRouter({
// hash模式,无需后端配置
history: createWebHashHistory(),
// html5模式,需要后端配置
history: createWebHistory(),
routes: [ ... ]
});

Vuex

这是Vue官方出的状态管理插件。它用来管理整个单页程序的所有数据。

项目架构

使用Vuex时,最佳实践一般是使用模块来组织各个部分的数据。假设我们的项目的store目录结构如下:

1
2
3
4
5
6
- store
- modules
- module1.js
- module2.js
- module3.js
- index.js

那么,我们可以在每个模块中这么定义数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const auth = {
state: {
token: null
},
mutations: {
SET_TOKEN(state, token) {
state.token = token;
}
},
actions: {
setToken({ commit }, token) {
commit("SET_TOKEN", token);
}
},
getters: {
getToken(state) {
return state.token;
}
}
};

export default auth;

然后在index.js中这么导入模块:

1
2
3
4
5
6
7
8
9
10
11
12
import Vue from 'vue';
import Vuex from 'vuex';
import modules from './modules';

Vue.use(Vuex);

const store = new Vuex.Store({
modules,
plugins: [localStoragePlugin]
});

export default store;

这种结构便于我们维护前端的数据模型。

Vite

pathResolve

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
});

ElementUI篇

完整引入

如果你对打包后的文件大小不是很在乎,那么使用完整导入会更方便。

1
2
3
4
5
6
7
8
9
10
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElementPlus)
app.mount('#app')
  • Volar 支持#

如果您使用 Volar,请在 tsconfig.json 中通过 compilerOptions.type 指定全局组件类型。

1
2
3
4
5
6
7
// tsconfig.json
{
"compilerOptions": {
// ...
"types": ["element-plus/global"]
}
}

自动导入

首先你需要安装unplugin-vue-components 和 unplugin-auto-import这两款插件

1
npm install -D unplugin-vue-components unplugin-auto-import

然后把下列代码插入到你的 Vite 或 Webpack 的配置文件中

Vite

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})

Webpack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// webpack.config.js
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')

module.exports = {
// ...
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}

想了解更多打包 (RollupVue CLI) 和配置工具,请参考 unplugin-vue-components 和 unplugin-auto-import

Nuxt

关于 Nuxt 用户, 你只需要安装 @element-plus/nuxt 即可.

1
npm install -D @element-plus/nuxt

然后将下面的代码写入你的配置文件.

1
2
3
4
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@element-plus/nuxt'],
})

配置文档参考 docs.

手动导入

Element Plus 提供了基于 ES Module 的开箱即用的 Tree Shaking 功能。

但你需要安装 unplugin-element-plus 来导入样式。 配置文档参考 docs.

App.vue

1
2
3
4
5
6
7
8
9
<template>
<el-button>我是 ElButton</el-button>
</template>
<script>
import { ElButton } from 'element-plus'
export default {
components: { ElButton },
}
</script>
1
2
3
4
5
6
7
8
// vite.config.ts
import { defineConfig } from 'vite'
import ElementPlus from 'unplugin-element-plus/vite'

export default defineConfig({
// ...
plugins: [ElementPlus()],
})

WARNING

如果使用 unplugin-element-plus 并且只使用组件 API,你需要手动导入样式。

Example:

1
2
import 'element-plus/es/components/message/style/css'
import { ElMessage } from 'element-plus'

全局配置

在引入 ElementPlus 时,可以传入一个包含 size 和 zIndex 属性的全局配置对象。 size 用于设置表单组件的默认尺寸,zIndex 用于设置弹出组件的层级,zIndex 的默认值为 2000

完整引入:

1
2
3
4
5
6
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus, { size: 'small', zIndex: 3000 })

按需引入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<el-config-provider :size="size" :z-index="zIndex">
<app />
</el-config-provider>
</template>

<script>
import { defineComponent } from 'vue'
import { ElConfigProvider } from 'element-plus'

export default defineComponent({
components: {
ElConfigProvider,
},
setup() {
return {
zIndex: 3000,
size: 'small',
}
},
})
</script>

el-input的输入问题

遇到过一次输入框无法输入的问题。查看了下官方文档发现是设计特性。正常来说,Input总是会响应输入事件,但是el-input是受控组件,所以它总是会更优先保证显示v-model绑定的数据值。这也就是为什么输入不会被正常响应的原因:没有给它加v-model,或者绑定了不存在/错误的对象。

不过我绑定不存在元素的时候居然没有报错,神奇……

vue3+vite相对路径打包

1
2
3
4
5
6
7
8
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
base: './'
})
作者

xeonds

发布于

2023-07-10

更新于

2024-05-13

许可协议

评论