Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 实现v-loading指令,在加载数据时替换内容_Typescript_Vuejs2_Directive - Fatal编程技术网

Typescript 实现v-loading指令,在加载数据时替换内容

Typescript 实现v-loading指令,在加载数据时替换内容,typescript,vuejs2,directive,Typescript,Vuejs2,Directive,我试图在Vue中实现一个v-loading指令,在该指令中,当表达式求值为true时,元素的内容被一个微调器替换 它的用法如下: <div v-loading="loading"> <p v-if="!data"> No data </p> <p v-else>Here is the data: {{data}}</p> </div> 但我宁愿得到指令。不幸的是,我对vue框架和VNode的了解还不够,VNode上

我试图在Vue中实现一个
v-loading
指令,在该指令中,当表达式求值为true时,元素的内容被一个微调器替换

它的用法如下:

<div v-loading="loading">
  <p v-if="!data"> No data </p>
  <p v-else>Here is the data: {{data}}</p>
</div>
但我宁愿得到指令。不幸的是,我对vue框架和VNode的了解还不够,VNode上API的文档重定向到,没有太多信息

有什么想法吗

检查,您的指令破坏了
el
,因此除非
重新装载
(再次编译模板),否则它将无法正确呈现

以下是两种解决方案:

解决方案1:可以附加一个元素以显示微调器,然后隐藏其其他子元素

Vue.config.productionTip=false
让vMyDirective={}
vMyDirective.install=函数安装(_Vue){
让_uid='vue指令加载'+Date.now().toString('16'))
_Vue.指令('加载'{
插入:功能(el,绑定){
设spinner=document.createElement('span'))
spinner.id=\u uid
spinner.innerHTML='正在加载…'
spinner.style.display=binding.value?'block':'none'
spinner.style['background-color']='red'
微调器。左=0
spinner.top=0
spinner.style.position='absolute'
el.childNodes.forEach((项目)=>{
item.style.display=binding.value?“无”:”
})
el.appendChild(微调器)
},
更新:函数(el、绑定、vnode){
让微调器=document.getElementById(\u uid)
spinner.style.display=binding.value?'block':'none'
el.childNodes.forEach((项目)=>{
如果(item.id===\u uid)返回
item.style.display=binding.value?“无”:”
})
}
})
}
Vue.use(vMyDirective)
新Vue({
el:“#应用程序”,
数据(){
返回{
加载:对,
数据集:“”
}
},
方法:{
toggleLoading:function(){
this.loading=!this.loading
},
AddData:函数(){
this.dataset=this.dataset+'a'
}
}
})

切换加载{{Loading}
添加数据

无数据

以下是数据:{{dataset}


非常感谢您提供完整的答案!只是一个问题:为什么要更改vnode.key,以及针对修改vnode的警告在哪里?@coyotte508当密钥更改(或)时,Vue将重新装载它。然后,对于第二个问题,选中,
除了el之外,您应该将这些参数视为只读参数,并且永远不要修改它们。如果您需要跨钩子共享信息,建议通过元素的数据集进行共享。
@coyotte508您可以将
console.log('something')
添加到hook='update'和'bind'中,您会发现一旦在hook='update'中更改了键,它将再次绑定。如果注释掉
vnode.key+=“1”
,它将只触发hook='update'。
import Vue from 'vue';

Vue.directive('loading', {
  bind(el: HTMLElement, binding: any, vnode: any) {
    console.log(vnode);
    // console.log(this, arguments);
    vnode.data.html = el.innerHTML;
    vnode.data.loading = binding.value;

    if (binding.value) {
      el.innerHTML = `<i class='fa fa-spin fa-spinner'></i>`;
    } else {
      el.innerHTML = vnode.data.html;
    }
  },

  update(el: HTMLElement, binding: any, vnode: any, oldVnode: any) {
    console.log(el.innerHTML);
    // console.log("update", this, arguments);

    if (binding.value) {
      el.innerHTML = `<i class='fa fa-spin fa-spinner'></i>`;
    } else {
      el.innerHTML = oldVnode.data.html;
    }

    vnode.data.html = oldVnode.data.html;
    vnode.data.loading = binding.value;
  }
});
<template>
  <div>
    <slot v-if="!loading"></slot>
    <i v-else class="fa fa-spin fa-spinner"></i>
  </div>
</template>