vue如何自定义组件

下面是一个自定义的组件的源代码

<template>
  <div>
    测试 type
    <d-button type="primary">primary</d-button>
    <d-button type="danger">danger</d-button>
    <d-button>default</d-button>

    测试 size
    <d-button size="small">primary</d-button>
    <d-button size="large">danger</d-button>
    <d-button>default</d-button>
    错误传值
    <d-button size="big"></d-button>
    点击事件
    <d-button @click="handle">传值</d-button>
    <!-- 组件绑定的事件默认是不会被浏览器识别的,我们需要做额外的处理让事件生效,有俩种方案, 
      1、添加 .native 修饰符,添加了这个修饰符,事件就会绑定到组件的根元素身上
      2、把click 当成自定义事件 通过 $emit 执行 (通用写法)
    -->
  </div>
</template>

<script>
import DButton from "./components/Button/index.vue";
export default {
  props: {},
  data() {
    return {};
  },
  created() {},
  mounted() {},
  watch: {},
  computed: {},
  methods: {
    handle(e) {
      console.log("点击了", e);
    },
  },
  components: {
    DButton,
  },
};
</script>
<style lang="less" scoped>
</style>

b-button.vue源代码

<template>
  <button :class="[typeClass, sizeClass]" class="h-btn" @click="clickBtn">
    <!-- 
          h-btn是一个基础类名,不管有没有,这个类都有
          动态渲染 具体的 颜色类 即可 
      -->
    <slot></slot>
  </button>
  <!-- 
      1、事件如果写道原生支持的标签身上,会被直接识别为原生事件 <button @click=handleder></button>
      2、事件如果写在 自定义组件身上,默认状态会被识别为自定义事件 <d-button @click="hander1"></d-button>
        1、添加 .native 修饰符,可以让 vue 帮助我们把事件绑定成浏览器支持的原生事件
        2、就当成自定义事件识别,然后按照 父子组件 通信的手段,通过子组件内事件触发,然后调用 $emit 方法触发即可。

   -->
</template>

<script>
export default {
  // 我们需要根据 不同的 type 的值,给button 绑定不同的类名
  // 'default' => h-btn-default
  // 'primary' => h-btn-primary
  // 'danger'  => h-btn-danger
  // type => h-btn-type
  props: {
    type: {
      type: String, // 必须是字符串类型
      default: "default", // 默认值
    },
    // 用来控制  button 的大小
    size: {
      type: String,
      default: "default",
      validator: function (value) {
        //   value 表示 这个 属性的值
        const sizeList = ["small", "large", "default"];
        // 如果传入的参数不在可选参数 的列表中,给出 用户提示 告诉他,那个参数传错了
        return sizeList.includes(value); // 判断这个值,数组中 有没有 返回值是 true 或者 false
        // 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告

        /* 
        如, 传入 size="big"
        控制台,则会报错 Invalid prop: custom validator check failed for prop "size".
        */
      },
    },
  },
  data() {
    return {};
  },
  created() {},
  mounted() {},
  watch: {},
  computed: {
    typeClass() {
      return `h-btn-type-${this.type}`;
    },
    sizeClass() {
      return `h-btn-size-${this.size}`;
    },
  },
  methods: {
    clickBtn(e) {
      // 触发 父组件 传下来的自定义事件  click
      this.$emit("click", e);
    },
  },
  components: {},
};
</script>
<style lang="less" scoped>
// 自己编写自定义组件的适合,  scoped 是必须要加上的,不能影响其他组件的样式
// 默认背景色 默认大小
.h-btn {
  line-height: 1.499;
  position: relative;
  display: inline-block;
  font-weight: 400;
  white-space: nowrap;
  text-align: center;
  background-image: none;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  touch-action: manipulation;
  padding: 5px 10px;
  font-size: 14px;
  border-radius: 4px;
  color: rgba(0, 0, 0, 0.65);
  background-color: #fff;
  border: 1px solid #d9d9d9;
}
.h-btn:focus {
  outline: 0;
}
// primary类
.h-btn-type-primary {
  color: #fff;
  background-color: #1890ff;
  border-color: #1890ff;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
}
// danger类
.h-btn-type-danger {
  color: #fff;
  background-color: #ff4d4f;
  border-color: #ff4d4f;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
}
// size:small
.h-btn-size-small {
  padding: 4px 8px;
  font-size: 12px;
}
// size:large
.h-btn-size-large {
  padding: 6px 12px;
  font-size: 16px;
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值