【问题标题】:How do I hide the VueJS syntax while the page is loading?如何在页面加载时隐藏 VueJS 语法?
【发布时间】:2016-07-11 06:07:26
【问题描述】:

也许这是一个微不足道的问题。

所以,当我在浏览器上运行我的 vuejs 应用程序并启用限制下载速度(设置为低连接)时。我在浏览器中得到了未完成的 vue 语法输出。

我知道我们可以通过在整个页面加载之前显示加载图像来解决这个问题,但是有没有最好的解决方案来解决这个问题?

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    将所有内容放在 <template> 中对我来说效果很好。

    内容在被 Vue 渲染之前是隐藏的。

    <!-- index.html -->
    <div id="app">
      <template>
        <span class="name">{{ name.first }} {{ name.last }}</span>
      </template>
    </div>
    
    /* index.js */
    new Vue({
      el: '#app',
      data: {
        name: { first: 'David', last: 'Davidovich'}
      }
    });
    

    【讨论】:

    • 这个技巧对我的用例来说已经足够了,谢谢!
    【解决方案2】:

    您可以使用 v-cloak 指令,如果您将其与正确的 CSS 结合使用,它将隐藏 Vue 实例直到编译完成。

    HTML:

    <div v-cloak>{{ message }}</div>
    

    CSS:

    [v-cloak] { display: none; }
    

    【讨论】:

    • 在 api 中说:[v-cloak] { display: none; } &lt;div v-cloak&gt; {{ message }} &lt;/div&gt; 这意味着,我应该在我希望隐藏的每个元素中添加 v-cloak 属性?
    • 只到主要的App div 应该没问题
    • 这行得通,但它很笨重。我真的希望有更优雅的东西。 +1 虽然
    • 似乎v-cloak 应该是默认值,如果有人真的想显示{{ }},他们应该使用v-uncloak 之类的东西。
    • display:none 在现有的 HTML 上,对 SEO 来说是一个坏标志。我认为在页面加载之前使用某种覆盖可能会更好。
    【解决方案3】:

    我更喜欢使用 v-if 和一个计算属性来检查我的数据是否准备好,如下所示:

    <template>
        <div v-if="shouldDisplay">
            {{ variableName }}
        </div>
        <div v-else>
          Here you can insert a loader
        </div>
    </template>
    <script>
    export default {
        name: 'Test',
        data() {
            return {
                variableName: null,
            };
        },
        computed() {
            shouldDisplay() {
                return this.variableName !== null;
            }
        },
        mounted() {
            this.variableName = 'yes';
        },
    };
    </script>
    

    通过这种方式,只有在数据未准备好时才显示加载器更容易(使用v-else)。

    在这种特殊情况下,v-if="variableName" 也可以工作,但可能会有更复杂的情况。

    【讨论】:

    • 这适用于页面脚本加载和 vue 安装后。这也是一个预编译的组件。 OP 指的是在运行时编译的页面,浏览器首先加载该页面。如果您的脚本加载缓慢,那么您会在短时间内看到 vue 语法。
    【解决方案4】:

    对于那些在具有多个 Laravel Blade 文件的视图中使用 v-cloak 并且它不起作用的人,请尝试在父刀片文件而不是任何子刀片文件中使用 v-cloak。

    【讨论】:

      【解决方案5】:

      不要在 HTML 文件中包含任何 vuejs 语法:

      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width,initial-scale=1.0">
          <title>My Super app</title>
        </head>
        <body>
          <div id="app"></div>
          <script src="/app.js"></script>
        </body>
      </html>
      

      在您的主 JavaScript 中,您可以:

      import Vue from 'vue'
      import App from './App'
      
      new Vue({
        el: '#app',
        components: { App },
        template: '<App/>'
      })
      

      请参阅vuetify webpack template 以供参考。

      另一种解决方案是使用:

      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width,initial-scale=1.0">
          <title>My Super app</title>
        </head>
        <body>
          <div id="app" is="App"></div>
          <script src="/app.js"></script>
        </body>
      </html>
      

      与:

      import Vue from 'vue'
      import App from './App'
      Vue.component("App", App);
      
      const app = new Vue({});
      
      window.addEventListener("load", async () => {    
        app.$mount("#app")
      })
      

      【讨论】:

        【解决方案6】:
        **html**
        <div v-cloak>{{ message }}</div>
        
        **css**
        [v-cloak] { display: none; }
        

        【讨论】:

          【解决方案7】:

          使用 v-cloak 指令,您可以隐藏未编译的 mustache 绑定,直到 vue 实例编译完成。在编译之前,您必须使用 CSS 块隐藏它。

          HTML:

          <div v-cloak>
            {{ vueVariable }}
          </div>
          

          CSS:

          [v-cloak] {
            display: none;
          }
          

          在编译完成之前,这个&lt;div&gt; 将不可见。

          您可以查看此链接Hide elements during loading using v-cloak 以获得更好的理解。

          【讨论】:

            【解决方案8】:

            是的,你可以使用v-cloak,我喜欢使用spinkit,它是一个非常棒的库,只有 CSS,看一个简单的例子:

            var vm = null;
                setTimeout(function() {
                	vm = new Vue({
                     el: '#app',
                    data: {
                      msg: 'Is great, using: ',
                      url: 'http://tobiasahlin.com/spinkit/'
                     }
                  });
                 }, 3000);
            #app .sk-rotating-plane,
            [v-cloak] > * { display:none }
            body{
            	background: #42b983;
            	color: #35495e;
            }
            #app[v-cloak] .sk-rotating-plane {
            	display:block;
            	background-color: #35495e;
            }
            <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
            
            <link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/tobiasahlin/SpinKit/master/css/spinkit.css">
            
            
            <div id="app" v-cloak>
                <div class="sk-rotating-plane"></div>
                <h1>Vue with c-cloak</h1>
              <p>
                {{ msg }}
                <a :href='url'>{{ url }}</a>
              <p>
            </div>

            链接: - http://tobiasahlin.com/spinkit/

            【讨论】:

              【解决方案9】:

              在将数据绑定到相关位置之前,使用&lt;v-cloak&gt; 隐藏您的 Vue 代码。它实际上位于 Vue 文档中的某个位置,除非您搜索或仔细阅读,否则任何人都可能会错过它。

              【讨论】:

                【解决方案10】:

                正如其他人所建议的那样,使用v-cloak 是正确的解决方案。然而,正如@DelightedD0D 提到的那样,它很笨重。简单的解决方案是在v-cloak 指令的伪选择器::before 中添加一些CSS。

                在您的 sass/less 文件中,类似于

                [v-cloak] > * { display:none; }
                [v-cloak]::before {
                  content: " ";
                  display: block;
                  position: absolute;
                  width: 80px;
                  height: 80px;
                  background-image: url(/images/svg/loader.svg);
                  background-size: cover;
                  left: 50%;
                  top: 50%;
                }
                

                当然,您需要提供有效且可访问的加载器图像路径。它会呈现类似的东西。

                希望对你有帮助。

                【讨论】:

                  【解决方案11】:

                  您可以将任何渲染移动到一个简单的包装器 component。 VueJS 初始化,例如new Vue(....) 不应包含除该单个包装器组件之外的任何 HTML。

                  根据设置,您甚至可以使用 &lt;app&gt;Loading...&lt;/app&gt;,其中 app 是包装组件,其中包含任何加载 HTML 或文本,然后在加载时替换。

                  【讨论】:

                    【解决方案12】:

                    我附上了以下代码笔。你可以看到有和没有v-cloak的区别。

                    <div id="js-app">
                    [regular]Hold it... <span>{{test}}</span><br/>
                    [cloak]Hold it... <span v-cloak>{{test}}</span>
                    </div>
                    

                    http://codepen.io/gurghet/pen/PNLQwy

                    【讨论】:

                    • 是的,我明白了...谢谢,您的 codepen 将对新来者有所帮助。
                    • 在加载 vuejs 时你仍然会得到第一个 {{test}},所以它不是一个完美的答案
                    • @twigg 这就是重点。第一个显示常规标记,第二个显示使用v-cloak 属性的隐藏标记。
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多