vue组件

定义Vue组件

什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;

组件化和模块化的不同:

  • 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
  • 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;

一 全局组件定义的三种方式

  1. 使用 Vue.extend 配合 Vue.component 方法:

     1.1 使用 Vue.extend 来创建全局的Vue组件
         通过 template 属性,指定了组件要展示的HTML结构
    
     	var login = Vue.extend({
           template: '<h1>登录</h1>'
         });
    
     1.2 使用 Vue.component('组件的名称', 创建出来的组件模板对象)
     	Vue.component('mycom1', login);
    
     1.3 如果要使用组件,标签形式,引入自己的组件
     	<mycom1></mycom1>
    
  2. 直接使用 Vue.component 方法:

     定义:
     Vue.component('mycom2', {
           template: '<h1>注册</h1>'
         });
    
     使用:
     如果要使用组件,标签形式,引入自己的组件
     <mycom2></mycom2>
    
  3. 将模板字符串,定义到script标签种:
    第二种的基础上方便HTML的编写

     <script id="tmpl" type="x-template">
       <div><a href="#">登录</a> | <a href="#">注册</a></div>
     </script>
    

    同时,需要使用 Vue.component 来定义组件:

     	Vue.component('account', {
           template: '#tmpl'
         });
    

注意: 组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!

二 组件中展示数据和响应事件

     1. 组件可以有自己的 data 数据 和 methods
     2. 组件的 data 和 实例的 data 有点不一样,实例中的 data 可以为一个对象,但是 组件中的 data 必须是一个方法
     3. 组件中的 data 除了必须为一个方法之外,这个方法内部,还必须返回一个对象才行;
     4. 组件中 的data 数据,使用方式,和实例中的 data 使用方式完全一样!!!
  1. 在组件中,data需要被定义为一个方法,而不是一个对象了。例如:

     Vue.component('account', {
           template: '<h1>这是全局组件 --- {{msg}}</h1>',
           data() {
             return {
               msg: '组件自己的数据'
             }
           },
           methods:{
             login(){
               alert('点击了登录按钮');
             }
           }
         });
    
  2. 在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的data属性中的值,需要使用this来访问;

【重点】为什么组件中的data属性必须定义为一个方法并返回一个对象

  1. 通过计数器案例演示

三 使用components属性定义局部子组件

  1. 组件实例定义方式:

      <script>
         // 创建 Vue 实例,得到 ViewModel
         var vm = new Vue({
           el: '#app',
           data: {},
           methods: {},
           components: { // 定义子组件
             account: { // account 组件
               template: '<div><h1>这是Account组件{{name}}</h1></div>', // 在这里使用定义的子组件
               components: { // 定义子组件的子组件
                 login: { // login 组件
                   template: "<h3>这是登录组件</h3>"
                 }
               }
             }
           }
         });
       </script>
    
  2. 引用组件:

       <div id="app">
         <account></account>
       </div>
    

四 使用flag标识符结合v-ifv-else切换组件(只能切换2个)

  1. 页面结构:

       <div id="app">
         <input type="button" value="toggle" @click="flag=!flag">
         <my-com1 v-if="flag"></my-com1>
         <my-com2 v-else="flag"></my-com2>
       </div>
    
  2. Vue实例定义:

       <script>
         Vue.component('myCom1', {
           template: '<h3>奔波霸</h3>'
         })
     
         Vue.component('myCom2', {
           template: '<h3>霸波奔</h3>'
         })
     
         // 创建 Vue 实例,得到 ViewModel
         var vm = new Vue({
           el: '#app',
           data: {
             flag: true
           },
           methods: {}
         });
       </script>
    

五 使用:is属性来切换不同的子组件,并添加切换动画(通过mode属性)

  1. 组件实例定义方式:

       // 登录组件
         const login = Vue.extend({
           template: `<div>
             <h3>登录组件</h3>
           </div>`
         });
         Vue.component('login', login);
     
         // 注册组件
         const register = Vue.extend({
           template: `<div>
             <h3>注册组件</h3>
           </div>`
         });
         Vue.component('register', register);
     
         // 创建 Vue 实例,得到 ViewModel
         var vm = new Vue({
           el: '#app',
           data: { comName: 'login' },
           methods: {}
         });
    
  2. 使用component标签,来引用组件,并通过:is属性来指定要加载的组件:

       <div id="app">
         <a href="#" @click.prevent="comName='login'">登录</a>
         <a href="#" @click.prevent="comName='register'">注册</a>
         <hr>
         <transition mode="out-in">
           <component :is="comName"></component>
         </transition>
       </div>
    
  3. 添加切换样式:

       <style>
         .v-enter,
         .v-leave-to {
           opacity: 0;
           transform: translateX(30px);
         }
     
         .v-enter-active,
         .v-leave-active {
           position: absolute;
           transition: all 0.3s ease;
         }
     
         h3{
           margin: 0;
         }
       </style>
    

