http://www.youbaobao.xyz/admin-docs/guide/base/vue.html
实例:$emit 和 $on
$emit 和 $on主要负责事件的定义和消费,实现逻辑的解耦
<html>
<head>
<title>$emit 和 $ontitle>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="root">
<button @click="boost">触发事件button>
div>
<script>
new Vue({
el: '#root',
data() {
return {
message: 'hello vue'
}
},
created() {
this.$on('my_events', this.handleEvents)
},
methods: {
handleEvents(e) {
console.log(this.message, e)
},
boost() {
this.$emit('my_events', 'my params')
}
}
})
script>
body>
html>
官方文档:https://cn.vuejs.org/v2/api/#vm-on
通过断点调试分析
var vm = this
vm._events[event]
判空,为空则赋予它一个空数组,然后把需要绑定的事件方法push进去通过第二步可知,可以多个事件绑定一个执行方法,也可以一个事件同时绑定多个执行方法
官方文档:https://cn.vuejs.org/v2/api/#vm-emit
通过断点调试分析
var vm = this
var lowerCaseEvent = event.toLowerCase()
vm._events[event]
中拿出事件方法,判空通过分析可知,$emit中出现error并不会中断执行只是使用try-catch抛出异常
官方文档:https://cn.vuejs.org/v2/api/#Vue-directive
实例:directive 用法
<html>
<head>
<title>directive 用法title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="root">
<div v-loading="isLoading">{{data}}div>
<button @click="update">更新button>
div>
<script>
Vue.directive('loading', {
update(el, binding, vnode) {
if (binding.value) {
const div = document.createElement('div')
div.innerText = '加载中...'
div.setAttribute('id', 'loading')
div.style.position = 'absolute'
div.style.left = 0
div.style.top = 0
div.style.width = '100%'
div.style.height = '100%'
div.style.display = 'flex'
div.style.justifyContent = 'center'
div.style.alignItems = 'center'
div.style.color = 'white'
div.style.background = 'rgba(0, 0, 0, .7)'
document.body.append(div)
} else {
document.body.removeChild(document.getElementById('loading'))
}
}
})
new Vue({
el: '#root',
data() {
return {
isLoading: false,
data: ''
}
},
methods: {
update() {
this.isLoading = true
setTimeout(() => {
this.data = '用户数据'
this.isLoading = false
}, 3000)
}
}
})
script>
body>
html>
vue自定义指令VNode详解
VNode虚拟DOM学习
需要改造的地方:
else {
const div = document.getElementById('loading')
div && document.body.removeChild(div)
}
官方文档:https://cn.vuejs.org/v2/api/#Vue-component
实例:Vue.component 用法
<html>
<head>
<title>Vue.component 用法title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="root">
<Test :msg="message">Test>
div>
<script>
Vue.component('Test', {
template: '{{msg}}',
props: {
msg: {
type: String,
default: 'default message'
}
}
})
new Vue({
el: '#root',
data() {
return {
message: "Test Component"
}
}
})
script>
body>
html>
ASSET_TYPES.forEach(function (type) {
Vue[type] = function (id,definition) {
function isPlainObject (obj) {return _toString.call(obj) === '[object Object]'}
var _toString = Object.prototype.toString;
为什么用Object.prototype.toString.call(obj)检测对象类型?
definition = this.options._base.extend(definition);
Vue.extend = function (extendOptions) {
var Sub = function VueComponent (options) {this._init(options);};
官方文档:https://cn.vuejs.org/v2/api/#Vue-extend
实例:Vue.extend 用法
<html>
<head>
<title>Vue.extend 用法title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="root">
<Test :msg="message">Test>
div>
<script>
const component = Vue.extend({
template: '{{msg}}',
props: {
msg: {
type: String,
default: 'default message'
}
},
name: 'Test'
})
Vue.component('Test')
new Vue({
el: '#root',
data() {
return {
message: "Test Extend Component"
}
}
})
script>
body>
html>
主要用来生成组件的构造函数VueComponent
Vue.extend = function (extendOptions) {
var Sub = function VueComponent (options) {this._init(options);};
其实本实例作用和上一个相同
官方文档:https://cn.vuejs.org/v2/api/#Vue-extend
实例:Vue.extend 进阶用法
<html>
<head>
<title>Vue.extend 用法2title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<style>
#loading-wrapper {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: rgba(0,0,0,.7);
color: #fff;
}
style>
head>
<body>
<div id="root">
<button @click="showLoading">显示Loadingbutton>
div>
<script>
function Loading(msg) {
const LoadingComponent = Vue.extend({
template: '{{msg}}',
props: {
msg: {
type: String,
default: msg
}
},
name: 'LoadingComponent'
})
const div = document.createElement('div')
div.setAttribute('id', 'loading-wrapper')
document.body.append(div)
new LoadingComponent().$mount('#loading-wrapper')
return () => {
document.body.removeChild(document.getElementById('loading-wrapper'))
}
}
Vue.prototype.$loading = Loading
new Vue({
el: '#root',
methods: {
showLoading() {
const hide = this.$loading('正在加载,请稍等...')
setTimeout(() => {
hide()
}, 2000)
}
}
})
script>
body>
html>
给vue实例添加自定义api,实现$loading
:
Vue.prototype.$loading = Loading
绑定方法'正在加载,请稍等...'
作为参数msg
传入Loading
方法中Vue.extend
的返回值赋值给变量LoadingComponent
const div = document.createElement('div')
创建divdiv.setAttribute('id', 'loading-wrapper')
起名为loading-wrapperdocument.body.append(div)
进行挂载new LoadingComponent().$mount('#loading-wrapper')
实例化一个LoadingComponent
对象,并挂载到前面创建的div上(直接覆盖,因此id必须相同,否则后面移除的时候找不到)const hide = this.$loading('正在加载,请稍等...')
,将this.$loading
的返回值() => {document.body.removeChild(document.getElementById('loading-wrapper'))
赋值给变量hide
,并在赋值过程中执行this.$loading
(this.$loading
执行过程中return的内容不执行)hide()
,延时执行完毕,执行匿名方法() => {document.body.removeChild(document.getElementById('loading-wrapper'))
(this.$loading
执行过程中return的内容),移除挂在的div将一个方法赋值给一个变量的过程中,方法会执行一次,变量获取到的是方法的返回值,而方法的返回值是一个匿名方法(箭头函数),因此变量名即这个匿名函数的方法名,所以这个变量可做方法来用
官方文档:https://cn.vuejs.org/v2/api/#Vue-use
实例:Vue.use 用法
<html>
<head>
<title>Vue.use 用法title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<style>
#loading-wrapper {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: rgba(0,0,0,.7);
color: #fff;
}
style>
head>
<body>
<div id="root">
<button @click="showLoading">显示Loadingbutton>
div>
<script>
const loadingPlugin = {
install: function(vm) {
const LoadingComponent = vm.extend({
template: '{{msg}}',
props: {
msg: {
type: String,
default: 'loading...'
}
}
}, 'LoadingComponent')
function Loading(msg) {
const div = document.createElement('div')
div.setAttribute('id', 'loading-wrapper')
document.body.append(div)
new LoadingComponent({
props: {
msg: {
type: String,
default: msg
}
}
}).$mount('#loading-wrapper')
return () => {
document.body.removeChild(document.getElementById('loading-wrapper'))
}
}
vm.prototype.$loading = Loading
}
}
Vue.use(loadingPlugin)
new Vue({
el: '#root',
methods: {
showLoading() {
const hide = this.$loading('正在加载,请稍等...')
setTimeout(() => {
hide()
}, 2000)
}
}
})
script>
body>
html>