# vue.use()插件的使用&vue.mixin
// 插件定义
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) {
// 逻辑...
}
}
// 插件使⽤用
Vue.use(MyPlugin)
vue.use()使用插件
xxx>install=function(){ //制作插件 }
vue.mixin() 混入扩展vue组件
# use和mixin一起使用的一个例子
export default{
install: function (Vue, options) {
// 1. 添加全局方法或属性
// 2. 添加全局资源
// 时间格式化过滤器,输入内容是number或者Date对象,输出是YYYY-MM-DD HH-MM-SS
Vue.filter('formatTime', function (value) {
Date.prototype.Format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
return new Date(value).Format("yyyy-MM-dd hh:mm:ss");
})
// 2. 添加全局资源
// 添加注入组件时,是否利用console.log来通知的判断条件,也是组件实例属性
Vue.prototype.NOTICE = true;
let a=100;
// 3. 注入组件
// 注入组件,插件加载开始前提示
Vue.mixin({
created: function () {
if (this.NOTICE)
console.log("组件开始加载")
},
mounted(){
console.log("挂载");
console.log(document.getElementById("T1"))
},
destroyed(){
a--;
console.log(a)
//每个运用到的组件都会触发,所以可能触发多次,
},
methods: {
test: function () {
console.log("mixin test");
}
}
})
// 4. 添加实例方法
// 返回数字是输入数字的两倍,如果不是数字或者不能隐式转换为数字,则输出null
// 组件实例方法
Vue.prototype.doubleNumber = function (val) {
if (typeof val === 'number') {
return val * 2;
} else if (!isNaN(Number(val))) {
return Number(val) * 2;
} else {
return null
}
}
// 4. 添加实例方法
// 服务组,将实例方法整合到$service中,避免命名冲突
Vue.prototype.$service = {
//电话号码合法性检查
telNumberCheck: function (tel) {
var pattern = /(^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$)|(^0{0,1}1[3|4|5|6|7|8|9][0-9]{9}$)/;
return pattern.test(tel)
}
}
}
}
//main.js
import Vue from 'vue'
import App from './App.vue'
import login from "./plugins/islogin.js"
import router from './router'
Vue.use(login)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
//App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
<button @click="btn">test方法</button>
<div>{{timer|formatTime}}</div>
<input type="number" v-model="phone" >
</div>
<router-view/>
</div>
</template>
<script>
export default{
name:"app",
data(){
return{
timer:new Date(),
phone:""
}
},
watch:{
phone(v1,v2){
if(this.phone.length==11){
console.log(this.$service.telNumberCheck(this.phone))
}
}
},
mounted(){
setInterval(()=>{
this.timer=new Date()
},1000)
},
methods:{
btn(){
this.test()
}
}
}
</script>
# vueminxin单独使用
export const hi = {
methods: {
sayHello: function() {
console.log('hello from mixin!')
}
},
mounted() {
this.sayHello()
}
}
<template>
<div id="app">
<div id="nav">
<button @click="btn">test方法</button>
</div>
</div>
</template>
<script>
import {hi} from "./plugins/islogin.js"
export default{
name:"app",
mixins:[hi],//mixins引入
methods:{
btn(){
hi.methods.sayHello()
this.sayHello() //两者都可以调用mixin里的方法
}
}
}
</script>
# vue-router源码实现
// krouter.js
import Home from "./views/Home";
import About from "./views/About";
import VueRouter from "./kvue-router";
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{ path: "/", component: Home },
{ path: "/about", component: About }
]
});
// main.js
import router from './krouter'
// kvue-router.js
let Vue;
class VueRouter {
constructor(options) {
this.$options = options;
this.routeMap = {};
this.app = new Vue({
data: {
current: "/"
}
});
}
// 绑定事件
init() {
this.bindEvents();
this.createRouteMap(this.$options);
this.initComponent();
}
bindEvents() {
window.addEventListener("load", this.onHashChange.bind(this), false);
window.addEventListener("hashchange", this.onHashChange.bind(this),
false);
}
// 路由映射表
createRouteMap(options) {
options.routes.forEach(item => {
this.routeMap[item.path] = item;
});
}
initComponent() {
Vue.component("router-link", {
props: {
to: String
},
render(h) {
return <a href={this.to}>{this.$slots.default}</a>;
// return h('a',{
// attrs:{
// href:'#'+this.to
// }
// },[
// this.$slots.default
// ])
}
});
Vue.component("router-view", {
render: h => {
var component = this.routeMap[this.app.current].component;
return h(component);
}
});
}
// 设置当前路路径
onHashChange() {
this.app.current = window.location.hash.slice(1) || "/";
}
}
// 插件逻辑
VueRouter.install = function(_Vue) {
Vue = _Vue;
Vue.mixin({
beforeCreate() {
if (this.$options.router) {
// 确保是根组件时执行一次,将router实例放到Vue原型,以后所有组件实例就均有$router
Vue.prototype.$router = this.$options.router;
this.$options.router.init();
}
}
});
};
← render&$mount vue高级特性 →