Vue组件化开发

Vue组件化开发

  1. JavaScript高阶函数的使用

    编程范式可以分为:命令式编程(JS)和声明式编程(Vue);或者面向对象编程(第一公民:对象)和函数式编程(第一公民:函数);

    JS高级函数可以实现链式编程!!这种编程称为函数式编程;例如箭头函数,首先经过过滤,找出小于100的数值,然后将这些数值乘以2,再求取该些值得总和:

    let total = nums.filter(n=> n < 100).map(n=> n*2).reduce((pre,n)=> pre+n);

    filter函数

    —传入参数为一个回调函数,可以循环遍历元素;

    —语法:list.filter(function(n){});

    —该函数传入的回调函数有一个要求:必须返回一个布尔值;当返回true时,函数内部会自动将这次回调函数中的参数n加入到新的数组中;当返回false时,回调函数会自动过滤掉该元素;

    例如:

    <script>
    //可以直接实现提取出数组中小于100的元素
    	const nums = [10,20,111,34,201,50]
    let list = nums.filter(function(n){
      return n<100
    })
    </script>
    

    map函数

    —传入参数为一个回调函数,可以循环遍历元素;

    —该函数传入的回调函数会将元素或者操作处理后的元素直接返回;

    例如:

    <script>
     //返回数组元素的2倍的新数组
    	const nums = [10,20,30,40]
     let list = nums.map(function(n){
         return n*2
     })
    </script>
    

    reduce函数

    —作用:可以实现数组中所有元素的汇总;

    —需要传入两个参数为,参数一为回调函数,参数二为0,相当于初始化值为0;

    —回调函数中也需要传入两个参数,参数一为前一次循环遍历返回的值(第一次循环遍历返回的值是初始化的值),参数二为循环遍历的元素值;

    例如:

    <script>
    	//返回数组总和
     const nums = [10,20,30,40]
     let sum = nums.reduce(function(preValue,n){
         return preValue+n
     },0)
     //分析:
     //第一次 preValue:0 n:10
     //第二次 preValue:0+10 n:20
     //第三次 preValue: 0+10+20 n:30
     //第四次 preValue: 0+10+20+30 n:40 返回0+10+20+30+40
    </script>
    
  2. 组件

    —基本思想:将一个页面中所有的处理逻辑全部放在一起,处理起来会比较复杂,不例如后续的管理及扩展,但是如果把页面拆分成一个个小的功能块,每个功能块完成属于自己的独立部分功能,整个页面的管理和维护就是十分容易了;

    —组件化是Vue中重要的思想,它提供一抽象,让我们可以开发出一个个独立可复用的小组件构造我们的应用;任何应用都会被抽象成一颗组件树;(这里涉及到数据结构中树结构和二叉树)

    注册组件的基本步骤

    —创建组件构造器:调用Vue.extend()方法;

    —注册组件:调用Vue.component()方法;(这里是一个全局组件)

    —使用组件:在Vue实例的作用范围内使用组件;

    —注册组件的语法糖形式,省去了Vue.extend()方法,直接使用一个对象代替:

    <script>
    //全局组件的注册语法糖
    	Vue.component('cpn',{
      template:`
    			<div>
    			<h2>我是一个标题</h2>
    		</div>
    		`
    })
     const app = new Vue({
         el:'#app',
         data(){
    
         },
         //局部组件的语法糖
         components:{
             'cnp2':{
                 template:`
    					<div>我是局部组件<div>
    				`
             }
         }
     })
    </script>
    

    组件化基本使用实例:

    <div id="app">
    <!--创建组件使其可复用-->
    <h2>我是标题</h2>
    <p>我是内容</p>
    <!--调用组件,必须在Vue实例作用的范围内才会有效果-->
    <my-cpn></my-cpn>
    </div>
    <script src="vue.js"></script>
    <script>
    //1. 创建组件构造对象
    //ES6语法,字符串可以使用``代替"",这样在``中的内容可以进行换行
    const cpnel = Vue.extend({
      //传入template作为自定义组件的模板
      template:
      `<div>
    			<h2>我是标题</h2>
    			<p>我是内容</p>
    	</div>`
    })
    //2. 注册组件
    //传递两个参数,第一个是组件标签名,第二个为组件构造对象
     Vue.component('my-cpn',cpnel)
    //Vue实例对象 
    	const app = new Vue({
      el:"#app",
      data:{
    
      }
    })
    </script>
    

    全局组件和局部组件

    —全局组件可以在多个Vue实例下使用;

    —局部组件:在Vue实例中components属性下注册的组件即为局部组件,不可以在其他实例中使用:

    <script>
    const cpnel = Vue.extend({
      //传入template作为自定义组件的模板
      template:
      `<div>
    			<h2>我是标题</h2>
    			<p>我是内容</p>
    	</div>`
    })
    	const app = new Vue({
      el:"app",
      data:{
    
      },
      //在单个Vue实例对象下注册局部组件
      component:{
          //组件标签名:组件构造器
          cpn:cpnel
      }
    })
    </script>
    

    父组件和子组件

    —Vue可以看作是最顶层的组件,root组件;

    <script>
    	//创建第一个组件构造器
     const cpnC1 = Vue.extend({
         template:
         `<div>
     		<h2>我是一个标题1</h2>
     	</div>`
     })
     //创建第二个组件构造器
     const cpnC2 = Vue.extend({
       template:
         `<div>
     		<h2>我是一个标题2</h2>
    			<cpn1></cpn1>
     	</div>`,
         //在组件构造器2中注册组件1,这样组件构造器2为父组件,组件构造器1为子组件
         components:{
             cpn1:cpnC1
         }
     })
    </script>
    

    —父子组件的错误用法:以子标签的形式在Vue实例中使用;因为子组件注册到父组件的compnents时,Vue会编译好父组件的模块;该模块的内容已经决定了父组件将要渲染的页面,就相当于父组件已经有了子组件的内容了;子组件标签只能在父组件中使用;

    父子组件的通信

    —在开发过程中,往往一些数据都是从上层传递到下层,比如一个页面从服务器请求到很多数据,其中一部分数据是需要下面子组件进行展示的,这个时候并不是让子组件在发送一个网络请求,而是直接让父组件将数据传递给子组件;

    —父子间通信的两种方式:

    1. 父组件通过props向子组件传递数据
    2. 子组件通过自定义事件向父组件发送消息

    通过props向子组件传递数据

    方式一:字符串数组,数组中的字符串就是传递时的名称;开发中很少使用;

    方式二:对象,对象可以设置传递时的类型,也可以设置默认值;

    注意,在使用v-bind绑定时,驼峰标识名会出错,需要进行转换,比如childMyMessage转换为child-my-message

    父组件通过props向子组件传递数据实例

    <div id = "app">
    <!--这里传递数据时一定要使用v-bind进行绑定-->
    <!--注意,在使用v-bind绑定时,驼峰标识名会出错,需要进行转换-->
    <cpn v-bind:c-movies="movies"></cpn>
    </div> 
    <template id = "cpn">
    <div>
       <ul>
           <li v-for = "item in cmovies">{{item}}</li>
       </ul>
    </div>
    </template>
    <script>
    const cpn = {
      template:'#cpn',
      //数组类型
      props:['cmovies'],
      //对象形式
      props:{
          //可以进行类型限制,要求传递类型为数组类型
          //如果类型是对象或者数组时,默认值必须是一个函数
          cMovies:{
              type:Array,
              default(){
                  return []
              }
          }
          //可以提供默认值
          cmessage:{
          	type:String,
          	default:'aaaa',
             //要求传递数据时,必须传递cmessage内容,否则报错
              required:true
      	}
      },
      data(){
          return{}
      }
    }
    	const app = new Vue({
      el:"#app",
      data:{
          movies:["Tom","Jack","Ammy"]
      },
      components:{
          //局部组件,对象ES6写法
          cpn
      }
    })
    </script>
    

    子组件向父组件传递数据

    —当子组件向父组件传递数据时,需要用到自定义事件,v-on不仅可以用于监听DOM事件,也可以应用组件之间的自定义事件;

    <!--父组件模板-->
    <div id="app">
    //驼峰标识需要转换
    <cpn @itemclick = "cpnClick"></cpn>
    </div>
    <template id="cpn">
    <div>
      <button v-for = "item in categories" @click = "btnClick(item)">
          {{item.name}}
      </button>
    </div>
    </template>
    <script>
    //子组件
    	const cpn = {
      template:"#cpn",
      data(){
          return{
              categories:[
                  {id:'aaa',name:"热门推荐"},
                  {id:'bbb',name:"手机数码"},
                  {id:'ccc',name:"电脑办公"}
              ]
          }
      },
      methods:{
          btnClick(item){
              //通过自定义事件将子组件的数据传递给父组件
             // 参数为自定义事件名称和自定因 
              this.$emit("itemclick",item)
          }
      }
    }
    //父组件
    const app = new Vue({
      el:"#app",
      data:{
    
      },
      components:{
          cpn
      },
      methods:{
          cpnClick(item){
              console.log(item)
          }
      }
    })
    </script>
    

    组件模块分离写法

    —在组件开发过程中,由于template模块写法太过于繁琐,我们可以将其中的HTML标签分离出来写,然后挂载到对应的组件上,使得结构变得清晰;

    实现方案有两种

    1. 使用<script>标签,注意类型必须是x-template
    2. 使用template标签;
    <!--1.使用script标签-->
    <script type = "text/x-template" id = "cpn">
    <div>
    	<h2>我是标题</h2>    
    </div>
    </script>
    <!--2.使用template标签-->
    <template id="cpn">
    	<div>
    		<h2>我是标题</h2>    
    	</div>
    </template>
    <script>
    	Vue.component('cpn',{
            template:'#cpn'
        })
    </script>
    
  3. 组件data函数

    —组件是一个单独功能模块的封装:这个模块有属于自己的HTML模块,也有自己的属性数据data

    组件不能直接访问Vue实例中的data数据,即使可以访问,将所有数据放在Vue实例中,Vue实例会变得很臃肿;因此Vue组件应该有自己保存数据的地方

    —组件对象中也有一个data属性(除此之外,也含有其他像methods属性),只是这个data属性必须是一个函数,这个函数返回一个对象,这个对象内部保存着数据;

    —为什么使用data函数,可以起到一个作用域作用,防止组件之间的数据相互调用,在创建组件时,需要重新创建并返回对象,组件之间的数据不会相互影响

    <template id="cpn">
    	<div>
         <h2>当前计数:{{counter}}</h2> 
         <button @click="increment">+</button>
         <button @click="decrement">-</button>
      <div>
    </template>
    <script>
    	//注册组件
     Vue.component('cpn',{
         template:'#cpn',
         data(){
             return {
                 counter:0
             }
         },
         methods:{
             increment(){
                 this.counter++
             },
             decrement(){
                 this.counter--
             }
         }
     })
    </script>
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值