Javascript

Vue的UI组件开发

本文主要是介绍Vue的UI组件开发,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

github地址 ,本来是个停车场实训项目,自己在上面又加了点内容 介绍地址

总体

在这里插入图片描述

同时也实现了比较普通的响应式布局,配合媒体查询和flex实现。
在这里插入图片描述


弹出框

这个弹出框的遮罩实现有问题,看源代码感觉是插入body里面,而我是直接插入到这个fixed的盒子上面,样式直接照搬element-ui的,vue的动画效果也直接搬运源代码,自己写的动画有点烂。

 <template>
  <transition name="dialog-fade">
 
      <div
      class="el-dialog__wrapper"
      v-show="visible"
      
    >
      <div
        ref="dialog"
        class="el-dialog"
        :class="[{ 'is-fullscreen': fullscreen, 'el-dialog--center': center }]"
        :style="style"
      >
       <div class="el-dialog__header">
            <slot name="title">
            <span class="el-dialog__title">{{ title }}</span>
          </slot>

          <button
            type="button"
            class="el-dialog__headerbtn"
            aria-label="Close"
            v-if="showClose"
            @click="handleClose">
            <i class="el-dialog__close el-icon el-icon-close"></i>
          </button>
       </div>
        <div class="el-dialog__body"><slot></slot></div>
          <div class="el-dialog__footer"><slot name="footer"></slot></div>
      </div>
      <!-- 暂时把点击事件移到遮罩上面 -->
      <div class="v-modal"   @click.self="handleWrapperClick"></div>
    </div>
    
  </transition>
</template>

<script >
export default {
  name: "FanDialog",

  props: {
    title: {
      type: String,
      default: "",
    },

    // modal    是否需要遮罩层
    modal: {
      type: Boolean,
      default: true,
    },

    // close-on-press-escape    是否可以通过按下 ESC 关闭 Dialog    
      closeOnPressEscape: {
        type: Boolean,
        default: true
      },

    // close-on-click-modal    是否可以通过点击 modal 关闭 Dialog
    closeOnClickModal: {
      type: Boolean,
      default: true,
    },

    // fullscreen    是否为全屏 Dialog
    fullscreen: Boolean,

    //是否居中
    center: {
      type: Boolean,
      default: false,
    },
     //关闭前的回调,会暂停 Dialog 的关闭
      beforeClose: Function,

    // show-close    是否显示关闭按钮
    showClose: {
      type: Boolean,
      default: true,
    },

    // width    Dialog 的宽度
    width: {
        type:String,
    },
    //双向绑定
    visible: {
      type: Boolean,
      default: true,
    },

    // top    Dialog CSS 中的 margin-top 值
    top: {
      type: String,
      default: "15vh",
    },
  },
    
  data() {
      return {
          closed: false
      }
  },
 
  watch:{
      visible(val){
          this.closed=val
          console.log(val);
  
      } 
  },

  computed: {
      style() {
        let style = {};
        if (!this.fullscreen) {
          style.marginTop = this.top;
          if (this.width) {
            style.width = this.width;
          }
        }
        return style;
      }
    },


  methods: {
    // 点击dialog自身
    handleWrapperClick() {
      //是否开启可以点击外界区域关闭
      if (!this.closeOnClickModal) return;
      this.handleClose();
    },

    // 关闭dialog
    handleClose() {
      //如果有回调函数 先执行回调函数
      if(typeof this.beforeClose=='function')
      {
        this.beforeClose(this.hide())
        
      }else{
        this.hide();
      }
    },
    // 隐藏dialog
    hide() {
      
      this.$emit("update:visible", false);
    },
  },
  destroyed(){
      console.log('我被摧毁了');
  }
};
</script >

在这里插入图片描述


输入框

挺多功能没实现,写的时候把理解且自己能够完全实现的功能先完成了

v-model的组件就是@input事件实现双向绑定,键入值就会触发。

这个组件主要自己要知道输入框的原生事件

<template>
  <div 
  class="fan_input"
   
  >
    <template>

           <input
       class="input_defalut"
       ref="input"
       :class="[
       {
         'is-disabled':disabled
       }
       ]"
       :disabled="inputdisabled"
        v-bind="$attrs"
        v-bind:value="value"
        :readonly="readonly"
        @input="handleInput"
        @focus="handleFocus"
        @blur="handleFBlur"
  
      >


    </template>
  
  </div>
</template>

<script>
export default {
  name:'FanInput',

     props: {
      // value / v-model    绑定值    string / number    —
      value: [String, Number],
      disabled:Boolean,
      focused:Boolean,
      readonly:Boolean
     },

      methods: {
         // 聚焦
      focus() {
        this.getInput().focus();
      },
      // 失焦
      blur() {
        this.getInput().blur();
      },
        //双向绑定
        handleInput(e)
        {
          this.$emit('input',e.target.value)
        },
         
         //聚焦事件
         handleFocus(e){
           this.$emit('focus', e);
         },
          //失焦事件
         handleFBlur(e){
           this.$emit('blur', e);
         },


        //获取ref
        getInput()
        {
          return this.$refs.input
        }
      },

     computed:{
         // 监听原生值
      nativeInputValue() {
        return this.value === null || this.value === undefined ? '' : String(this.value);
      },
      //是否被禁用
      inputdisabled(){
        
        return this.disabled
      },
   
    
    }
}
</script>

在这里插入图片描述


标记

主要认识上标sub下标sup

在这里插入图片描述


图片

第一次了解到css的object-fit属性,对图片进行处理剪切

在图片加载的时候自己定义了loading的样式

对插槽理解运用也更加熟练。

(侧边栏刷新没有记忆下来index值,导致没有到指定位置,本地储存可以实现,不知道有没有更好的方法)

<template>
<div class="fan-image">

     <slot v-if="loading" name="placeholder">
      <i class="el-icon-loading fan-loading-img"></i>
    </slot>

    <slot v-else-if="error" name='error'>
        <div class="fan-image__error">加载失败</div>
    </slot>
      <img
  v-else
  class="fan-image__inner"
  :src="src"
  :alt="alt"
  :style="{ 'object-fit': fit }">
</div>

</template>

<script>
export default {
    name:'FanImage',

    props:{

        src:String,
        alt:String,
        fit:String,
      
},

//监听src变化
    watch:{
        src:{
            handler(val){
                this.loadImage(val);
        },
            immediate:true
    }
},

    data() {
        return {
            error:false,
            loading:false
        }
},

    methods: {
         // 加载图片
      loadImage(val) {
        // reset status
        this.loading=true
       setTimeout(()=>{
            this.error = false;

        const img = new Image();
        img.onload = this.handleLoad.bind(this);
        img.onerror = this.handleError.bind(this);
        img.src = val;
       },500)
      },
      // load    图片加载成功触发   
      handleLoad(e) {
        this.loading=false
        this.$emit('load', e);
      },
       // error    图片加载失败触发    
      handleError(e) {
        this.loading=false
        this.error = true;
        this.$emit('error', e);
      },
    },


   
}
</script>

在这里插入图片描述

在这里插入图片描述


总结

看源码自己去写组件还是有很大的收获的,以前看vue文档会很迷糊,但现在配合组件开发会有很大的收获。

现在要结合vue文档和实例一起使用,才能高效性学习。

这篇关于Vue的UI组件开发的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!