前端的一些封装

封装框架组件

方法一(自己写框架时可以这么干):

假设我们自己封装了一个 组件 my-demo,并且在 组件A 中调用了组件 my-demo

组件 my-demo 中:

  1. HTML代码该怎么写还怎么写
  2. CSS 代码该怎么写还怎么写
  3. JS 代码:
    1. 原来写在 data 中的变量,现在要写到 prop
    2. 原来写在 methods 中的方法,现在要把事件发送给父组件

组件A 中:

  1. import 导入封装的组件
  2. components 中注册封装的组件
  3. 在 HTML 中使用封装的组件

DEMO:

开发框架(库)以及IDE:
IDE:HBuilder X (3.1.13.20210514 版本)
框架:vue(2.0 版本)、uniapp、uView (1.8.4 版本)、ColorUi(2.1.6 版本)

封装的组件 components/my-demo/my-demo.vue

<template>
	<view>
		<view v-for="(item, index) in listSon" :key="index" @click="doClose(index, 'HelloWorld')">
			<view v-if="show">
				<view>小组号:{{ num }}</view>
				<view>姓名:{{ item.name }}</view>
				<view>年龄:{{ item.age}}</view>
			</view>
		</view>
	</view>
</template>

<script>
export default {
	name: "my-demo",
	props: {
		list: {
		// 数组,默认为空
			type: Array,
      		default: [],
		},
		show: {
			// 是否显示,默认显示
			type: [Boolean, String],
      		default: true,
		},
		num: {
			// 数字,默认0
			type: [Number, String],
      		default: 0,
		}
	},
	data() {
    	return {
      		listSon: this.list,
    	};
  	},
  	watch: {
    	list(val) {
      		this.listSon= val;
    	},
  	},
	methods: {
		doClose(index, msg) {
			// 发送事件给父组件
			// 父组件通过 @clickThis 触发,且可以获得两个参数
			this.$emit("clickThis", index, msg);
		}
	}
}
</script>

<style>
// 略
</style>

在组件A中,调用封装的组件:

<template>
	<view>
		<my-demo
        :list="theList"
        :show="theShow"
        :num="theNum"
        @clickThis="doThis"
      ></my-demo>
	</view>
</template>

<script>
import myDemo from "@/components/my-demo/my-demo.vue";
export default {
	components: { myDemo },
	data: {
		return {
			theList: [1,3,5,7,9],
			theShow: false,
			theNum: 520
		}
	},
	methods: {
		doThis(index, msg) {
			this.theNum = index;
			this.theList.push(8);
			this.theShow = !this.theShow;
		}
	}
}
</script>

<style>
// 略
</style>

番外:
自己写是很容易会出现此 BUG:

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value.
如图:在这里插入图片描述
原因大多是:在子组件中改动了 props 中的值。
解决办法是:在子组件的 data 中声明变量,将 props 的值赋给此变量,通过 watch 监听改变变量。这样避免了直接更改 props 中的值,就不会报错。


方法二:

以封装 ElementUIMessage 消息提示 为例

  • 官方提供的使用教程:
<template>
  <el-button :plain="true" @click="open2">成功</el-button>
</template>

<script>
  export default {
    methods: {
      open2() {
        this.$message({
          message: '恭喜你,这是一条成功消息',
          type: 'success'
        });
      },
    }
  }
</script>
  • 自定义框架的$message 方法为 $baseMessage,并使$baseMessage可以全局使用:

1、在 vue 原型上定义 $baseMessage

src/utils/prototype.js

import { Message } from 'element-ui'

const install = (Vue) => {
    /* 全局Message */
    Vue.prototype.$baseMessage = (message, type) => {
        Message({
            offset: 60,
            showClose: true,
            message: message,
            type: type,
            dangerouslyUseHTMLString: true,
            duration: 3000,
        })
    }
}

if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue)
}

export default install

2、引入自己定义的(亦可在main.js中直接引入):

src/plugins/index.js

/**
* @author mygoes mygoes@sohu.com
* @description 插件的公共引入
*/

import Vue from 'vue'
import MyGoes from '@/utils/prototype'

