Vue组件

组件的概念和分类

  1. 组件具有复用性,但是复用的组件之间的数据是独立的

这也解释为什么data被声明为一个函数再返回一个对象

  1. 局部组件与全局组件

全局组件只要定义,处处皆可使用,使用简单性能较差;局部组件,定义后需要引入才能使用,使用复杂,性能高于全局组件

    Vue.component('counter', {
      data () {
        return {
          count: 1
        }
      },
      template: `<div @click="count += 1">{{count}}</div>`
    })
    // 局部组件
    const DivCounter = {
      data () {
        return {
          count: 2
        }
      },
      template: `<div @click="count +=1">{{count}}</div>`
    }
    const app = new Vue({
      el: "#app",
      components: {
        DivCounter
      },
      template: `<div>
        <counter/>
        <DivCounter/>
      </div>`
    });

父组件向子组件传值

  1. 基础用法
const DivCounter = {
  // 使用props接收传递的值
  props: ["count"],
  template: `<div>{{count}}</div>`
}
const app = new Vue({
  el: "#app",
  data() {
    return {
      count: 1
    }
  },
  components: {
    DivCounter
  },
  template: `<div>
    // 引入子组件时动态绑定参数值和参数名称(参数名称就是props中接收的名称)
    <DivCounter :count="count"/>
  </div>`
});
  1. props
    可以接收的参数类型包含:String、Boolean、Array、Object、Fuction、Symbol,使用时一般的值如同使用自己的data的方法,函数如同使用自己的methods中的方法

props的几种形式

// 1.最简化的方式-->数组
props:["count"]
// 2. 对象只规定类型
props: {
  count:Number
}
// 3. 对象严格规定
props:{
  count: {
    type: xxx,
    required: true/false,
    default: xxx,
    validator: func
  }
}

单向数据流

通过props传递给子组件的数据不能被子组件修改,原因很简单,一个父组件可以对应多个子组件它的数据可能被用于自身及其他多个子组件,如果简单的在一个子组件中修改,可能会影响其它组件

  1. 解决方案一
props: ["count"],
data () {
  return {
    myCount: this.count, // 复制一份
  }
}

Non_props

  1. 基础用法

类似于props绑定,但是没有props那么会以属性的形式绑定在子组件的最外层,通过inheritAttrs: fasle阻止绑定

const DivCounter = {
  template: `<div><div>myCount</div></div>`
}
const app = new Vue({
  el: "#app",
  data() {
    return {
      count: 1
    }
  },
  components: {
    DivCounter
  },
  template: `<div>
    <DivCounter count="count"/>
  </div>`
});
  1. $attrs

可以将属性或属性的一部分绑定在子组件的任意一个元素上

const DivCounter = {
  template: `<div><div v-bind="$attrs">myCount</div></div>`
  // template: `<div><div :count="$attrs.count">myCount</div></div>` 只使用count
  // 其余地方使用
  // mounted () {
     // console.log(this.$attrs.count);
  // }
}
const app = new Vue({
  el: "#app",
  data() {
    return {
      count: 1
    }
  },
  components: {
    DivCounter
  },
  template: `<div>
    <DivCounter count="count" hello="data" class="hello" style="color: red;"/>
  </div>`
});

子组件向父组件传递信息

  1. $emit
const DivCounter = {
  props: ["count"],
  methods: {
    handleItemClick () {
      // 2. 向父组件传递一个自定义事件和参数
      this.$emit("addOne", 2)
    }
  },
  // 1. 绑定触发的函数
  template: `<div @click="handleItemClick">{{count}}</div>`,
}
const app = new Vue({
  el: "#app",
  data() {
    return {
      count: 1
    }
  },
  components: {
    DivCounter
  },
  methods: {
    handleAddOne(param) {
      this.count += param;
    }
  },
  // 3. 触发父组件中的事件
  template: `<div>
    <DivCounter :count="count" @addOne="handleAddOne"/>
  </div>`
});

插槽slot

方便传递一些标签组件的插入

  1. 一般用法
const DivCounter = {
  template: `
    <form>
      <input />
      <slot><slot>
    </form>
  `,
}
const app = new Vue({
  el: "#app",
  data() {
    return {
      count: 1
    }
  },
  components: {
    DivCounter
  },
  template: `<div>
    <DivCounter>
      <button>按钮</button>
    </DivCounter>
    <DivCounter>
      <div>div</div>
    </DivCounter>
  </div>`
});

值得注意的是slot无法绑定事件,需要绑定事件可以在外包裹一层标签

  1. 具名插槽
// 1. 具名插槽用template包裹(v-slot可以简写为#)
<template v-slot:header>
  <div>header</div>
</template>
// 2. 使用
<slot name="header"></slot>
  1. 作用域插槽

父组件决定子组件的slot为什么dom元素,但是其中的值是由子组件的data决定的,一般{{}}中的值只能在其本身所在的组件内部的data中获取

const List = {
  data() {
    return {
      items: [1, 2, 3],
    }
  },
  template: `
    <div>
      <slot v-for="item in items" :item="item"/>
    </div>
  `,
}
const app = new Vue({
  el: "#app",
  data() {
    return {}
  },
  components: {
    List
  },
  template: `
    <List v-slot="slotProps">
      <div>{{slotProps.item}}</div>
    </List>
  `
});

动态组件

  1. 基础用法

动态组件<components :is="" />通过数据动态决定渲染的组件

const Com1 = {
  template: `<input />`,
}
const Com2 = {
  template: `<div>这是组件二号</div>`,
}
const app = new Vue({
  el: "#app",
  data () {
    return {
      currentItem: "Com1"
    }
  },
  components: {
    Com1,
    Com2
  },
  methods: {
    handleClick () {
      this.currentItem === 'Com1' ? this.currentItem = 'Com2': this.currentItem = 'Com1';
    }
  },
  template: `<div>
    <component :is="currentItem" />
    <button @click="handleClick">切换</button>
  </div>`
});
  1. keep-alive

keep-alive嵌套于动态组件的外层,决定其切换时是否被销毁,同时监听切换事件

posted on   L-GIS  阅读(23)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示