自己需要知道自定义组件的一些细节
data 必须是一个函数
data () {
return {
......
}
}
一个组件的
data选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝,相互之间不会因为组件的复用而影响到其他的实例
全局注册和局部注册
// 注册组件,传入一个扩展过的构造器
Vue.component(
'myComponent',
Vue.extend({
/* ... */
})
)
// 注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component('my-component', {
/* ... */
})
Vue.extend(options)
使用基础 Vue 构造器,创建一个“子类”
Vue.nextTick(cb)
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
Vue.nextTick(() => {...})
// promise
Vue.nextTick().then(() => {...})
判断是否是服务端还是客户端
Node 和浏览器之间存在许多微小的环境差异,全局化组件需要注册在 window 上,如果在 Node 中,由于 window 不存在,程序会报错,可以使用下面两种方法避免在服务端使用 window
void 0 和 undefined 、 null
undefined表示未定义, 一般我们可以用全局变量undefined(就是名为undefined的这个变量) 来表示这个值
但是 JS 中undefined只是一个变量,并不是一个关键字,可以被篡改
解决方法:void可以把任何一个表达式变成undefined,一般使用void 0来获取undefined值
typeof window === void 0null是 JS 中的关键字,可以使用null变量来获取null的值
使用
typeof对window进行判断,即使window不存在, 也不会报错,只会返回undefined
使用typeof判断window是否存在,如果 返回的值是undefined,则不会继续后续对window的操作和注册全局的组件
process.browser在浏览器中它返回 true,而在 Node 中它返回 false, 也可以用来判断是服务端还是客户端
全局化挂载组件
- 首先完成一个简单的组件
<!-- SuccessBox.vue -->
<template>
<div class="success-wrapper center-flex" @click="close" v-if="visible">
<div class="success-container" @click.stop>
<div class="bg-container">
<img src="../assets/success_icon.png" alt="" class="bg-img" />
</div>
<div class="success-header">
{{data.header}}
</div>
<div class="success-detail" v-for="(item, key) in data.detail" :key="key">
{{item}}
</div>
<div class="success-tip" v-if="data.tip">
{{data.tip}}
</div>
<div class="success-button" @click.stop="close">
确认
</div>
</div>
</div>
</template>
<script>
export default {
name: 'SuccessBox',
props: {},
data() {
return {
visible: true,
data: {
header: '购买成功',
detail: ['购买成功!', '请在门店支付订单后进行兑换!'],
tip: ''
}
}
},
methods: {
close() {
this.visible = false
}
}
}
</script>
- 挂在到全局对象
window上
// utils/SuccessBox.js
import Vue from 'vue'
const SuccessBox = Vue.extend(require('@/common/successBox.vue').default)
let instance
export default {
show: (data = {}, callback) => {
if (typeof document === 'undefined') return // 服务端渲染
// 挂载到全局对象上
if (!instance) {
instance = new SuccessBox({
el: document.createElement('div')
})
document.body.appendChild(instance.$el)
}
if (callback) instance.callback = callback
instance.data = { ...instance.data, ...data }
Vue.nextTick(() => {
instance.visible = true
})
}
}
- 挂载到全局
// nuxt.config.js
plugins: [
{ src: '~plugins/vue-awesome-swiper.js', ssr: false }, // swiper
'~plugins/$SuccessBox.js'
],