Vue.use(MyGoes)

3、在main.js 中引入:

main.js

import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import './plugins'

Vue.use(ElementUI);

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

4、在页面中使用:

可以用this.直接使用 $baseMessage
也可以用Vue.prototype.使用 $baseMessage,但记得 import 引入一下 Vue

<template>
  <div>
    <el-button @click="btn">点击测试1</el-button>
    <el-button @click="btn2">点击测试2</el-button>
  </div>
</template>

<script>
import Vue from "vue";
export default {
  methods: {
    btn() {
      Vue.prototype.$baseMessage("测试1成功", "success");
    },
    btn2() {
      this.$baseMessage("测试2成功", "success");
    },
  },
};
</script>

项目源码

分割图

模块封装

在模块中对外输出变量:

// hello.js

'use strict';

var s = 'Hello';

function greet(name) {
    console.log(s + ', ' + name + '!');
}

module.exports = greet;

引入其他模块输出的对象:

// world.js

'use strict';

// 引入hello模块:
var greet = require('./hello');

var s = 'Michael';

greet(s); // Hello, Michael!

分割图

一些常用 js 的封装:

时间倒计时(现在 到 目标时间)

	/**
     * @description:时间倒计时(现在 到 目标时间)
     * @param {date} 目标时间: '2020.11.17 17:54:00'
     * @return: 剩余时间
     */
    Countdown = (date) => {
        date = date.replace(/\./g, '/');
        let timestamp = (new Date(date)).valueOf();
        let nowStr = (new Date()).valueOf();
        let remain = (timestamp - nowStr) / 1000;
        if (remain < 0) {
            remain = 0;
        }
        let days = Math.floor(remain / 3600 / 24),
            hours = Math.floor((remain / 3600) % 24),
            minutes = Math.floor((remain % 3600) / 60),
            seconds = Math.floor((remain % 3600) % 60);
        if (hours < 10) hours = "0" + hours;
        if (minutes < 10) minutes = "0" + minutes;
        if (seconds < 10) seconds = "0" + seconds;
        return {
            days: days,
            hours: hours,
            minutes: minutes,
            seconds: seconds,
        }
    };

	// 尝试使用:
    console.log(Countdown('2080.11.17 00:00:00'));

分割图

时间转换(2022-11-18T08:47:14.502Z 到 2022/11/18 08:47:14)

	renderTime = (date) => {
		let dateee = new Date(date).toJSON();
		return new Date(dateee).toISOString().replace(/T/g, ' ').replace(/-/g, '/').replace(/\.[\d]{3}Z/, '')
	}

	// 尝试使用:
	console.log('时间转换', renderTime('2020-11-18T08:47:14.502Z'));

时间 2020-11-18T08:47:14.502Z 已转换为 2020/11/18 08:47:14
可对replace进行修改实现自定义的时间输出格式。

分割图

浮点数转换为金钱大写

/**
 * @description:将浮点数转换为金钱大写
 * @method cnMoneyFormat
 * @param {Number} money 浮点数
 */
export function changeMoneyFormat(money) {
  var cnMoney = '零元整'
  var strOutput = ''
  var strUnit = '仟佰拾亿仟佰拾万仟佰拾元角分'
  money += '00'
  var intPos = money.indexOf('.')
  if (intPos >= 0) {
    money = money.substring(0, intPos) + money.substr(intPos + 1, 2)
  }
  strUnit = strUnit.substr(strUnit.length - money.length)
  for (var i = 0; i < money.length; i++) {
    strOutput +=
      '零壹贰叁肆伍陆柒捌玖'.substr(money.substr(i, 1), 1) +
      strUnit.substr(i, 1)
  }
  cnMoney = strOutput
    .replace(/零角零分$/, '整')
    .replace(/零[仟佰拾]/g, '零')
    .replace(/零{2,}/g, '零')
    .replace(/零([亿|万])/g, '$1')
    .replace(/零+元/, '元')
    .replace(/亿零{0,3}万/, '亿')
    .replace(/^元/, '零元')
  return cnMoney
}

分割图

示意图

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值