Vue组件之全局组件与局部组件

举报
tea_year 发表于 2021/12/29 23:05:04 2021/12/29
【摘要】 组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。个人认为就是一个可以重复利用的结构层代码片段。 全局组件注册方式:Vue.co...

      组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。个人认为就是一个可以重复利用的结构层代码片段。
      全局组件注册方式:Vue.component(组件名,{方法})
      eg:
      <body>
      <div id="app">
      <my-component></my-component>
      </div>
      <div id="app1">
         <my-component></my-component>
      </div>
      <script>
      Vue.component("my-component",{
         template:"<h1>我是全局组件</h1>"
      });
      new Vue({
         el:"#app"
      });
      new Vue({
         el:"#app1"
      })
      </script>
      </body>
      渲染结果:
      <div id="app">
         <h1>我是全局组件</h1>
      </div>
      <div id="app1">
         <h1>我是全局组件</h1>
      </div>
      这里需要注意:
      1.全局组件必须写在Vue实例创建之前,才在该根元素下面生效;
      eg:
      <body>
      <div id="app">
         <my-component></my-component>
      </div>
      <div id="app1">
         <my-component></my-component>
      </div>
      <script>
         new Vue({
             el: "#app"
          });
         Vue.component("my-component", {
             template: "<h1>我是全局组件</h1>"
          });
         new Vue({
             el: "#app1"
          })
      </script>
      </body>
      这样只会渲染app1根元素下面的,并不会渲染app根元素下面的,并且会报错。
      2.模板里面第一级只能有一个标签,不能并行;
      <body>
      <div id="app">
         <my-component></my-component>
      </div>
      <script>
         new Vue({
             el: "#app"
          });
         Vue.component("my-component", {
             template: "<h1>我是全局组件</h1>" +
             "<p>我是全局组件内标签</p>"
          });
         new Vue({
             el: "#app1"
          })
      </script>
      </body>
      这样子会报错,并且只会渲染第一个标签h1;我们应该这样子写:
      <body>
      <div id="app">
         <my-component></my-component>
      </div>
      <script>
         new Vue({
             el: "#app"
          });
         Vue.component("my-component", {
             template: "<h1>我是全局组件<p>" +
             "我是全局组件内标签</p></h1>"
          });
         new Vue({
             el: "#app1"
          })
      </script>
      </body>
      局部组件注册方式,直接在Vue实例里面注册
      eg:
      <body>
      <div id="app1">
         <child-component></child-component>
      </div>
      <script>
         new Vue({
             el: "#app1",
             components:{
                 "child-component":{
                     template:"<h1>我是局部组件</h1>"
                  }
              }
          });
      </script>
      局部组件需要注意:
      1.属性名为components,s千万别忘了;
      2.套路比较深,所以建议模板定义在一个全局变量里,代码看起来容易一点,如下:(模板标签比较多的时候,这样子写更加简洁规整)
      <body>
      <div id="app1">
         <child-component></child-component>
      </div>
      <script>
         var child={
             template:"<h1>我是局部组件</h1>"
          };
         new Vue({
             el: "#app1",
             components:{
                 "child-component":child
              }
          });
      </script>
      </body>
      关于组件中的其他属性,可以和实例中的一样,但是data属性必须是一个函数:
      eg:
      <body>
      <div id="app1">
         <child-component></child-component>
      </div>
      <script>
         var child={
             template:"<button @click='add2'>我是局部组件:{{m2}}</button>",
             data:function(){
                 return {m2:1}
              },
             methods:{
                 add2:function(){
                     this.m2++
                  }
              }
          };
         new Vue({
             el: "#app1",
             components:{
                 "child-component":child
              }
          })
      </script>
      </body>
      显示结果:
      clipboard.png
      全局组件和局部组件一样,data也必须是一个函数:
      <body>
      <div id="app1">
         <my-component></my-component>
      </div>
      <script>
         Vue.component("my-component",{
             template:"<button @click='add1'>全局组件:{{m1}}</button>",
             data:function(){
                 return {
                     m1:10
                  }
              },
             methods:{
                 add1:function(){
                     this.m1++
                  }
              }
          });
         new Vue({
             el:"#app1"
          })
      </script>
      </body>
      显示结果:
      clipboard.png
      当使用 DOM 作为模板时 (例如,将 el 选项挂载到一个已存在的元素上),你会受到 HTML 的一些限制,因为 Vue 只有在浏览器解析和标准化 HTML 后才能获取模板内容。尤其像这些元素 <ul><ol><table><select> 限制了能被它包裹的元素,而一些像<option> 这样的元素只能出现在某些其它元素内部。
      自定义组件 <my-row> 被认为是无效的内容,因此在渲染的时候会导致错误。变通的方案是使用特殊的 is 属性:
      eg:
      <body>
      <div id="app1">
      <ul>
         <li is="my-component"></li>
      </ul>
      </div>
      <script>
      Vue.component("my-component",{
          template:"<h1>{{message}}</h1>",
          data:function(){
              return {
                  message:"hello world"
               }
           }
       });
      new Vue({
          el:"#app1"
       })
      </script>
      </body>
      渲染结果为:
      clipboard.png
      对于全局与局部的作用域问题,我们可以这样理解,只要变量是在组件内部用的,这些变量必须是组件内部的,而在外部html结构中引用的变量,都引用的是该挂载下的实例里面的变量
      eg:
      <body>
      <div id="app1">
      <my-component></my-component>
      </div>
      <script>
      Vue.component("my-component",{
          template:"<button @click='add3'>" +
          "{{message}}</button>",
          data:function(){
              return {
                  message:"hello world"
               }
           },
          methods:{
              add3:function(){
                  alert("我是局部")
               }
           }
       });
      new Vue({
          el:"#app1",
          methods:{
              add3:function(){
                  alert("我是全局")
               }
           }
       })
      </script>
      </body>
      弹出框显示:我是局部
      Vue中所谓的全局指的是该挂载下的区域;
      下面这种做法是错误的,按我的想法觉得应该会弹出:我是全局,但是却报错,也就是说组件处于全局下不可以添加默认事件,要用全局的事件函数,必须父子通信
      <body>
      <div id="app1">
      <my-component @click="add3"></my-component>
      </div>
      <script>
      Vue.component("my-component",{
          template:"<button @click='add3'>" +
          "{{message}}</button>",
          data:function(){
              return {
                  message:"hello world"
               }
           }
       });
      new Vue({
          el:"#app1",
          methods:{
              add3:function(){
                  alert("我是全局")
               }
           }
       })
      </script>
      </body>
      额外话题:
      1.函数return后面必须跟返回的内容,不能换行写
      eg:
      clipboard.png
      下面这种写法不会返值回来:
      clipboard.png
      2.Vue和小程序等一样,采用es6的函数写法,this指向是不一样的
      <body>
      <div id="app1">
         <button @click="f">ES5</button>
         <button @click="f1">ES6</button>
      </div>
      <script>
      new Vue({
         el:"#app1",
         methods:{
             f:function(){
               console.log(this)
              },
             f1:()=>{
                 console.log(this)
              }
          }
      })
      </script>
      </body>
      结果:
      第一个this指的是Vue实例
      第二个this指的是Window
      clipboard.png
      由于它和小程序不一样,我发现在data里面this指的是window,在methods里面this才是Vue实例
      所以建议大家用es5写吧
      new Vue({
          el:"#app1",
          data:{that:this},
      })
      clipboard.png
  
 

 

文章来源: aaaedu.blog.csdn.net,作者:tea_year,版权归原作者所有,如需转载,请联系作者。

原文链接:aaaedu.blog.csdn.net/article/details/86573232

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。