我的意图:
使用Vue.js(v2)属性[v-cloak],我希望拥有" app"隐藏直到准备好。删除[v-cloak]后,我想要" app"淡入。使用CSS不透明度和过渡来实现淡入淡出。
问题:
从我的" app"中移除[v-cloak]时没有像我期望的那样过渡。它立即从隐藏变为可见。似乎忽略了CSS。
示例:
我用Vue.js和一个JavaScript模拟版本做了一个夸张的例子来展示它们的行为方式。
https://codepen.io/freemagee/pen/wXqrRM
查看此示例时,您将看到" Plain old JavaScript"红框在5秒内淡入视野。但Vue控制版只是没有褪色。它们共享相同的CSS用于转换,因此理论上应该以相同的方式工作。
有效使用[v-cloak]来实现平滑过渡吗?
Codepen代码
HTML
class CategoryVC: BaseVC,JExpandableTableViewDataSource,JExpandableTableViewDelegate{
@IBOutlet weak var tblViewCategory: JExpandableTableView!
var tableViewData = [SectionInfo]()
var expandedIndexPath: IndexPath?
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Category"
self.tblViewCategory.dataSource = self
self.tblViewCategory.delegate = self
self.tblViewCategory.keepPreviousCellExpanded = false
self.LoadData()
}
func LoadData() {
var cellInfo = CellInfo("SubCategory 1",SubCount: "10")
let sec1 = SectionInfo("Category 1", SubCount: "5", Image: UIImage(named: "Category3")!)
sec1.cells.append(cellInfo)
let sec2 = SectionInfo("Category 2", SubCount: "8", Image: UIImage(named: "Category3")!)
cellInfo = CellInfo("SubCategory 2",SubCount: "20")
sec2.cells.append(cellInfo)
cellInfo = CellInfo("SubCategory 2.1",SubCount: "30")
sec2.cells.append(cellInfo)
let sec3 = SectionInfo("Category 3", SubCount: "10", Image: UIImage(named: "Category3")!)
cellInfo = CellInfo("SubCategory 3",SubCount: "30")
sec3.cells.append(cellInfo)
tableViewData.append(sec1)
tableViewData.append(sec2)
tableViewData.append(sec3)
let celNib = UINib.init(nibName: "SubCategoryCell", bundle: nil)
tblViewCategory.register(celNib, forCellReuseIdentifier: "SubCategoryCell")
let headerNib = UINib.init(nibName: "HeaderView", bundle: nil)
tblViewCategory.register(headerNib, forHeaderFooterViewReuseIdentifier: "HeaderView")
}
@IBAction func DrawerMenutap(_ sender: Any) {
self.OpenDrawerMenu()
}
func tableView(_ tableView: JExpandableTableView, numberOfRowsInSection section: Int, callback: @escaping (Int) -> Void) {
let sectionInfo = self.tableViewData[section]
callback(sectionInfo.cells.count)
}
func tableView(_ tableView: JExpandableTableView, heightForHeaderInSection section: Int) -> CGFloat {
return 150
}
func tableView(_ tableView: JExpandableTableView, heightForRowAtIndexPath indexPath: IndexPath) -> CGFloat {
return 44
}
func tableView(_ tableView: JExpandableTableView, initialNumberOfRowsInSection section: Int) -> Int {
// let sectionInfo = self.tableViewData[section]
return 0
}
func numberOfSections(in tableView: JExpandableTableView) -> Int {
return tableViewData.count
}
func tableView(_ tableView: JExpandableTableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let section = tableViewData[indexPath.section]
let row = section.cells[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "SubCategoryCell", for: indexPath) as! SubCategoryCell
cell.contentView.backgroundColor = UIColor.white
cell.lblSubCategoryName.text = row.SubcategoryName
return cell
}
func tableView(_ tableView: JExpandableTableView, viewForHeaderInSection section: Int) -> UIView? {
let section = self.tableViewData[section]
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderView") as! HeaderView
header.contentView.backgroundColor = UIColor.groupTableViewBackground
header.CatName.text = section.CategoryName
header.CatImgView.image = UIImage(named: "Category4")
header.CatCount.text = section.CategoryCount
return header
}
}
//MARK: Table View Cell for Category
class CatCell: UITableViewCell {
@IBOutlet weak var lblName: UILabel!
}
CSS
<div id="app" v-cloak>
<div class="red-box"></div>
<p>Vue.js {{ message }}</p>
</div>
<div id="app2" v-cloak>
<div class="red-box"></div>
<p>Plain old JavaScript</p>
</div>
JS
html,
body {
margin: 0;
height: 100%;
min-height: 100%;
}
[v-cloak] .red-box {
opacity: 0;
visibility: hidden;
transition: visibility 0s 5s, opacity 5s linear;
}
#app,
#app2{
padding-top: 50px;
}
.red-box {
margin: 0 auto;
width: 100px;
height: 100px;
background: red;
opacity: 1;
visibility: visible;
transition: opacity 5s linear;
}
p {
text-align: center;
}
答案 0 :(得分:3)
这不会起作用,因为在Vue应用实例初始化之后, #app
div实际上被移除,重新渲染并变成另一个div ,即使它看起来像相同。这可能是由于Vue的虚拟DOM机制。
在#app2
之后,document.getElementById("app2").removeAttribute("v-cloak");
元素仍然是相同的DOM:https://codepen.io/jacobgoh101/pen/PaKQwV
#app
元素是new Vue(...)
之后的另一个DOM:https://codepen.io/jacobgoh101/pen/ERvojx?editors=0010
对于Vue应用,删除了带有v-cloak
的元素,添加了另一个没有v-cloak
的元素。 没有元素从&#34;过渡到v-cloak
&#34;到没有v-cloak
&#34; 这就是为什么CSS过渡不起作用的原因。希望这很清楚。
(如果您还不知道这一点,)您可以使用Transition Component
答案 1 :(得分:1)
如前所述,[v-cloak]无法进行转换,因为没有v-cloak的DOM元素是新的。
我想出了一个简单的解决方法,使用mounted方法及其钩子vm。$ nextTick(),在这种情况下,不再需要使用v-cloak。
当将原始app元素替换为Vue生成的新元素时,会调用Mounted,但这并不一定意味着每个孩子都已经被渲染。当每个子元素都已在应用视图中呈现后,将调用nextTick。
首先,我已经这样设置了HTML应用程序元素:
<div id="main-view" :class="{ready: isPageReady}">...</div>
在我的Vue应用中:
new Vue({
el: "#main-view",
data: {
isPageReady: false,
[...]
mounted: function() {
this.$nextTick(function () {
this.isPageReady = true;
});
}
});
最后在CSS中,我尝试使用不透明性进行简单的fading:
#main-view {
opacity: 0;
}
#main-view.ready {
opacity: 1;
transition: opacity 300ms ease-in-out;
}
当心:如果您打开了浏览器的检查器/调试器,则转换不会总是显示。