Vue注册组件

24 篇文章 0 订阅
15 篇文章 0 订阅

Vue注册组件

注册组件,关键字:component()有两个参数

  1. 第一个参数:新组件的名称(字符串类型)组件名定义时可以使用驼峰命名,但是使用时必须是用“-”来连接

  2. 第二个参数:回调函数(写Vue的代码)

    自定义组件是可以复用多个的,但是都是双标签,不建议使用单标签的形式
     <div id="app">
            <itme-li></itme-li>
            <itme-li></itme-li>
            <itme-li></itme-li>
            <itme-li></itme-li>
    	   <!-- </itme-li> 不建议使用,即使用了也是无效的-->
        </div>
        <script>
            Vue.component("itme-li",{
                template:`<li>hello world</li>`
            })
        </script>
    
  • 如果要是在template里面写两个同级的元素,则第二个不会显示,而且会报错。要想实现两个或多个同级元素,则必须在前面加个根元素

     <div id="app">
            <itme-li></itme-li>
        </div>
        <script>
            //错误写法
            Vue.component("itme-li",{
                template:`
                <li>hello world</li>
                <li>你好</li>//这个则不会显示,切报错
                `
            });
            //正确写法
            Vue.component("itme-li",{
                template:`
                <ul>
                    <li>hello world</li>
                    <li>你好</li>
                </ul>
                `
            });
        </script>
    
  • 上面传的都是死值,那我们也可以动态传值,有个关键词:props();定义一个props接收父组件的值,这里面写的名称就是template语法糖里面的名称要保持一致,可以写多个值

     <div id="app">
            <!-- v-bind:show="msg"必须写在开始标签的后面 -->
            <!-- <v-bind:show="msg" itme-li></itme-li> 这个是错误写法-->
         	<!-- 如果绑定的数据比较多的话,是可以分开写的,示例见如下代码 -->
            <!-- props传的什么值就只能用谁 -->
         	<!-- v-for="itme in list"遍历的是父组件里面数组 -->
         	<!-- 这里v-bind绑定的也是props里的值 -->
            <itme-li 
            v-bind:show="msg" 
            v-bind:shows="msgTwo"
            v-for="itme in list"
            v-bind:arr="itme"
            :key="itme.id"
            ></itme-li>
        </div>
        <script>
            Vue.component("itme-li",{
                //定义一个props接收父组件的值,这里面写的名称就是template语法糖里面的名称要保持一致,可以写多个值
                props:["show","shows","arr"],
                template:`
                <ul>
                    <li>{{show}}</li>
                    <li>{{shows}}</li>
                    <li>{{arr.id}}--{{arr.name}}</li>
                </ul>
                `
            });
            let vm = new Vue({
                el:"#app",
                data:{
                    msg:'今天天气真好啊',
                    msgTwo:"心情也好很多了",
                    list:[
                        {id:0,name:"旭陌"},
                        {id:1,name:"旭陌1"},
                        {id:2,name:"旭陌2"},
                        {id:3,name:"旭陌3"}
                    ]
                }
            });
        </script>
    
  
  以上代码所渲染的示例!![@HXO[05N7PO)DIU@0DM`$J9](C:\Users\admin\Desktop\@HXO[05N7PO)DIU@0DM`$J9.png)
  
