Как сделать плагин так, что бы он стал реактивным в шаблоне?

Как сделать плагин так, что бы он стал реактивным в шаблоне?

И так, плагин я сделал,

spoiler

/* eslint-disable */
import { JsSIPFactory, JsSPConfiguration } from './JsSIPFactory'
import { UA } from 'jssip'
import {
  ConnectingEvent,
  EndEvent,
  IncomingEvent,
  OutgoingEvent,
  RTCSession
} from 'jssip/lib/RTCSession'

export enum JsSIPState {
  idle = 'idle',
  call = 'call',
  connecting = 'connecting',
  accepted = 'accepted'
}

export class JsSIP {
  private _state: string = JsSIPState.idle
  private _target: string = ''
  private ua: UA

  constructor (url: string, config: JsSPConfiguration) {
    this.ua = JsSIPFactory.create(url, {
      /* eslint-disable */
      uri: config.uri,
      display_name: config.display_name,
      password: config.password
      /* eslint-enable */
    })
    return this
  }

  get target () {
    return this._target
  }

  set target (value: string) {
    this._target = value
  }

  get state (): string {
    return this._state
  }

  /**
   * call up
   * @param target
   */
  public call (target: string): RTCSession {
    if (!this.ua) {
      throw new Error('Initialization required')
    }
    const _this: JsSIP = this as JsSIP
    this._target = target
    this._state = JsSIPState.call
    const session: RTCSession = this.ua.call(target, {
      eventHandlers: {
        connecting: (event: ConnectingEvent) => {
          console.log('session: connecting', event)
          _this._state = JsSIPState.connecting
        },
        accepted: (event: IncomingEvent | OutgoingEvent) => {
          console.log('session: accepted', event)
          _this._state = JsSIPState.accepted
        },
        progress: (event: IncomingEvent | OutgoingEvent) => {
          console.log('session: progress', event)
          _this._state = JsSIPState.idle
        },
        failed: (event: EndEvent) => {
          console.log('session: failed', event)
          _this._state = JsSIPState.idle
        }
      },
      pcConfig: {
        rtcpMuxPolicy: 'negotiate', // Важно для хрома, чтоб работал multiplexing. Эту штуку обязательно нужно включить на астере.
        iceServers: []
      },
      mediaConstraints: {
        audio: true, // Поддерживаем только аудио
        video: false
      }
    })
    session.connection.addEventListener('addstream', (e: any) => {
      // Remote audio control
      const audio: HTMLAudioElement = document.getElementById('audio') as HTMLAudioElement
      audio.srcObject = e.stream
      audio.play()
    })
    return session
  }

  /**
   * Cancel call
   */
  public cancel () {
    this.ua.terminateSessions()
  }

  /**
   * Change configuration
   * @param url
   * @param config
   */
  public setConfiguration (url: string, config: JsSPConfiguration) {
    this.ua = JsSIPFactory.create(url, {
      /* eslint-disable */
      uri: config.uri,
      display_name: config.display_name,
      password: config.password
      /* eslint-enable */
    })
    return this
  }

  public start (): JsSIP {
    this.ua.start()
    return this
  }

  public on (event: string, handler: (...args: any[]) => void): JsSIP {
    (this.ua as UA).addListener(event, handler)
    return this
  }

  public off (event: string, handler: (...args: any[]) => void): JsSIP {
    (this.ua as UA).removeListener(event, handler)
    return this
  }
}



Инсталлирую вот так
import Vue from 'vue'
import { JsSIP } from '@/jsSIP/plugin'

/* eslint-disable */
const $jssip: JsSIP = new JsSIP(`wss://server:8089/ws`, {
  /* eslint-disable */
  uri: `sip:0000@server`,
  display_name: 'Test',
  password: 'password'
  /* eslint-enable */
})

class JsSIPlugin {
  public install () {
    Object.defineProperties(Vue.prototype, {
      $jsSIP: {
        get (): JsSIP {
          return $jssip
        }
      }
    })
  }
}

Vue.use(new JsSIPlugin())


Теперь в шаблоне хочу вызвать свойство $jsSIP.state
Как итог нет реактивности, в интернете масса дерьмовых примеров.

В процессе работы плагина, свойство $jsSIP.state меняется, но в шаблоне не рендерится.

Я хочу реализовать автономный плагин.
  • Вопрос задан
  • 263 просмотра
Решения вопроса 1
IgorPI
@IgorPI Автор вопроса
В общем дело обстоит следующим образом.

В Vue есть метод observable

Нужно указать объект за которым планируем следить
Vue.observable({
      count: 0
    })


В моём случае, так
class JsSIPlugin {
  public install () {
    Object.defineProperties(Vue.prototype, {
      $jsSIP: {
        get (): JsSIP {
          return $jssip
        }
      }
    })

    Vue.observable($jssip)
  }
}


Теперь в шаблоне происходит магия.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы