无法使用v-if获取元素的id

问题描述 投票:0回答:2

我是VueJS的新手。我正在使用VueJS和Bootstrap开发一个应用程序。我希望根据条件渲染一个div。

我一直试图在div上使用v-if,这样一旦条件成立,data属性设置为true并显示div。

我的代码看起来像这样:

export default {
    
    data(){
      
      return {

        detailsSectionOpen: false
        
      }
   },
   
   methods:{
   
    showDetails() {
        if(this.detailsSectionOpen === false){
           this.detailsSectionOpen = true;
        }
        const detailsSection = document.getElementById("details");
        const showSection = document.getElementById("show");
        detailsSection.classList.add("col-xl-3");
        showSection.classList.add("col-xl-9", "col-md-6");
        showSection.classList.remove("col-xl-12", "col-md-6");
      },
   
   }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="content" style="padding-top: 3px;">
    <div class="row">
      <div class="col-xl-12 col-md-6" id="show" style="padding-left: 0px;padding-right: 0px;">

        <div class="container-fluid">

          <ol class="breadcrumb" id="topButtons" style="display: flex;width: 100%;padding: 0rem 1rem;background-color: transparent;margin-bottom: 0px;">
            <li class="breadcrumb-item active" style="margin-right: auto; margin-left: 0px; padding-top: 13px; color: #424242; 
                font-family: 'Source Sans Pro'; 
                font-size: 18px; 
                font-weight: normal; 
                font-style: normal; 
                text-decoration: none; 
                text-align: left;">Files</li> 
            <li class="pull-right">
              <button class="btn">
                <i class="fa fa-sort-amount-asc">
                </i>
              </button>
            </li> 
            <li class="pull-right">
              <button v-if="gridView === false" @click="changeView" class="btn">
                <i class="fa fa-th-large"></i>
              </button>
              <button v-if="gridView === true" @click="changeView" class="btn">
                <i class="fa fa-list-ul">
                </i>
              </button>
            </li> 
            
          </ol>

          <!-- Line break -->
          <hr class="breadcrumb-hr">

        </div>

      <div class="container-fluid">
        <div style="width: 280px; height: 30px; margin-left: 15px; ">
          <p style="color: #424242; font-family: 'Source Sans Pro'; font-size: 16px; font-weight: bold; font-style: normal; text-decoration: none; text-align: left;">Recent</p>
        </div>

        <!-- Recently used files section begins here -->
        <div class="row" style="padding-right: 15px; padding-left: 15px;">
          
          <div class="col-md-5ths col-xs-6" v-for="(file,index) in recentFiles">
            <stats-card>
              <div slot="header" class="header-rectangle" @contextmenu.prevent="$refs.menu.open">
                <img :src="file.source" style=" height: 50px; margin-top: 50px">
              </div>
              <div slot="footer" class="footer-rectangle" @contextmenu.prevent="$refs.menu.open" style="display: flex; flex-direction: column; justify-content: center;">
                <div class="row" >
                  <div class="col-xl-9"  style="display: flex;flex-direction: column;justify-content: center;">
                    <div class="file-name-style">
                        <span>{{file.name}}</span>
                    </div>
                    <div class="file-size-style" >
                      <span>{{file.size}} MB</span>
                    </div>
                  </div>
                  <div class="col-xl-3" style="display: flex; flex-direction: column; justify-content: center; margin-top:">
                    <div v-show="!file.shared" style="float: right; padding: 0px 5px 5px 0px; margin-right: 10px;">
                      <i class='fas fa-users' id="image"></i>
                    </div>
                  </div>
                </div>
              </div>
            </stats-card>
          </div>

          <vue-context ref="menu">
            <ul style="font-family: 'Source Sans Pro'; font-size: 15px; font-weight: normal; font-style: normal; text-decoration: none; text-align: left; ">
              <li class="context-menu-item" @click="onClick($event.target.innerText)"><i class='fa fa-file' id="context-menu-icon"></i><span class="context-menu-span">Preview</span></li>
              <li class="context-menu-item" @click="onClick($event.target.innerText)"><i class="fa fa-share-alt" id="context-menu-icon"></i><span class="context-menu-span">Share</span></li>
              <li class="context-menu-item" @click="onClick($event.target.innerText)"><i class="fa fa-copy" id="context-menu-icon"></i><span class="context-menu-span">Copy/Move</span></li>
              <li class="context-menu-item" @click="onClick($event.target.innerText)"><i class='far fa-star' id="context-menu-icon"></i><span class="context-menu-span">Add to Starred</span></li>
              <li class="context-menu-item" @click="onClick($event.target.innerText)"><i class='fas fa-cloud-download-alt' id="context-menu-icon"></i><span class="context-menu-span">Download</span></li>
              <li class="context-menu-item" @click="onClick($event.target.innerText)"><i class='fas fa-pencil-alt' id="context-menu-icon"></i><span class="context-menu-span">Rename</span></li>
              <li class="context-menu-item" @click="onClick($event.target.innerText)"><i class='fas fa-tag' id="context-menu-icon"></i><span class="context-menu-span">Tags</span></li>
              <li class="context-menu-item" @click="onClick($event.target.innerText)"><i class="far fa-trash-alt" id="context-menu-icon"></i><span class="context-menu-span">Delete</span></li>
              <li class="context-menu-item" @click="onClick($event.target.innerText)"><i class="far fa-chart-bar" id="context-menu-icon"></i><span class="context-menu-span">Access Stats</span></li>
            </ul>
          </vue-context>

        </div>

        <!-- Folder section begins here -->
        <div v-if="gridView === true" style="width: 280px; height: 30px; margin-left: 15px;">
          <p style="color: #424242; font-family: 'Source Sans Pro'; font-size: 16px; font-weight: bold; font-style: normal; text-decoration: none; text-align: left;">Folders</p>
        </div>

        <div v-if="gridView === true" class="row seven-cols" style="padding-right: 15px; padding-left: 15px;">
          <div class="col-md-1" id="no-padding" v-for="(folder,index) in folders">
            <stats-card>
              <div slot="header" :data-key="index" class="folder-rectangle" @click="folderSelected=index" :class="{'folder-selected':folderSelected==index}">
                <div class="row">
                  <div class="col-xl-3" style="padding-right: 15px;padding-left: 15px;">
                    <div class="clearfix" v-if="folder.shared" style="margin-top: 8px; margin-left: 10px;">
                      <i class="material-icons" id="folder-image">&#xe2c9;</i>
                    </div>
                    <div class="clearfix" style="margin-top: 8px; margin-left: 10px;" v-else>
                      <i class="material-icons" id="folder-image">folder</i>
                    </div>
                  </div>
                  <div class="col-xl-9" style="padding-left: 7px;padding-right: 7px;padding-top: 7px;padding-bottom: 7px;">
                    
                      <div class="file-name-style" style="padding-right: 5px; padding-left: 5px;">
                        <span>{{folder.name}}</span>
                      </div>
                      <div class="file-size-style" style="padding-bottom: 5px;padding-top: 10px;padding-left: 5px;">
                        <span>{{folder.numFiles}} files</span>
                      </div>
                    </div>
                  </div>
                </div>
              
            </stats-card>
          </div>
        </div>


        <!-- Files section begins here -->
        <div v-if="gridView === true" style="width: 280px; height: 30px; margin-left: 15px;">
          <p style="color: #424242; font-family: 'Source Sans Pro'; font-size: 16px; font-weight: bold; font-style: normal; text-decoration: none; text-align: left;">Files</p>
        </div>

        <div v-if="gridView === true" class="row" style="padding-bottom: 15px; margin-bottom: 20px; padding-right: 15px; padding-left: 15px;">

          <div class="col-md-5ths col-xs-6">
            <stats-card>
              <div slot="header" class="header-rectangle">
                <img src="https://image.flaticon.com/icons/png/512/136/136526.png" style="height: 50px; margin-top: 50px">
              </div>
              <div slot="footer" class="footer-rectangle" style="display: flex;
                flex-direction: column;
                justify-content: center;">
                <div class="row" >
                  <div class="col-xl-12"  style="display: flex;flex-direction: column;justify-content: center;">
                    <div class="file-name-style">
                        <span>File Name</span>
                    </div>
                    <div class="file-size-style" >
                      <span>1 MB</span>
                    </div>
                  </div>
                  
                </div>
              </div>
            </stats-card>
          </div>

          <div class="col-md-5ths col-xs-6">
            <stats-card>
              <div slot="header" class="header-rectangle">
                <i class="far fa-file-image" style=" height: 50px; margin-top: 50px; color:#4CAF50; font-size: 40px;"></i>
              </div>
              <div slot="footer" class="footer-rectangle" style="display: flex;
                flex-direction: column;
                justify-content: center;">
                <div class="row" >
                  <div class="col-xl-12"  style="display: flex;flex-direction: column;justify-content: center;">
                    <div class="file-name-style">
                        <span>File Name</span>
                    </div>
                    <div class="file-size-style" >
                      <span>1 MB</span>
                    </div>
                  </div>
                  
                </div>
              </div>
            </stats-card>
          </div>


          <div class="col-md-5ths col-xs-6">
            <stats-card>
              <div slot="header" class="header-rectangle">
                <img src="http://www.dap.asn.au/wp-content/uploads/2017/01/pdfLogo.png" style=" height: 50px; margin-top: 50px;">
              </div>
              <div slot="footer" class="footer-rectangle" style="display: flex;
                flex-direction: column;
                justify-content: center;">
                <div class="row" >
                  <div class="col-xl-12"  style="display: flex;flex-direction: column;justify-content: center;">
                    <div class="file-name-style">
                        <span>File Name</span>
                    </div>
                    <div class="file-size-style" >
                      <span>1 MB</span>
                    </div>
                  </div>
                  
                </div>
              </div>
            </stats-card>
          </div>

          <div class="col-md-5ths col-xs-6">
            <stats-card>
              <div slot="header" class="header-rectangle">
                <img src="https://www.cleverducks.com/wp-content/uploads/2018/01/Excel-Icon.png" style="height: 50px; margin-top: 50px">
              </div>
              <div slot="footer" class="footer-rectangle" style="display: flex;
                flex-direction: column;
                justify-content: center;">
                <div class="row" >
                  <div class="col-xl-12"  style="display: flex;flex-direction: column;justify-content: center;">
                    <div class="file-name-style">
                        <span>File Name</span>
                    </div>
                    <div class="file-size-style" >
                      <span>1 MB</span>
                    </div>
                  </div>
                  
                </div>
              </div>
            </stats-card>
          </div>  
        </div>

        <!-- List View section begins here -->
        <list-view :gridView="gridView" :folders="folders">

        </list-view>
        
      </div>
    </div>

    <!-- File Details section begins here -->
    <div v-if="detailsSectionOpen" id="details" ref="detailsSection">
      <div class="content">
        <div class="container-fluid">
          <ol class="breadcrumb" id="topButtons" style="display: flex;width: 100%;padding: 0rem 1rem;background-color: transparent;margin-bottom: 0px;">
            <li class="pull-right">
              <button class="btn" @click="closeDetailsSection">
                <i class="fa fa-close">
                </i>
              </button>
            </li>
          </ol>

          <!-- Line break -->
          <hr class="breadcrumb-hr-details">
        </div>

        <div class="container-fluid">
          <div style="width: 280px; height: 30px;">
            <p style="color: #424242;width: 239px;height: 30px;font-family: 'Source Sans Pro'; font-size: 16px; 
                      font-weight: bold; 
                      font-style: normal; 
                      text-decoration: none; 
                      text-align: left;">Details</p>
          </div>
          <div class="row">
            <div class="col">
              <div style="height: 100px; width: 100px; margin: 0 auto" >
                <i class="fas fa-folder" style="font-size: 100px; color: #878D99"></i>
              </div>
              <div style="max-width: 100%;">
                <ul style="list-style: none;padding-left: 20px;padding-right: 20px; padding-top: 60px;padding-bottom: 60px;" class="details-ul">
                  <li>Shared with: ~ 15 people</li>
                  <li>Name: Folder Name</li>
                  <li>Type: Folder</li>
                  <li>Files: 20</li>
                  <li>Location: Home</li>
                  <li>Owner: John</li>
                  <li>Created: March 10, 2018</li>
                  <li>Opened: March 10, 2018, 7 PM by Jenny</li>
                  <li>Modified: March 10, 2018, by me</li>
                  <li>Downloaded: March 10, 2018, by John </li>
                  <li>Retention Policy:  None</li>
                  <li>Tags: Add</li>
                  <li>Description: Add</li>
                </ul>
              </div>
              <div style="height: 100px; width: 100px; margin: 0 auto" >
                <button class="plus-circle-btn"><i class="fa fa-plus-circle"></i></button>
              </div>
            </div>
          </div>
        </div>
        </div>
      </div>
    </div>

  </div>

当调用方法showDetails()时,我能够看到在DOM上呈现的div。

但是,当我尝试通过其ID获取元素时,结果为null。所以,document.getElementById('details')返回null。

我认为它与Vue中的反应性以及v-if如何工作有关。有人可以帮我解决这个问题吗?

谢谢!

javascript html css vue.js vuejs2
2个回答
2
投票

v-if添加/删除DOM中的元素。您无法显示或隐藏DOM中不存在的内容。

试图隐藏或显示基于不同元素的v-if的另一个DOM元素没有任何意义,因为你可以简单地添加另一个v-if="condition",它将以相同的方式工作。

如果你真的无法在DOM中添加另一个检查,那么你应该在VUE中观察相同的数据元素,即if正在观看...

通过添加一个类来做到这一点,因为对于切换更好,因为ID只应该在每页使用一次。您可以根据Vue状态在DOM中的任何位置添加此类。

<div v-if="visibleCheck">
  This element will be visible if visibleCheck = true
</div>

<div id="anotherElement" v-bind:class="visibleCheck ? 'isVisble' : 'notVisible'">
 If visibleCheck = true this div will have a class .isVisible
 If visibleCheck = false/null this div will have a class .notVisible
</div>

然后对这些类做一些事情:

.isVisible {
 display:block;
}
.notVisible {
 display:none;
}

Vue的重点不是要观察DOM的变化,而是要根据数据的DOM变化

使用你的例子:

<div id="whatever" v-bind:class="detailsSectionOpen ? 'col-xl-9' : 'col-xl-12'">
   stuff
</div>

0
投票

您可以尝试使用$nextTick,它将在组件重新渲染后调用:

showDetails() {
     if(this.detailsSectionOpen === false){
        this.detailsSectionOpen = true;
     }
     this.$nextTick(() => {
       const detailsSection = document.getElementById("details");
       const showSection = document.getElementById("show");
       detailsSection.classList.add("col-xl-3");
       showSection.classList.add("col-xl-9", "col-md-6");
       showSection.classList.remove("col-xl-12", "col-md-6");
     })
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.