AMISRenderer.vue 3.58 KB
<template><div class="amis-container">Loading...</div></template>

<script>
  import qs from 'qs'

  export default {
    name: 'AMISRenderer',
    components: {},
    props: {
      schema: {
        type: Object,
        default: () => ({}),
      },
      locals: {
        type: Object,
        default: () => ({}),
      },
      props: {
        type: Object,
        default: () => ({}),
      },
      env: {
        type: Object,
        default: () => ({}),
      },
      // 这里面的数据所有 amis 页面都可以获取到
      // 可以用来放一下公共数据,比如用户信息等
      // 不要放受控数据,受控数据应该通过 data 下发
      context: {
        type: Object,
        default: () => ({}),
      },
    },
    data() {
      const router = this.$router
      return {
        get location() {
          const current = router.history.current
          return {
            pathname: current.path,
            hash: current.hash,
            query: current.query,
            search: `?${qs.stringify(current.query)}`,
          }
        },
        loading: false,
        amisInstance: null,
        unmounted: false,
      }
    },

    watch: {
      locals: function () {
        this.updateProps()
      },
      props: function () {
        this.updateProps()
      },
      $route: function () {
        this.updateProps()
      },
    },
    async mounted() {
      if (this.unmounted) {
        return
      }

      const scoped = amisRequire('amis/embed')
      const { normalizeLink } = amisRequire('amis')
      const router = this.$router
      const instance = scoped.embed(
        this.$el,
        this.schema,
        {
          data: {
            ...this.locals,
          },
          context: this.context,
          location: this.location,

          // todo 下发 location 对象
          ...this.props,
        },
        {
          jumpTo: (to, action) => {
            // 覆盖内置的跳转逻辑,根据项目需求自己处理
            // if (to === 'goBack') {
            //   return router.go(-1)
            // }
            //
            // to = normalizeLink(to, this.location)
            //
            // if (action?.actionType === 'url') {
            //   action.blank === false ? router.push(to) : window.open(to)
            //   return
            // }
            //
            // // 主要是支持 nav 中的跳转
            // if (action && to && action.target) {
            //   window.open(to, action.target)
            //   return
            // }
            //
            // if (/^https?:\/\//.test(to)) {
            //   window.location.replace(to)
            // } else {
            //   router.push(to)
            // }
          },

          updateLocation: (location, replace) => {
            // 覆盖内置的跳转逻辑,根据项目需求自己处理
            // if (location === 'goBack') {
            //   return router.go(-1)
            // }
            //
            // location = normalizeLink(location, this.location)
            // replace ? router.replace(location) : router.replace(location)
          },

          ...this.env,
        },
        () => {
          this.$emit('ready', {
            instance,
          })
        }
      )

      this.amisInstance = instance
    },

    destroyed() {
      this.unmounted = true
      this.amisInstance?.unmount()
    },

    methods: {
      updateProps() {
        this.amisInstance?.updateProps({
          data: {
            ...this.locals,
          },
          context: this.context,
          ...this.props,
        })
      },
    },
  }
</script>