Vue学习笔记-组件

1、基础组件

     注册组件:使用component()方法,该方法里面需传人两个参数:name【下面引用组件用】,obj【设置组件内容,data属性和template属性,data存放组件中参数,template值是一个html格式的字符串】

// 定义一个新的组件,名称为 button-counter
Vue.component('button-counter', {
data: function () {
    return {
    count: 0
   }
},
template: '<button v-on:click="count++">你点击了 {{ count }} 次。</button>'
})

 使用组件:首先需要创建Vue对象,然后在声明的对象里将属性名当作html的元素名使用即可

var vm=Vue({
  el:"app",
});//js部分代码
<!--html代码--!>
<div id="app">
  <button-counter></button-counter>
</div>

2、复用组件

     重复使用组件时,为防止data变量相互干扰,在注册组件时data必须是一个函数,返回一个对象。

3、传值

   无论是父传子还是子传父,首先要分清楚谁是父,谁是子。子与父并不是指两个vue文件,父是指使用组件的整体,子是指创建的模板。

    a、父传子(通过props传值)

     子组件:是指组件创建时用到的html元素

     在创建时设置一个props属性,属性值是一个数组,数组里添加需要传入的参数名,再template的用法跟data中的值一样,直接输入参数名即可。

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

   父组件在使用子组件时,需要在元素标签里面添加一个属性名,需要传入的值赋值给该属性,即可向子组件传参

<blog-post title="我的 Vue 旅程"></blog-post>

  注:父组件给子组件传递一个静态字符串类型的参数是可以直接如上直接用title=“”的格式传递,但是如果你先传递一个动态数据时,需要用v-bind绑定。

 子组件的接收方式没什么区别,但是父组件传递时需要改变一下。例如传递obj(一个对象),一个数组,此时子组件的创建方式是一样的,但是父组件的传值方式要做改变。

<template>
  <div id="zujian">
    <!--<demo title="传递一个固定值字符串"></demo>-->
  <!--传递一个对象-->
   <!--<obj-demo :obj="objs"></obj-demo>-->
  <!--传递一个数组-->
    <arr-demo v-for="item in stu" :key="item.id" :name="item.name"></arr-demo>
  </div>
</template>
<script>
  import Vue from 'vue'
  export default{
      name:"zujian",
    data(){
      return {
          objs:{
              name:"测试zhong"
          },
          stu:[
            {id:1,name:"周"},
            {id:2,name:"刘"},
            {id:3,name:"董"},
          ]
      };
    },
    components:{
        "demo":{
            props:['title'],
            template:'<h3>{{title}}</h3>'
        },
        "obj-demo":{
            props:['obj'] ,
            template:'<h2>{{obj.name}}</h2>'
        },
        "arr-demo":{
          props:['name'],
          template:"<h2>{{name}}</h2>"
        }
    }
  }
</script>

b、子传父

    子组件向父组件传值需要通过事件和来实现$emit来实现,在子组件注册时添加事件,在事件内使用$emit来触发一个自定义事件,并传入一个值,父组件通过绑定该自定义的事件来获取子组件传入值。

   子组件:

<template>
  <!--template只能有一个孩子节点-->
  <div>
    <h2>{{name}}</h2>
    <button @click="sendMes">点击向父组件传值</button>
  </div>
</template>
<script>
  export default{
      props:['name'],
      methods:{
          sendMes:function () {
            this.$emit('getMes',"子组件传入值")
          }
      }
  }
</script>

  父组件:

<template>
  <div>
    <h2>{{values}}</h2>
    <cinema-son @getMes="showMes"></cinema-son>
  </div>
</template>
<script>
  import cinemaSon from "../components/cinemaSon.vue"
  export default{
      data(){
          return {
              values:'初始值',
          }
      },
      components:{
          cinemaSon
      },
    methods:{
          showMes:function (data) {
            this.values=data;//this指向Vue
          }
    }
  }
</script>

4、项目中组件开发

    项目中组件的开发,子组件可以是一个单独的vue文件,但是在父组件中使用子组件要把子组件注册进去

      子组件:

<template>
  <!--template只能有一个孩子节点-->
  <div>
    <h2>{{name}}</h2>
    <button @click="showAlert">点击</button>
  </div>
</template>
<script>
  export default{
      props:['name'],
      methods:{
          showAlert:function () {
            alert("子组件");
          }
      }
  }
</script>
    父组件:
<template>
  <div>
    <cinema-son name="传值"></cinema-son>
  </div>
</template>
<script>
  import cinemaSon from "../components/cinemaSon.vue"
  export default{
      components:{
          cinemaSon
      }
  }
</script>

5、插槽内容(slot:内容分发)

     插槽,也就是slot,是组件的一块HTML模板,这块模板显示与不显示,以及怎样显示由父组件决定。slot的两个核心问题是显示不显示与怎么显示。插槽slot跟'div、span'这些一样,直接写在界面中。虽然它的显示不显示由父组件决定,但是它显示的位置由子组件决定,子组件中它写在哪个位置,父组件传过来的模块就显示在什么位置。

     插槽分为单个插槽、具名插槽和作用域插槽。

    单个插槽,又叫默认插槽,它可以放在任何位置,但是一个组件只能有一个该类插槽。

   父组件控制模板内容,并通过child(child为引入的子组件名字)传递:

