init vue
This commit is contained in:
70
blk_inventory_vue/README.md
Normal file
70
blk_inventory_vue/README.md
Normal file
@ -0,0 +1,70 @@
|
||||
# demo
|
||||
|
||||
## 文件目录说明
|
||||
|
||||
```ts
|
||||
├─README.md
|
||||
├─block.json 小组件元信息,npm run upload上传的时候,代码将上传到block.json中的blockTypeID对应的小组件(插件),更换其中的url可以更换npm run start预览时打开的多维表格
|
||||
├─jsconfig.json
|
||||
├─package.json
|
||||
├─src 组件
|
||||
| ├─App.vue 组件入口
|
||||
| ├─main.js 入口js文件
|
||||
| ├─locales 多语配置
|
||||
| | ├─en.json en语言配置
|
||||
| | ├─i18n.js 多语配置文件,默认启用中文和英文
|
||||
| | └zh.json zh语言配置
|
||||
| ├─components
|
||||
| | └Form.vue 代码示例
|
||||
| ├─assets
|
||||
| | └main.css 默认重制了一些css样式
|
||||
├─public
|
||||
| ├─favicon.ico 图标
|
||||
| └index.html 入口文件
|
||||
├─config
|
||||
| └webpack.config.js webpack配置文件
|
||||
```
|
||||
|
||||
## 国际化
|
||||
|
||||
本模板已内置国际化方案,你只需提供国际化的文案即可
|
||||
|
||||
1.在 src/locales 对应文件增加国际化文案,如在en.json中:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "title"
|
||||
}
|
||||
```
|
||||
|
||||
2.在代码中通过$t函数使用国际化key,如在App.vue中:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<h1>{{$t('title')}}</h1>
|
||||
</template>
|
||||
```
|
||||
|
||||
## 安装依赖
|
||||
|
||||
```sh
|
||||
npm / yarn / pnpm install
|
||||
```
|
||||
|
||||
## 启动
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## 打包
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
## 发布
|
||||
|
||||
```sh
|
||||
npm run upload
|
||||
```
|
4
blk_inventory_vue/block.json
Normal file
4
blk_inventory_vue/block.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"blockTypeID": "blk_67bf27b12481001387d8f3b9",
|
||||
"url": "https://hailiang.feishu.cn/base/AhiKbmafxasuodsRyoHc79junPe"
|
||||
}
|
117
blk_inventory_vue/config/webpack.config.js
Normal file
117
blk_inventory_vue/config/webpack.config.js
Normal file
@ -0,0 +1,117 @@
|
||||
const { VueLoaderPlugin } = require("vue-loader");
|
||||
const path = require("path");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const { ESBuildMinifyPlugin } = require("esbuild-loader");
|
||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||
const WebpackBar = require("webpackbar");
|
||||
const {
|
||||
BitableAppWebpackPlugin,
|
||||
opdevMiddleware,
|
||||
} = require("@lark-opdev/block-bitable-webpack-utils");
|
||||
|
||||
const AutoImport = require("unplugin-auto-import/webpack");
|
||||
const Components = require("unplugin-vue-components/webpack");
|
||||
const { ElementPlusResolver } = require("unplugin-vue-components/resolvers");
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV === "development";
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
|
||||
const config = {
|
||||
entry: "./src/main.js",
|
||||
devtool: isProduction ? false : "inline-source-map",
|
||||
mode: isDevelopment ? "development" : "production",
|
||||
stats: "errors-only",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "../dist"),
|
||||
clean: true,
|
||||
publicPath: isDevelopment ? "/block/" : "./",
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
use: "vue-loader",
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
include: [/node_modules\/@lark-open/],
|
||||
use: ["source-map-loader"],
|
||||
enforce: "pre",
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [isDevelopment ? "style-loader" : MiniCssExtractPlugin.loader, "css-loader"],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|jpeg|gif|ico|svg)$/,
|
||||
type: "asset/resource",
|
||||
generator: {
|
||||
filename: "assets/[name][ext][query]",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
...(isDevelopment ? [new WebpackBar()] : [new MiniCssExtractPlugin()]),
|
||||
|
||||
new BitableAppWebpackPlugin({
|
||||
// open: true, // 控制是否自动打开多维表格
|
||||
}),
|
||||
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "index.html",
|
||||
template: "./public/index.html",
|
||||
publicPath: isDevelopment ? "/block/" : "./",
|
||||
}),
|
||||
|
||||
new VueLoaderPlugin(),
|
||||
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
dts: false,
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
dts: false,
|
||||
}),
|
||||
],
|
||||
optimization: {
|
||||
minimize: isProduction,
|
||||
minimizer: [new ESBuildMinifyPlugin({ target: "es2015", css: true })],
|
||||
moduleIds: "deterministic",
|
||||
runtimeChunk: true,
|
||||
splitChunks: {
|
||||
chunks: "all",
|
||||
cacheGroups: {
|
||||
vendor: {
|
||||
name: "vendor",
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
chunks: "all",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
devServer: isProduction
|
||||
? undefined
|
||||
: {
|
||||
hot: true,
|
||||
client: {
|
||||
logging: "error",
|
||||
},
|
||||
setupMiddlewares: (middlewares, devServer) => {
|
||||
if (!devServer || !devServer.app) {
|
||||
throw new Error("webpack-dev-server is not defined");
|
||||
}
|
||||
middlewares.push(opdevMiddleware(devServer));
|
||||
return middlewares;
|
||||
},
|
||||
},
|
||||
cache: {
|
||||
type: "filesystem",
|
||||
buildDependencies: {
|
||||
config: [__filename],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = config;
|
8
blk_inventory_vue/jsconfig.json
Normal file
8
blk_inventory_vue/jsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
11700
blk_inventory_vue/package-lock.json
generated
Normal file
11700
blk_inventory_vue/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
39
blk_inventory_vue/package.json
Normal file
39
blk_inventory_vue/package.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "@bitable/board-view-demo",
|
||||
"version": "0.1.0",
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=development webpack-dev-server --mode development --config ./config/webpack.config.js",
|
||||
"start": "npm run dev",
|
||||
"build": "cross-env NODE_ENV=production webpack --mode production --config ./config/webpack.config.js",
|
||||
"upload": "npm run build && opdev upload ./dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lark-opdev/block-bitable-api": "^0.3.2",
|
||||
"@vue/compiler-sfc": "^3.3.13",
|
||||
"element-plus": "^2.3.6",
|
||||
"@element-plus/icons": "^0.0.11",
|
||||
"normalize-css": "^2.3.1",
|
||||
"style-loader": "^3.3.3",
|
||||
"vue": "^3.3.11",
|
||||
"vue-i18n": "^9.4.1",
|
||||
"vue-template-compiler": "^2.7.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lark-opdev/block-bitable-webpack-utils": "^0.1.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^6.8.1",
|
||||
"esbuild-loader": "^2.20.0",
|
||||
"html-webpack-plugin": "^5.6.0",
|
||||
"mini-css-extract-plugin": "^2.7.6",
|
||||
"simple-progress-webpack-plugin": "^2.0.0",
|
||||
"source-map-loader": "^4.0.1",
|
||||
"vue-hot-reload-api": "^2.3.4",
|
||||
"vue-loader": "^17.4.0",
|
||||
"webpack": "^5.74.0",
|
||||
"unplugin-auto-import": "^0.16.4",
|
||||
"unplugin-vue-components": "^0.25.1",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-dev-server": "^4.10.0",
|
||||
"webpackbar": "^5.0.2"
|
||||
}
|
||||
}
|
BIN
blk_inventory_vue/public/favicon.ico
Normal file
BIN
blk_inventory_vue/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
13
blk_inventory_vue/public/index.html
Normal file
13
blk_inventory_vue/public/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Base Script</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
26
blk_inventory_vue/src/App.vue
Normal file
26
blk_inventory_vue/src/App.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<script setup>
|
||||
import Form from './components/Form.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main>
|
||||
<h1>{{$t('title')}}</h1>
|
||||
<h4>编辑 <code>src/App.vue</code> 并保存以重新加载</h4>
|
||||
<Form />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
main {
|
||||
padding: 1rem;
|
||||
}
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: #d63384;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
</style>
|
1
blk_inventory_vue/src/assets/main.css
Normal file
1
blk_inventory_vue/src/assets/main.css
Normal file
@ -0,0 +1 @@
|
||||
@import "normalize-css";
|
72
blk_inventory_vue/src/components/Form.vue
Normal file
72
blk_inventory_vue/src/components/Form.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<script>
|
||||
import { bitable } from '@lark-opdev/block-bitable-api';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import {
|
||||
ElButton,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
} from 'element-plus';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ElButton,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
},
|
||||
setup() {
|
||||
const formData = ref({ table: '' });
|
||||
const tableMetaList = ref([]);
|
||||
|
||||
const addRecord = async () => {
|
||||
const tableId = formData.value.table;
|
||||
if (tableId) {
|
||||
const table = await bitable.base.getTableById(tableId);
|
||||
table.addRecord({ fields: {} });
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
const [tableList, selection] = await Promise.all([bitable.base.getTableMetaList(), bitable.base.getSelection()]);
|
||||
formData.value.table = selection.tableId;
|
||||
tableMetaList.value = tableList;
|
||||
});
|
||||
|
||||
return {
|
||||
formData,
|
||||
tableMetaList,
|
||||
addRecord,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-form ref="form" class="form" :model="formData" label-position="top">
|
||||
<el-form-item label="选择数据表" size="large">
|
||||
<el-select v-model="formData.table" placeholder="请选择数据表" style="width: 100%">
|
||||
<el-option
|
||||
v-for="meta in tableMetaList"
|
||||
:key="meta.id"
|
||||
:label="meta.name"
|
||||
:value="meta.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-button type="primary" plain size="large" @click="addRecord">新增一行记录</el-button>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.form :deep(.el-form-item__label) {
|
||||
font-size: 16px;
|
||||
color: var(--el-text-color-primary);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.form :deep(.el-form-item__content) {
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
3
blk_inventory_vue/src/locales/en.json
Normal file
3
blk_inventory_vue/src/locales/en.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"title":"title"
|
||||
}
|
20
blk_inventory_vue/src/locales/i18n.js
Normal file
20
blk_inventory_vue/src/locales/i18n.js
Normal file
@ -0,0 +1,20 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import en from './en.json';
|
||||
import zh from './zh.json';
|
||||
import { bitable } from '@lark-opdev/block-bitable-api'
|
||||
|
||||
|
||||
|
||||
export const i18n = createI18n({
|
||||
locale: 'en',
|
||||
allowComposition: true, // 占位符支持
|
||||
messages: {
|
||||
en: en,
|
||||
zh: zh
|
||||
}
|
||||
})
|
||||
|
||||
bitable.bridge.getLanguage().then((lang) => {
|
||||
i18n.global.locale = lang
|
||||
})
|
||||
|
3
blk_inventory_vue/src/locales/zh.json
Normal file
3
blk_inventory_vue/src/locales/zh.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"title": "标题"
|
||||
}
|
6
blk_inventory_vue/src/main.js
Normal file
6
blk_inventory_vue/src/main.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import './assets/main.css'
|
||||
import {i18n} from './locales/i18n.js'
|
||||
createApp(App).use(i18n).mount('#app') // 注入国际化函数$t
|
||||
|
Reference in New Issue
Block a user