1、混合
混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。
2、自定义指令
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令
3、插件
插件形式一般有很多种,以下最为常见:
// 开始一个插件(myplug.js)
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () { ...}
// 2. 添加全局资源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) { ...}
})
// 3. 注入组件
Vue.mixin({
created: function () { ...}
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) { ...}
}
// 使用插件
import MyPlugin from 'xxx';
Vue.use(MyPlugin)
4、过滤
实现数据的筛选、过滤、格式化。如时间格式化,小写转大写,价格后面都加上¥符号等等。
5、简单例子
5.1、混合
<script type="text/javascript">
// 定义一个混合对象
var myMixin = {
created:function(){
this.hello();
},
methods:{
hello:function(){
console.log('hello mixin');
}
}
}
// vue对象
var vm = new Vue({
el:"#app",
data:{},
mixins:[myMixin],
created:function(){
console.log("hello");
}
});
</script>
// 执行上面代码会依次打印出:“hello mixin”,“hello”
5.2、自定义指令:
// 如:注册一个全局自定义指令 `v-focus` :
Vue.directive('focus',{
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
// 如:注册一个局部自定义指令 `v-focus` :
directives:{
focus:{
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
// 在页面中使用如下:<input v-focus>
5.3、插件的用法
// 实现tip弹窗效果
import './tips.css'; // 引入需要的样式文件
const vueTips = {};
vueTips.install = (Vue, options = {}) => {
//自定义指令实现
Vue.directive('mytip', {
bind: function (el, binding, vnode) {
// 鼠标移入
el.onmouseover = function() {...}
// 鼠标离开
el.onmouseout = function() {...}
}
});
});
export default vueTips;
5.4、过滤的用法
1、创建:
new Vue({
filters:{
myCurrency:function(){
//处理结果
}
}
});
2、使用:
语法:
<any>{{表达式 | 过滤器}}</any>
举个例子:
<h1>{{price | myCurrency}}</h1>
6、简单应用
6.1、使用自定义指令实现一个水波纹效果:(全局注册)
<script type="text/javascript">
Vue.directive('waves', {
bind: function (el, binding) {
// 点击产生的效果(点击事件)
el.addEventListener('click',e=>{
//TODO 处理代码...
},false);
}
});
</script>
html:
<button v-waves >水波纹效果</button>
<button v-waves="{type: 'center'}">水波纹效果</button>
分析:
上面的 "waves" 为指令的名称,在html中需要使用‘v-waves’命名。
binding:
只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
el:指令所绑定的元素,可以用来直接操作 DOM(如button元素)
binding:一个对象,包含以下属性:
name:指令名。
value:绑定的值(如:type: 'center'为最终的值)
具体实现代码:
js
const customOpts = Object.assign({}, binding.value);
// 处理点击操作
const opts = Object.assign({
ele: el, // 波纹作用元素
type: 'hit', // hit点击位置扩散,center中心点扩展
color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
}, customOpts);
const target = opts.ele;
if (target) {
target.style.position = 'relative';
target.style.overflow = 'hidden';
// 获取元素高宽,坐标,上下左右间距
const rect = target.getBoundingClientRect();
let ripple = target.querySelector('.waves-ripple');
// 如果没有找到,开始创建一个节点
if (!ripple) {
ripple = document.createElement('span');
ripple.className = 'waves-ripple';
ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px';
target.appendChild(ripple);
} else {
ripple.className = 'waves-ripple';
}
switch (opts.type) {
case 'center':
ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px';
ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px';
break;
default:
ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px';
ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px';
}
ripple.style.backgroundColor = opts.color;
ripple.className = 'waves-ripple z-active';
return false;
css:
.btn {
background-color: #0094ff;
color: #fff;
font-size: 16px;
user-select: none;
border: none;
border-radius: 5px;
padding: 10px;
outline: none;
height: 100px;
width: 200px;
}
.btn:hover {
background-color: #5eb0ff;
}
.waves-ripple {
position: absolute;
border-radius: 100%;
background-color: rgba(0, 0, 0, 0.15);
background-clip: padding-box;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
opacity: 1;
}
.waves-ripple.z-active {
opacity: 0;
-webkit-transform: scale(2);
-ms-transform: scale(2);
transform: scale(2);
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
}
6.2、实现一个全局时间格式化过滤器
1)全局js文件,多个过滤操作都可以放在这里,这里以时间过滤为例如下:
/**
* 时间转化时间戳
* @param time
* @param cFormat
*/
export function timeFormatting(time, cFormat) {
// 转化为时间戳
let timestamp = Date.parse(new Date(time));
return parseTime(timestamp,cFormat);
}
/**
*
* @param date
* @param cFormat
* @returns {*}
*/
export function formatTotime(date, cFormat) {
date = new Date(Date.parse(date.replace(/-/g, '/')));
// 转化为时间戳
date = date.getTime();
return parseTime(date, cFormat);
}
/**
*
* @param time
* @param cFormat
* @returns {*}
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return null;
}
if ((time + '').length === 10) {
time = +time * 1000
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
let date;
if (typeof time == 'object') {
date = time;
} else {
date = new Date(parseInt(time));
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
};
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key];
if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1];
if (result.length > 0 && value < 10) {
value = '0' + value;
}
return value || 0;
});
return time_str;
}
2)注册:
import * as filters from './filters'; // 全局vue filter
// register global utility filters.
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
});
- 使用:
<span>{{ xxx_time | timeFormatting('{y}-{m}-{d} {h}:{i}') }}</span>
如 xxx_time = '2018-02-09T12:08:21.000Z' 最终结果为:2018-02-09 20:08
如时间格式为2018/02/09需要转化为2018-01-09可以这样实现
<span>{{'2018/02/09' | formatTotime('{y}-{m}-{d}') }}</span> 结果为:2018-02-09
上面最终的结果都是将某种格式的时间转化为时间戳,再由parseTime函数转化为固有格式。
所以如果得到的是时间戳可以直接这么写就可以了:
<span>{{'需要转化的时间戳' | parseTime('{y}-{m}-{d}') }}</span>
网友评论