六 父组件向子组件传值

  1. 组件实例定义方式,注意:一定要使用props属性来定义父组件传递过来的数据

     <script>
         // 创建 Vue 实例,得到 ViewModel
         var vm = new Vue({
           el: '#app',
           data: {
             msg: '这是父组件中的消息'
           },
           components: {
             son: {
               template: '<h1>这是子组件 --- {{finfo}}</h1>',
               props: ['finfo']
             }
           }
         });
       </script>
    
  2. 使用v-bind或简化指令,将数据传递到子组件中:

     通过 属性绑定(v-bind:) 的形式, 把 需要传递给 子组件的数据,
     	以属性绑定的形式,传递到子组件内部,供子组件使用
    
     <div id="app">
      <son :finfo="msg"></son>
     </div>
    
  3. data与props的区别

      注意1: 子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,
     		比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上;
      注意2: data 上的数据,都是可读可写的;
             props 中的数据,都是只读的,无法重新赋值
    

七 父组件向子组件传方法

1.定义一个字面量类型的 组件模板对象
2.创建vue实例,得到ViewModel,加载组件
3.template: 通过指定了一个 Id, 这个指定Id的 template 元素中的内容,当作 组件的HTML结构
4.在app控件中使用事件绑定机制传递方法
5.在子组件template模板中,通过自己的方法–调用传递进来的父组件的方法[this.$emit]

var com2 = {
      template: '#tmpl', // 通过指定了一个 Id, 表示 说,要去加载 这个指定Id的 template 元素中的内容,当作 组件的HTML结构
      data() {
        return {
          sonmsg: { name: '小头儿子', age: 6 }
        }
      },
      methods: {
        myclick() {
          // 当点击子组件的按钮的时候,如何 拿到 父组件传递过来的 func 方法,并调用这个方法???
          //  emit 英文原意: 是触发,调用、发射的意思
          // this.$emit('func123', 123, 456)
          this.$emit('func', this.sonmsg)
        }
      }
    }


=============================================

 // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        datamsgFormSon: null
      },
      methods: {
        show(data) {
          // console.log('调用了父组件身上的 show 方法: --- ' + data)
          // console.log(data);
          this.datamsgFormSon = data
        }
      },

      components: {
        com2
        // com2: com2
      }
    });
 =====================================
 	 <div id="app">
		 <com2 @func="show"></com2>
	 </div>
 =====================================
 <template id="tmpl">
    <div>
      <h1>这是 子组件</h1>
      <input type="button" value="这是子组件中的按钮 - 点击它,触发 父组件传递过来的 func 方法" @click="myclick">
    </div>
  </template>

八 子组件向父组件传值

  1. 原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去;

  2. 子组件内部通过this.$emit('方法名', 要传递的数据)方式,来调用父组件中的方法,同时把数据传递给父组件使用

     在子组件方法中传入参数
     	this.$emit('方法名', 123,456)    data =123 data2 =456
    
     在父类方法中接收参数   
          var vm = new Vue({
     	      el: '#app',
     	      data: {
     	        datamsgFormSon: null
     	      },
     	      methods: {
     	        show(data,data2) {
     	          // console.log('调用了父组件身上的 show 方法: --- ' + data + data2)
     	          this.datamsgFormSon = data
     	        }
     	      }
    

九 评论列表案例

目标:主要练习父子组件之间传值

十 使用 this.$refs 来获取元素和组件(获取dom元素)

  <div id="app">
    <div>
      <input type="button" value="获取元素内容" @click="getElement" />
      <!-- 使用 ref 获取元素 -->
      <h1 ref="myh1">这是一个大大的H1</h1>

      <hr>
      <!-- 使用 ref 获取子组件 -->
      <my-com ref="mycom"></my-com>
    </div>
  </div>

  <script>
    Vue.component('my-com', {
      template: '<h5>这是一个子组件</h5>',
      data() {
        return {
          name: '子组件'
        }
      }
    });

    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        getElement() {
          // 通过 this.$refs 来获取元素
          console.log(this.$refs.myh1.innerText);
          // 通过 this.$refs 来获取组件
          console.log(this.$refs.mycom.name);
        }
      }
    });
  </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

良之才-小良

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

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

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

打赏作者

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

抵扣说明:

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

余额充值