使用 Vue 开发自定义控件
一、初衷:
-
Trantor 集成内置的 Engine 组件无法满足业务的需要
-
使用者在开发自定义容器与控件的时候需要使用 Vue 框架来开发
对此,我们使用 vuera 来兼容 Vue框架开发的组件,让用户能够使用 Vue 以及周边生态来开发自定义容器与控件
二、 准备工作
-
环境搭建
环境搭建具体请参考 自定义数据容器与控件
使用例子请参考 Demo
-
Vue 环境准备
-
安装 t-tools
Terminal window yarn add t-tools -g// ornpm install t-tools -g注意,t-tools 版本需要使用新版本防止部分功能不生效,目前需使用
^0.1.7 -
安装依赖
在根目录下
package.json中新增以下依赖:{"devDependencies": {"@terminus/t-tools": "0.1.7","@terminus/t-tools-externals-deps": "0.0.10","@terminus/t-tools-externals-lazy-deps": "0.0.10","@terminus/t-tools-externals-lazy-pkgs": "0.0.10","babel-loader": "^8.2.2","babel-plugin-import": "^1.13.3","css-loader": "4.3.0","vue-loader": "^15.9.8","vue-template-compiler": "^2.6.14","webpack": "^4.29.5","webpack-merge": "^5.7.0"},"dependencies": {"ant-design-vue": "^1.7.8","core-js": "2","vue": "^2.6.14","vue-router": "^3.5.2","vuera": "^0.2.7"},} -
配置根目录
settings.js(webpack 配置)const { dynamicExternals } = require('@terminus/t-tools-externals-lazy-pkgs');const { VueLoaderPlugin } = require('vue-loader')const webpack = require('webpack')module.exports ={dist: './dist',dev:{port: 8000,browser: true},isTrantor: true,externals: [ 'react', 'react-dom', 'moment', 'lodash', 'classnames', 'classnames/bind', 'mobx', 'mobx-react', '@terminus/nusi', '@terminus/nusi-engine', '@terminus/i18n-plat-sdk-js'],dynamicExternals,// 这里需要改为 true,让自定义组件开发时使用用户安装的依赖node_modules: true,tool: 'webpack',cssmodule: true,// 配置 webpack,让 t-tools 获得处理 vue、css 的能力webpackConfig: (webpackConfig, webpackMerge)=> {const config = {module: {rules: [{test: /\.vue$/,loader: 'vue-loader'},{test: /\.css$/,use: ['style-loader', 'css-loader']}],},plugins: [new VueLoaderPlugin(),new webpack.WatchIgnorePlugin([/\.d\.ts$/])]}webpackConfig.module.rules[0].options['appendTsSuffixTo'] = [/\.vue$/]return webpackMerge.merge(webpackConfig, config);}}
-
三、开发自定义容器(组件)
-
/src/components/Demo/index.tsximport React from 'react'import { VueInReact } from 'vuera'import MyVueComponent from './Demo.vue'// 容器类型import { ListContainer } from '@terminus/nusi-engine'export default class extends ListContainer {render() {// vueraconst Component = VueInReact(MyVueComponent)return (// 将ListContainer 的属性透传到 vue 组件中<Component message='Hello from Vue!' ctx={this.props}/>)}} -
/src/components/Demo.vue<template><a-form :form="form" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }" @submit="handleSubmit"><a-form-item label="Note"><a-inputv-decorator="['note', { rules: [{ required: true, message: 'Please input your note!' }] }]"/></a-form-item><a-form-item label="Gender"><a-selectv-decorator="['gender',{ rules: [{ required: true, message: 'Please select your gender!' }] },]"placeholder="Select a option and change input text above"@change="handleSelectChange"><a-select-option value="male">male</a-select-option><a-select-option value="female">female</a-select-option></a-select></a-form-item><a-form-item :wrapper-col="{ span: 12, offset: 5 }"><a-button type="primary" html-type="submit">Submit</a-button></a-form-item></a-form></template><!-- 这边使用 lang 为 ts --><script lang="ts">import Vue from 'vue';import Antd from 'ant-design-vue';import 'ant-design-vue/dist/antd.css';Vue.use(Antd);export default {props: {// this.props 属性中可以拿到原 container 中的所有属性方法// 具体使用方法参考 [自定义控件与容器的实践](https://trantor-docs.app.terminus.io/v0.17.x/doc/developer-guide/custom-component#%E5%9B%9B%E3%80%81%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B6%E4%B8%8E%E5%AE%B9%E5%99%A8%E7%9A%84%E5%AE%9E%E8%B7%B5)ctx: Object},data() {return {formLayout: 'horizontal',form: this.$form.createForm(this, { name: 'coordinated' }),};},mounted() {console.log('xxxxxxxxxxxx', this)},methods: {handleSubmit(e) {e.preventDefault();this.form.validateFields((err, values) => {if (!err) {console.log('Received values of form: ', values);}});},handleSelectChange(value) {console.log(value);this.form.setFieldsValue({note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,});},}};</script> -
manifest.json自定义容器描述文件
{"Demo": {"type": "container","entry": {"CustomComponents/Demo": "./components/Demo/index.tsx"},"model": "","description": "Vue Demo 容器组件。"}}
注意事项
09 - 017 自定义组件使用 vue 开发方式均一致,注意使用最新的 t-tools,如有疑问可以直接钉钉联系许超
相关链接: