通过JavaScript生成的按钮不调用VueJS中的函数

huangapple go评论78阅读模式
英文:

Buttons generated via JavaScript do not call functions in VueJS

问题

这是代码的翻译部分:

我创建了一个函数用于生成列表中每个项目的按钮当点击每个按钮时应该运行App.vue文件中的一个函数

问题在于 `onclick`  `v-on:click` 方法无法正常工作

这是代码

```javascript
    await resetView();
    // document.getElementById("projSelLb").style.display = "none";
    var projects = await detaStorage.getAllProjects();
    var parentDiv = document.getElementById('projectsDetaDiv');
    projects.forEach(function(item) {
      var div = document.createElement('div');
      div.innerHTML = `<button type="button" class="btn btn-primary" style="margin-top: 12px;" @click.native="loadFromDeta(String(item))">${item}</button>`;
      parentDiv.appendChild(div);
    });
    // document.getElementById("projSelLb").style.display = "block";
    document.getElementById("spinnerGetProj").style.display = "none";
  }

  async function resetView() {
    // document.getElementById("projSelLb").style display = "none";
    document.getElementById("spinnerGetProj").style.display = "block";
    document.getElementById('projectsDetaDiv').innerHTML = null;
  }

  function loadFromDeta(name) {
    workspaceClear();
    var data = detaStorage.getProjectData();
    Blockly.Xml.domToWorkspace(data.xml, foo.value.workspace);
  }

如果您需要进一步的帮助或解释,请随时告诉我。

英文:

I've made a function that generates buttons for every item in a list, and every button when clicked should run a function in the App.vue file.

The problem is that the onclick and the v-on:click methods do not work.

This is the code:

    await resetView();
    // document.getElementById(&quot;projSelLb&quot;).style.display = &quot;none&quot;;
    var projects = await detaStorage.getAllProjects();
    var parentDiv = document.getElementById(&#39;projectsDetaDiv&#39;);
    projects.forEach(function(item) {
      var div = document.createElement(&#39;div&#39;);
      div.innerHTML = `&lt;button type=&quot;button&quot; class=&quot;btn btn-primary&quot; style=&quot;margin-top: 12px;&quot; @click.native=&quot;loadFromDeta(String(item))&quot;&gt;${item}&lt;/button&gt;`;
      parentDiv.appendChild(div);
    });
    // document.getElementById(&quot;projSelLb&quot;).style.display = &quot;block&quot;;
    document.getElementById(&quot;spinnerGetProj&quot;).style.display = &quot;none&quot;;

  async function resetView() {
    // document.getElementById(&quot;projSelLb&quot;).style.display = &quot;none&quot;;
    document.getElementById(&quot;spinnerGetProj&quot;).style.display = &quot;block&quot;;
    document.getElementById(&#39;projectsDetaDiv&#39;).innerHTML = null;
  }

function loadFromDeta(name) {
  workspaceClear();
  var data = detaStorage.getProjectData();
  Blockly.Xml.domToWorkspace(data.xml, foo.value.workspace);
}

答案1

得分: 1

如果你真的想在Vue中手动创建元素,你需要使用render()函数。然而,虽然它有实际的应用场景,但我相信在常规的Vue风格中编写示例会更好,其中你将模板和数据操作分开,这将为你提供更干净、更容易维护的代码。

在模板中,你可以使用v-if来显示和隐藏加载动画,使用v-for来从列表创建按钮,实现与上面相同的DOM操作:

<div v-if="loading" id="spinnerGetProj"/>
<div v-else v-for="item in projects" :key="item">
  <button
    type="button"
    class="btn btn-primary mt-4"
    @click="loadFromDeta(item)"
  >{{ item }}</button>
</div>

你没有提到你使用的Vue版本,但在Vue 3的组合API中,相应的脚本部分会类似于这样:

const projects = ref([])
const loading = ref(true)

const loadProjects = async () => {
  loading.value = true
  projects.value = await detaStorage.getAllProjects()
  loading.value = false
}

就是这样。现在你只需调用loadProjects(),其他一切都会就位。希望对你有所帮助。

英文:

Oh, if you really want to create the elements manually in Vue, you need to use the render() function. However, while there are practical applications for it, I am pretty sure it would serve you better to write your example in the regular Vue style, where you separate between template and data operations, as it gives you cleaner code that is easier to maintain.

In the template, you can express the exact same DOM operations you did above, using v-if to show and hide the loading spinner and using v-for to create the buttons from the list:

&lt;div v-if=&quot;loading&quot; id=&quot;spinnerGetProj&quot;/&gt;
&lt;div v-else v-for=&quot;item in projects&quot; :key=&quot;item&quot;&gt;
  &lt;button
    type=&quot;button&quot;
    class=&quot;btn btn-primary mt-4&quot;
    @click=&quot;loadFromDeta(item)&quot;
  &gt;{ item }&lt;/button&gt;
&lt;/div&gt;

You didn't say which Vue version you are using, but in Vue 3 composition api, the corresponding script part would look something like this:

const projects = ref([])
const loading = ref(true)

const loadProjects = async() =&gt; {
  loading.value = true
  projects.value = await detaStorage.getAllProjects()
  loading.value = false
}

And that's it. Now you just have to call loadProjects(), and everything else falls into place. Hope that helps.

huangapple
  • 本文由 发表于 2023年2月14日 04:21:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75440798.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定