Vue组件的使用方法

Vue组件的使用方法

Vue组件化思想

组件化是Vue中的重要思想

  • 他提供了一种抽象,让我们可以开发出一个个可复用的小组件来构造我们的应用
  • 任何应用都会被抽象成一颗组件树

组件化思想的应用

  • 尽可能的将页面拆分成一个个可复用的小组件
  • 方便代码管理,可复用性强

注册组件的基本步骤

组件使用分为三个步骤

  • 1.调用Vue.extend创建构造器
    传入template代表我们自定义组件的模板,该模板就是使用到组件的地方,要显示的html代码
  • 2.Vue.component() 注册组件(全局注册和局部注册)
    调用Vue.component()是将刚才的构造器注册成一个组件,并给他取一个组件的标签名称
    需要两个参数,:1.注册组件的名称 2. 被注册的构造器的名称
  • 使用组件
    组件必须被挂载在某个Vue实例下,否则他不会生效
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  //创建组件构造器
  const cpnC = Vue.extend({
    
    
    template:`<div>啊</div>`
  })
  //注册组件(全局组件,意味着可以在多个vue实例中使用)
  Vue.component('cpn',cpnC)
 
  const app = new Vue({
    
    
    el:"#app",
    data:{
    
    
    }
  })
</script>

在这里插入图片描述

vue的全局组件和局部组件

上面的组件在注册时,可以看到是全局组件,而全局组件的意思是可以在多个Vue实例下使用,但是,实际项目开发中,这样不是很方便,因此还有局部组件

全局组件

全局组件的注册方法

Vue.component('组件名称',组件构造器名称)

好处 所有的Vue实例都可以用
坏处容错率低,一般都需要在某个节点下使用

局部组件

局部组件只能在当前Vue实例下使用
因此直接在创建的Vue的实例下注册

const app = new Vue({
    
    
    el:"#app",
    data:{
    
    
    },
    components:{
    
    
    //注意组件名称不能使用驼峰命名
      'app-component':{
    
    
      	template:`<div>啊</div>`//内容必须被html元素包裹
      },
      //可以有data属性,但是里面必须是个函数
      data:{
    
    
      	function(){
    
    
      	}
      }
    }
  })

当某些html标签不能放入我们的自定义组件时

可以在的那个钱html标签上添加is属性+组件标签名称

组件内部是不能访问Vue实例数据的

Vue组件应该有自己保存自己数据的地方

那么组件内部的数据放在哪里呢?

  • 就像Vue实例一样,组件内部也有个data属性
  • 但是这个data属性必须是一个函数
  • 而且这个函数返回一个对象,对象内部保存数据
const app = new Vue({
    
    
      el:"#app",
      data:{
    
    
      },
      components:{
    
    
        'cpn2':{
    
    
        template:"#cpn2",
          data(){
    
    
            return {
    
    
              msg: '干嘛'
            }
          }
        }
      }
    })

所以,因为组件的内部的data是return的对象,因此这个data的对象可以被复用,这个组件就可以被复用,作为独立的组件运行相互不干扰

父子件通信

上面提到了,子组件是不能引用父组件或者Vue实例数据的
但是,在开发中,往往数据是需要从上层往下层传递的

那么如何进行父子间通信呢

  • 使用props向子组件传递数据
  • 通过事件像父组件传递数据

关于父组件像子组件传递信息,可以这么理解

  • 首先,父组件在应用子组件的元素标签上引用一个属性 a1 ,标签内容为你好
  • 子组件使用props传递父组件的内容
  • 此时,props数组中的’属性名称’,就是父组件元素标签上的属性.
  • 那么属性名称=‘内容’,此时props数组内的’属性名称’.两个属性名称相同,达到了引用的方法
  • 那么这个属性内容就可以被引用,在子组件的模板上直接使用属性名称,就可以引用属性内容
  • 而父组件的属性一般都是动态绑定的,绑定在Vue的实例中的data中
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    <child-component a1='你好'></child-component>
  </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    
    
    el:"#app",
    data:{
    
    
    },
    components:{
    
    
      'child-component':{
    
    
        template:`<div>{
     
     {a1}}</div>`,
        props:['a1']
      }
    }
  })
</script>
</body>
</html>

单向数据流

第一种使用场景

将父组件传递进来的数据通过初始值保存起来
props的值可以通过组件data函数中的this.xxx直接获取
这样保存好的来自父组件的数据,就可以在不同组件中单独操作

  • 这样,我子组件直接引用data函数返回的对象中的count就可以了嗷
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    <child-component a1='你好'></child-component>
  </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    
    
    el:"#app",
    data:{
    
    
    },
    components:{
    
    
      'child-component':{
    
    
        template:`<div>{
     
     {count}}</div>`,
        props:['a1'],
        data(){
    
    
          return{
    
    
            count: this.a1
          }
        }
      }
    }
  })
</script>
</body>
</html>

第二种使用场景

另一种情况时props作为需要被转变的原始值传入,这种情况计算属性就可以
将父组件传递进来的数据,通过计算属性重新计算,返回值

  • 小demo,根据父组件传进来的数字,决定子组件的宽度
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    <input type="text" v-model='width'>
    <child-component :a1='width'></child-component>
  </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    
    
    el:"#app",
    data:{
    
    
      width:'0'
    },
    components:{
    
    
      'child-component':{
    
    
        template:`<div :style='style'>{
     
     {a1}}</div>`,
        props:['a1'],
        computed:{
    
    
          style(){
    
    
            return {
    
    
              width: this.a1 +'px',
              background: 'red',
              height: '100px'
            }
          }
        }
      }
    }
  })
</script>
</body>
</html>

在这里插入图片描述

那么子组件怎么给父组件传递信息呢?

子组件使用$emit()触发事件
父组件用$on()监听事件

  • 第一步 自定义事件
  • 第二步 在子组件使用$emit()触发事件,第一个参数是事件名,后面是要传递的数据
  • 第三步,在自定义事件中用一个参数接收
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    点击数字发生变化:{
    
    {
    
    msg}}
    <child-component @change='handleMsg'></child-component>
  </div>
<template id='aaa'>
  <button @click='add'>+</button>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    
    
    el:'#app',
    methods:{
    
    
      handleMsg(value){
    
    
        this.msg=value//父组件事件方法中拿到子组件的值,并把值付给msg
      }
    },
    data:{
    
    
      msg:0
    },
    components:{
    
    
      'child-component':{
    
    
      template:'#aaa',
        data(){
    
    
          return {
    
    
            count: 0
          }
        },
        methods:{
    
    
          add(){
    
    
            this.count++//设置子组件点击事件的方法,点击按钮造成子组件的count++
            this.$emit('change',this.count)//然后把子组件的count的值传递给父组件的自定义事件,第一个参数是自定义事件的名称,第二个参数是子组件要传递的值
          }
        }
}
    }
    
  })
</script>
</body>
</html>

上面的例子使用的是自定义事件

其实不需要使用自定义事件,直接绑定v-model,并$emit()触发input事件,效果是一样的

  • 就是个语法糖
  • 因为v-model是双向绑定的,v-model本身绑定的是input事件,并且动态绑定value和data的值
  • 因此,原理就是将子组件的参数传给value,通过v-model,然后传给父组件的data.

猜你喜欢

转载自blog.csdn.net/MS6324_ZAKU/article/details/109182008
今日推荐