Vue.js [v-cloak]不使用CSS过渡

时间:2018-06-14 14:19:22

标签: javascript html css vue.js

我的意图:

使用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;
}

2 个答案:

答案 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;
}

当心:如果您打开了浏览器的检查器/调试器,则转换不会总是显示。