VueJS; дождаться элемента перед запуском локального JavaScript файла - PullRequest
1 голос
/ 06 апреля 2020

У меня есть несколько компонентов, javascript и элементов, которые необходимо запустить в определенном порядке.

1-й - opensheetmusicdisplay.min.js, которые есть в моем файле индекса. html. Это не проблема.

2-й - <div id="xml">

3-й - xml-loader.js, который зависит как от "xml" div, так и от opensheetmusicdisplay.min,js

Это индекс. html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script rel="preload" src="<%= BASE_URL %>js/osmd/opensheetmusicdisplay.min.js"></script>    
  </head>

  <body>
    <div id="xml2">words go here</div>
    <div id="app"></div>   
  </body>
</html>

И это часть JavaScript, которую я пытаюсь проверить:

window.onload = function() {
    alert("xx == ", document.getElementById("xml2"));
}

alert("xx2 == ", document.getElementById("xml2"));

alert(JSON.stringify(opensheetmusicdisplay, null, 1));

Когда я запускаю это, они оба экземпляра "xml2" показать пробелы. opensheetmusicdisplay показывает данные, что означает, что они читают из источника в разделе head в index.html

. В комментариях было указано, что предупреждение принимает только один аргумент. Это ошибка, которую я собираюсь оставить на мгновение. Ошибка в консоли: TypeError: document.getElementById (...) имеет значение null.

Теперь это главное. js. Есть много комментариев из-за моих различных идей:

// vue импорт и конфигурация импорт Vue из 'vue' импорт приложения из '@ / App' импорт VueRouter из 'vue -router '

Vue .use (VueRouter) Vue .config.productionTip = false

// page imports
import Notation from '@/components/Notation'
import HomePage from '@/components/HomePage'
// component imports and registration
import { FoundationCSS } from  '@/../node_modules/foundation-sites/dist/css/foundation.min.css'
Vue.component('foundation-css', FoundationCSS)

import SideNav from '@/components/SideNav'
Vue.component('side-nav', SideNav);

// import * as Osmd from '@/../public/js/osmd/opensheetmusicdisplay.min.js'
// Vue.component('osmd-js', Osmd)
// import { OsmdJs } from '@/components/Osmd'

import * as XmlJs from '@/../public/js/osmd/xml-loader.js'
Vue.component('xml-js', XmlJs)
// import XLoad from '@/components/XmlLoader'

const router =  new VueRouter({
    mode: 'history',
    routes: [
        { path: '/',
          components: {
              maininfo: HomePage
          }
        },
        { path: '/chromatic-scales/c-chromatic-scale',
          components: {
              maininfo: Notation// ,
              // xmlloader: XLoad
          }
        }
    ]
})


new Vue({
    el: '#app',
    router,
    template: '<App/>',
    components: { App }
})

Я зарегистрировал XmlJs как глобальный, потому что это единственный выход из 100 вещей, которые на самом деле работает. Затем я вставляю его в Notation.vue примерно так:

<template>
<div>

  <div id="xml">
    {{ notation.data }}
  </div>
  <xml-js />
</div>
</template>

<script>
import axios from 'axios'


export default ({
data () {
return {
notation: null,
}
},
mounted () {
axios
    .get('http://localhost:3000/chromatic-scales/c-chromatic-scale')
    .then(result => (this.notation = result))
}})


</script>

<style scoped></style>

Последний файл - это мясо и картошка того, что я пытаюсь сделать. xml-loader.js отбирает данные из <div id="xml"> и делает все магические операции c, которые программа делает для вывода нужного мне результата. Проблема в том, что в {{ notation.data }}.

я, кажется, все равно не дождусь, пока я новичок в использовании фреймворков vuejs и front-end javascript в целом. Я признаю, что код, вероятно, не является оптимальным в настоящее время.

Ответы [ 2 ]

2 голосов
/ 06 апреля 2020

Существует состояние гонки, при котором элемент DOM недоступен во время обращения к нему. Решение состоит в том, чтобы не получить доступ к элементам DOM, созданным Vue вне его. Элемент DOM готов к использованию только после асинхронного запроса:

<template>
<div>
  <div ref="xml" id="xml">
    {{ notation.data }}
  </div>
  <xml-js />
</div>
</template>

<script>
import axios from 'axios'

export default ({
data () {
return {
notation: null,
}
},
async mounted () {
  const result = await axios
    .get('http://localhost:3000/chromatic-scales/c-chromatic-scale')
  this.notation = result;
  this.$nextTick(); // wait for re-render
  renderXml(this.$ref.xml); // pass DOM element to third-party renderer
}})
0 голосов
/ 06 апреля 2020

Вы можете импортировать xml -loader. js в нотацию. vue как функцию. Тогда вы можете просто сделать что-то вроде этого:

mounted () {
  axios.get(PATH).then(result => {
    this.notation = result
    let xmlResult = loadXML(result)
    doSomethingWithResult(xmlResult)
  }
},
methods: {
  doSomethingWithResult (result) {
    // do something
  }
}
...