- $emit():从子组件传值给父组件:有两个参数,第一个为事件名称,第二个是提供的值(或者是实参)。这里的自定义事件名不能使用驼峰命名,必须全部使用小写或者短横线分割。

  ```html
   <div id="app">
          <itme-li 
          v-for="itme in list"
          v-bind:arr="itme"
          :key="itme.id"
          :style="{fontSize:fontSize + 'em'}"
          v-on:change="num"
          ></itme-li>
      </div>
      <script>
          Vue.component("itme-li",{
              props:["arr"],
              template:`
              <ul>
                  <li>{{arr.id}}--{{arr.name}}</li>
                  <button @click="$emit('change',0.1)">点击方法字体</button>
              </ul>
              `
          });
          let vm = new Vue({
              el:"#app",
              data:{
                  list:[
                      {id:0,name:"旭陌"},
                      {id:1,name:"旭陌1"},
                      {id:2,name:"旭陌2"},
                      {id:3,name:"旭陌3"}
                  ],
                  fontSize:1
              },
              methods:{
                  num(n){
                      this.fontSize += n;
                  }
              }
          });
      </script>
  • 局部组件:

    • 优点:局部组件只能在定义它的实例中使用,是不可以在别的实例中使用的,方便管理
    • 缺点:代码冗余比较高
  • 全局组件:

    • 优点:可以在任何的vue实例中使用
    • 缺点:如果说你的项目中已经没有使用这个组件了,它依然会包含在我们项目最终的构建结果中
    <div id="app">
            <itme-one></itme-one>//这个全局组件可以用
            <ccc></ccc>//这个是可以用的
        </div>
        <div id="app1">
            <itme-one></itme-one>//这个全局组件可以用
            <ccc></ccc>//这个会报错,组件为定义
        </div>
        <script>
            //全局组件
            Vue.component("itme-one",{
                template:`<div>这是全局组件</div>`
            });
    
            let vm = new Vue({
                el:"#app",
              	//components属性定义一个组件  
                components:{
                    //ccc是组件名
                    'ccc':{
                        template:`<h2>这是局部组件</h2>`//组件模板
                    }
                }
            });
    
            let vm1 = new Vue({
                el:"#app1",
            });
        </script>
    
  • props的类型,前面也讲过了props是可以以数组的形式的,但是同时也是可以以对象的形式存在,而这个时候就可以选择props的接收数据名称的类型,如果类型以父组件里面的数据类型不一样虽然也可以渲染,但是也是会报错的,下面就来看一个例子吧

     <div id="app">
            <itme-one 
            v-bind:change='msg'
            ></itme-one>
        </div>
        <script>
            Vue.component("itme-one",{
               props:{
                   //这里就设置为数值类型
                   'change':Number//此刻改成string就可以了
               },
               template:`<div>{{change}}</div>`
            });
            let vm = new Vue({
                el:"#app",
                data:{
                    //而父组件的数据是string类型
                    msg:"你好啊,很高兴认识你"
                }
            });
        </script>
    
  • :插槽

    • 插槽的基本用法:使用注册组件时,直接在组件标签中写入内容是无效的,但是如果使用了slot标签的话,则能够将内容展示出来。当组件渲染的时候,将会被我们自己在模板写的内容替代。还有就是如果slot标签在某个元素的前面,则展现的内容也会在某个元素的内容前面

      <div id="app">
              <itme-one 
              v-bind:url='url'
              ><h2>haha</h2></itme-one>
          </div>
          <script>
              Vue.component("itme-one",{
                props:['url'],
                 template:`<div>
                  <slot></slot>
                  <a href="url">点我</a>
                 </div>`
              });
              let vm = new Vue({
                  el:"#app",
                  data:{
                      url:'/today'
                  }
              });
          </script>
      
    • 插槽里的作用域编译:父级作用里的内容是在父级模板里编译的, 而子作用域里的内容是在子作用域里编译的

      <div id="app">
              <itme-one 
              v-bind:url='url'
              >
              <!-- 这里是父级作用域的内容 -->
                  <h2>{{msg}}</h2>
              </itme-one>
          </div>
          <script>
              Vue.component("itme-one",{
                props:['url'],
                data:function(){
                    return {
                        msg:"这里是子作用域的内容"
                    }
                },
                 template:`<div>
                  <slot></slot>
                  <a href="url">{{msg}}}</a>
                 </div>`
              });
              let vm = new Vue({
                  el:"#app",
                  data:{
                      url:'/today',
                      msg:"这里是父作用域的内容"
                  }
              });
          </script>
      
    • 插槽的后备内容,当注册组件里没有写内容的时候,slot插槽里的内容是默认的,要是注册组件里有内容,则显示注册组件里的内容为主。

      <div id="app">
              <itme-one 
              v-bind:url='url'
              >
                  <!-- <h2>{{url}}</h2>这里没写内容的时候就是slot的默认内容显示 -->
              </itme-one>
          </div>
          <script>
              Vue.component("itme-one",{
                props:['url'],
                 template:`<div>
                  <slot>{{url}}<i>这里是默认的内容</i></slot>
                  
                  <a href="url">{{url}}</a>
                 </div>`
              });
              let vm = new Vue({
                  el:"#app",
                  data:{
                      url:'/today'
                  }
              });
          </script>
      
    • 具名插槽:如果有多个slot插槽的话,这个时候slot是有name属性的,在slot写上属性名就可以了

      <div id="app">
              <itme-one>
                  <!-- v-slot:header可以缩写成#header -->
                  <template v-slot:header>
                      <h2>这里是头部区域</h2>
                  </template>
      
                  <p>这里是p1</p>
                  <p>这里是p2</p>
                  <p>这里是p3</p>
      
                  <template #footer>
                      <h2>这里是footer区域</h2>
                  </template>
              </itme-one>
          </div>
          <script>
              Vue.component("itme-one",{
              //   props:['url'],
                 template:`<div>
                  <header>
                      <slot name="header"></slot>
                  </header>
                  <main>
                      <slot></slot>
                  </main>
                  <footer>
                      <slot name="footer"></slot>
                  </footer>
                 </div>`
              });
              let vm = new Vue({
                  el:"#app"
              });
          </script>
      
    • 作用域插槽:如果你想在父级用子级的内容,就需要用到作用域插槽

       <!--  v-bind:user="user"v-bind:自定义属性名=传过去使用的值
      	   v-slot={user,password:pwd}如果有多个对象的话,用,隔开直接写传过去的参数
      	   password:pwd这里的password改成pwd,所以用第二个对象就是pwd了,要是不写的话就是默认的password,就跟es6的解构赋值是一样的
      -->
      <div id="app">
              <itme-one v-slot={user,password:pwd}>
                  {{user.name}}
                  {{pwd.val}}
              </itme-one>
          </div>
          <script>
              Vue.component("itme-one",{
                  data(){
                      return {
                          user:{
                              name:"xumo"
                          },
                          password:{
                              val:123
                          }
                      }
                  },
                 template:`<div><slot 
                 v-bind:user="user"
                 v-bind:password="password"
                 ></slot></div>`
              });
              let vm = new Vue({
                  el:"#app"
              });
          </script>
      
      • $refs:父组件获取子组件的属性和方法

        <div id="app">
            	 <!-- ref属性可以获取父组件的属性和方法 -->
                <itme-one ref="son"></itme-one>
                <button @click="getData">点击获取数据</button>
                <p>{{msg1}}--{{msg2}}</p>
            </div>
            <script>
                Vue.component("itme-one",{
                    data(){
                        return{
                            a:123,
                            b:456
                        }
                    },
                    template:`<ul><li style='list-style:none'></li></ul>`
                });
                let vm = new Vue({
                    el:"#app",
                    data:{
                        msg1:"",
                        msg2:""
                    },
                    methods:{
                        getData(){
                            // console.log(this.$refs);
                            return this.msg1 = this.$refs.son.a,
                            this.msg2 = this.$refs.son.b
                        }
                    }
                });
            </script>
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旭陌小生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值