插件基础
1. Vue.use去使用一个插件,并且会执行install方法
如果use传入的参数是一个方法且方法没有install方法,就执行这个方法
var a = function () {
console.log(1)
}
Vue.use(a)
// 控制台打印1
如果use传入的参数有install方法,就执行install方法
var a = function () {
console.log(1)
}
a.install = function () {
console.log('install')
}
Vue.use(a)
// 控制台打印install
2.Vue.mixin往vue的全局中混入自定义的操作
在install方法使用mixin混入全局变量
// 混入
var a = function () {
console.log(1)
}
a.install = function (vue) {
vue.mixin({
data: function () {
return {
c: 123456
}
}
})
}
Vue.use(a)
// 使用
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>{{c}}</p>
</div>
</template>
混入全局方法
// 混入
var a = function () {
console.log(1)
}
a.install = function (vue) {
vue.mixin({
data: function () {
return {
c: 123456
}
},
methods: {
globalMethod: function () {
console.log('this is global method')
}
}
})
}
Vue.use(a)
// 使用
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>{{c}}</p>
</div>
</template>
<script>
export default {
name: 'test',
data () {
return {
msg: 'test'
}
},
mounted () {
this.globalMethod()
}
}
// 控制台打印this is global method
混入生命周期
var a = function () {
console.log(1)
}
a.install = function (vue) {
vue.mixin({
data: function () {
return {
c: 123456
}
},
created (this) {
console.log('i am create')
console.log(this) // this 指向当前vue实例
}
})
}
Vue.use(a)
// 每个vue实例打印一次i am create
3.vue工具方法
warn extend mergeOptions defineReactive
defineReactive: 监听对象的属性变化
var a = function () {
console.log(1)
}
var test = {
a: 1
}
setTimeout(function () {
test.a = 4444
}, 5000)
a.install = function (vue) {
// vue工具方法
console.log(vue.util)
vue.util.defineReactive(test, 'a')
vue.mixin({
data: function () {
return {
c: 123456
}
},
beforeCreate () {
this.test = test
},
created () {
console.log('i am create')
}
})
}
4. 实现简单的vue-router
代码实现
class HistoryRoute {
constructor () {
// 需要监听的当前路径
this.current = null
}
}
class vueRouter {
// options: 路由配置
constructor (options) {
this.mode = options.mode || 'hash'
this.routes = options.routes || []
this.routersMap = this.createMap(this.routes)
this.history = new HistoryRoute()
this.init()
}
init () {
if (this.mode === 'hash') {
// 自动加#号
if (location.hash !== '') {
location.hash = '/'
}
// location.hash ? '' : location.hash = '/'
// 初始化加载
window.addEventListener('load', () => {
this.history.current = location.hash.slice(1)
})
// 监听hash变化
window.addEventListener('hashchange', () => {
console.log('change')
this.history.current = location.hash.slice(1)
})
}
}
// 路由数组改为对象
createMap (routes) {
return routes.reduce((memo, current) => {
memo[current.path] = current.component
return memo
}, {})
}
}
vueRouter.install = function (vue) {
// 注意判断插件是否已经注册
if (vueRouter.install.installed) {
return false
}
vueRouter.install.installed = true
vue.mixin({
beforeCreate () {
if (this.$options && this.$options.router) {
this._root = this
this._router = this.$options.router
vue.util.defineReactive(this, 'current', this._router.history)
} else {
this._root = this.$parent._root
}
// $router私有 外部只能访问不能修改
Object.defineProperty(this, '$router', {
get () {
return this._root._router
}
})
}
})
// 渲染对应组件
vue.component('router-view', {
render (h) {
let current = this._self._root._router.history.current
let routerMap = this._self._root._router.routersMap
return h(routerMap[current])
}
})
}
export default vueRouter
使用
import Vue from 'vue'
import Router from '../myrouter'
import HelloWorld from '@/components/HelloWorld'
import Test from '@/components/test'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/test',
name: 'Test',
component: Test
}
]
})