<template>
    <div class="father">
        <h3>这里是父组件</h3>
        <child>
            <div class="tmpl">
              <span>菜单1</span>
              <span>菜单2</span>
              <span>菜单3</span>
              <span>菜单4</span>
              <span>菜单5</span>
              <span>菜单6</span>
            </div>
        </child>
    </div>
</template>
<script>
import child from ""
</script>
子组件则只需要在需要的位置添加
<slot></slot>
    具名插槽,需要添加name属性,具名插槽可以在一个组件里出现多次。

在父组件中通过添加上slot属性,来区分不同的具名插槽需要插入的内容。

<template>
  <div class="father">
    <h3>这里是父组件</h3>
    <child>
      <div class="tmpl" slot="up">
        <span>菜单1</span>
        <span>菜单2</span>
        <span>菜单3</span>
        <span>菜单4</span>
        <span>菜单5</span>
        <span>菜单6</span>
      </div>
      <div class="tmpl" slot="down">
        <span>菜单-1</span>
        <span>菜单-2</span>
        <span>菜单-3</span>
        <span>菜单-4</span>
        <span>菜单-5</span>
        <span>菜单-6</span>
      </div>
      <div class="tmpl">
        <span>菜单->1</span>
        <span>菜单->2</span>
        <span>菜单->3</span>
        <span>菜单->4</span>
        <span>菜单->5</span>
        <span>菜单->6</span>
      </div>
    </child>
  </div>
</template>
子组件要给slot添加对应的name属性
 // 具名插槽
    <slot name="up"></slot>
    <h3>这里是子组件</h3>
    // 具名插槽
    <slot name="down"></slot>
    // 匿名插槽
    <slot></slot>
  作业域插槽,其实也可以叫做带数据插槽,它要去在slot上面绑定数据。这样就成了样式父组件说了算,但是内容子组件可以规定。
子组件通过绑定data事件传递值(绑定是data里的数据)
<template>
  <div class="child">

    <h3>这里是子组件</h3>
    // 作用域插槽
    <slot  :data="arr"></slot>
  </div>
</template>

 export default {
    data: function(){
      return {
        arr: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
      }
    }
}
父组件通过 slot-scope接收数据
<template>
  <div class="father">
    <h3>这里是父组件</h3>
    <!--第一次使用:用flex展示数据-->
    <child>
      <template slot-scope="user">
        <div class="tmpl">
          <span v-for="item in user.data">{{item}}</span>
        </div>
      </template>

    </child>

    <!--第二次使用:用列表展示数据-->
    <child>
      <template slot-scope="user">
        <ul>
          <li v-for="item in user.data">{{item}}</li>
        </ul>
      </template>

    </child>

    <!--第三次使用:直接显示数据-->
    <child>
      <template slot-scope="user">
       {{user.data}}
      </template>

    </child>

    <!--第四次使用:不使用其提供的数据, 作用域插槽退变成匿名插槽-->
    <child>
      我就是模板
    </child>
  </div>
</template>

6、动态组件

   简单的说就是几个组件放在一个挂载点下,通过绑定is属性的变量(is绑定的值是组件名)来决定显示哪一个。

<template>
  <div id="zujian">
    <button @click="toshow">点击</button>
    <component :is="showIndex"></component><!--此处节点名是comopent,多个组件在此切换-->
  </div>
</template>
<script>
  import Vue from 'vue'
  export default{
      name:"zujian",
    data(){
      return {
        showIndex:"",
      };
    },
    methods:{
      toshow: function () {   //切换组件显示
        var arr = ["first", "second", "third", ""];
        var index = arr.indexOf(this.showIndex);
        if (index < 3) {
          this.showIndex = arr[index + 1];
        } else {
          this.showIndex = arr[0];
        }
      }
      },
    components: {
      first: { //第一个子组件
        template: "<div>这里是子组件1</div>"
      },
      second: { //第二个子组件
        template: "<div>这里是子组件2</div>"
      },
      third: { //第三个子组件
        template: "<div>这里是子组件3</div>"
      },
    }
  }
</script>
动态组件中还有几个常用 属性,下面做个简单的介绍。
属性 用途 例子
keep-alive 原本每次切换都会在父组件的this.$chilren里面添加一个子组件,
添加该属性后不再会重复添加
<component v-bind:is="showIndex" keep-alive></component>
activate钩子 延迟加载,跟template、data等属性平级,值是一个函数,当这
个函数执行时,才会切换组件
 

transition-mode

过渡模式,动态组件切换时,让其出现动画效果,默认是进入
和退出一起,但是也可以通过该属性更改,值有“in-out"、
"out-in"、也可以与transition配合,自定义过渡方式
<component v-bind:is="showIndex" transition="bounce" transition-mode="out-in"></component>
Vue.transition("bounce",{
enterClass:"",
leaveClass:"" //填写类名
})


  

  



猜你喜欢

转载自blog.csdn.net/zhou8023ddw/article/details/80840406