我是VueJS的新手。我正在使用VueJS和Bootstrap开发应用程序。我希望根据条件渲染一个div。
我一直在尝试在div上使用v-if
,以便一旦条件为true,就将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"></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()方法时,我可以看到div在DOM上呈现。
但是,当我尝试通过其ID获取元素时,结果为null。因此,document.getElementById('details')
返回null。
我认为这与Vue中的反应性以及v-if的工作方式有关。有人可以帮我解决这个问题吗?
谢谢!
答案 0 :(得分: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>
答案 1 :(得分: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");
})
}
}