Giter Site home page Giter Site logo

关于Vue自定义组件实现 about amis HOT 10 CLOSED

baidu avatar baidu commented on April 27, 2024
关于Vue自定义组件实现

from amis.

Comments (10)

RickCole21 avatar RickCole21 commented on April 27, 2024 6

新的自定义组件核心还是React组件,可以参考以下的思路:

1. 在 React 中创建 Vue 的实例

import * as Vue from 'vue/dist/vue';  // 注意这里要引同时包含编译器和运行时的完整版本
import {Renderer} from '../factory' //  根据自定义组件的需求自行选择渲染器,Renderer、FormItem或者OptionsControl

@Renderer({
    test: /(^|\/)hello\-vue$/
})
class VueComponent extends React.PureComponent<any>{
    vm: any;

    constructor(props: any) {
        super(props);
        this.domRef = React.createRef();
    }

    componentDidMount() {

        // DidMount的时候实例化Vue
        this.vm = new Vue({
            el: '#dom',
            template: '<div>Hello {{name}}</div>',
            data() {
                return {
                    name: 'Vue'
                };
            }
        });
        this.domRef.current.appendChild(this.vm.$mount().$el);
    }

    componentWillUnmount() {
        this.vm.$destroy();
    }

    render() {
        return (
            <div ref={this.domRef}></div>
        );
    }
}

2. 打通和 amis 的通信

大部分情况应该是会编写基于FormItem或者OptionsControl的表单组件,那么amisVue之间的通信不可避免,分两个方向

vue -> amis

在实例化Vue后,通过$on监听当前实例上的自定义事件,例如:

// 这里的this.props.onChange是amis暴露出来的方法,可以修改表单项的值
this.vm.$on('change', (value: any) => this.props.onChange(value));

监听之后在Vue实例中就可以这样使用

 this.$emit('change', '新的value');

amis -> vue

有时候amis数据的变化,也需要通知到Vue组件中,例如给OptionsControl配置source动态拉取数据时,拉取到options需要通知给Vue组件进行更新

但是由于Vue的限制,你需要在实例化的时候声明所有响应式属性,所以在实例化Vue组件之前,将 amispropsVue组件的 data merge一下,方便后续的通信,例如:

let amisData = {};
Object.keys(this.props).forEach(key => {
    const value = this.props[key];
    typeof value !== 'function' && (amisData[key] = value);
});
this.vm = new Vue({
    data() {
        return Object.assign(amisData, {
            name: 'Vue'
        });
    }
});

之后在componentDidUpdate,直接通过this.vm更新数据就可以了

componentDidUpdate() {
    Object.keys(this.props).forEach(key =>
        // 过滤掉function
        typeof this.props[key] !== 'function' && (this.vm[key] = this.props[key]);
    );
}

from amis.

2betop avatar 2betop commented on April 27, 2024

应该是这样的方式, React 还是底层,Vue 组件在 React 的 didMount 中实例化出来,并打通通信。

from amis.

2betop avatar 2betop commented on April 27, 2024

@RickCole21 可以来详细说一下

from amis.

qdsang avatar qdsang commented on April 27, 2024

@2betop 不考虑直接出个全vue版本吗?

from amis.

2betop avatar 2betop commented on April 27, 2024

不考虑,这成本得多大!!

from amis.

qdsang avatar qdsang commented on April 27, 2024

https://elemefe.github.io/element-react/
他们家怎么做到了?

现在新业务很少会选 React 做后台了吧,基本都是Webpack+Vue做基础

from amis.

2betop avatar 2betop commented on April 27, 2024

这是json renderer 不是 ui 库,用什么底层无所谓

from amis.

Niqian avatar Niqian commented on April 27, 2024

关于vue组件的问题,能不出一个完整的demo,从自定义组件的开发打包到实际在vue项目中运用,对于前端基础差的同学们真的是很有必要的,谢谢了

from amis.

guanyue-leo avatar guanyue-leo commented on April 27, 2024

我的方法:

import Vue from 'vue'
import VueComponent from './VueComponent '
let React = amisRequire('react')
let amisLib = amisRequire('amis')

function CustomComponent(props) {
  let dom = React.useRef(null)
  React.useEffect(function () {
    const vm = new Vue({...VueComponent , propsData: props})
    dom.current.appendChild(vm.$mount().$el)
  })
  return React.createElement('div', {
    ref: dom
  })
}

// 注意test为组件名
amisLib.Renderer({
  test: /(^|\/)vue-component/
})(CustomComponent)

from amis.

jwxhhxx avatar jwxhhxx commented on April 27, 2024

我的方法:

import Vue from 'vue'
import VueComponent from './VueComponent '
let React = amisRequire('react')
let amisLib = amisRequire('amis')

function CustomComponent(props) {
  let dom = React.useRef(null)
  React.useEffect(function () {
    const vm = new Vue({...VueComponent , propsData: props})
    dom.current.appendChild(vm.$mount().$el)
  })
  return React.createElement('div', {
    ref: dom
  })
}

// 注意test为组件名
amisLib.Renderer({
  test: /(^|\/)vue-component/
})(CustomComponent)

请问这个amis怎传数据给vue组件呢

from amis.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.