今天小編給大家分享一下Vue中Vue.extend()如何使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
Vue.extend 屬于 Vue 的全局 API,在實際業務開發中我們很少使用,因為相比常用的 Vue.component 寫法使用 extend 步驟要更加繁瑣一些。但是在一些獨立組件開發場景中,Vue.extend + $mount 這對組合是我們需要去關注的。
在 vue 項目中,初始化的根實例后,所有頁面基本上都是通過 router 來管理,組件也是通過 import 來進行局部注冊,所以組件的創建不需要去關注,相比 extend 要更省心一點點。但是這樣做會有幾個缺點:
組件模板都是事先定義好的,如果我要從接口動態渲染組件怎么辦?所有內容都是在 #app 下渲染,注冊組件都是在當前位置渲染。如果我要實現一個類似于 window.alert() 提示組件要求像調用 JS 函數一樣調用它,該怎么辦?
這時候,Vue.extend + vm.$mount 組合就派上用場了。
基礎用法
Vue.extend( options )
參數:{Object} options
用法:使用基礎 Vue 構造器,創建一個“子類”。參數是一個包含組件選項的對象;
data 選項是特例,需要注意: 在 Vue.extend() 中它必須是函數;
<div id="mount-point"></div>
// 創建構造器
var Profile = Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 創建 Profile 實例,并掛載到一個元素上。
new Profile().$mount('#mount-point')
// 結果如下:
<p>Walter White aka Heisenberg</p>可以看到,extend 創建的是 Vue 構造器,而不是我們平時常寫的組件實例,所以不可以通過 new Vue({ components: testExtend }) 來直接使用,需要通過 new Profile().$mount(’#mount-point’) 來掛載到指定的元素上。
第二種寫法
可以在創建實例的時候傳入一個元素,生成的組件將會掛載到這個元素上,跟 $mount 差不多。
// 1. 定義一個vue模版
let tem ={
template:'{{firstName}} {{lastName}} aka {{alias}}',
data:function(){
return{
firstName:'Walter',
lastName:'White',
alias:'Heisenberg'
}
}
// 2. 調用
const TemConstructor = Vue.extend(tem)
const intance = new TemConstructor({el:"#app"}) // 生成一個實例,并且掛載在 #app 上今天,我們使用Vue.extend()編程式的寫法來編寫一個vue插件,本質是將插件實例掛載到Vue的原型上。然后,就像element-ui的toast組件那樣,使用this.$toast()實例方法去調用插件。
使用Vue這個基礎構造器,構造出一個“子類”,其實就是個構造函數,通過new運算符生成vue實例。具體見官方文檔Vue-extend。
比如,我們要實現個彈窗功能。通過編程式導航,我們就不用在模板中寫了,可以使用js直接編寫喚出彈窗。首先,我們正常的編寫彈窗組件。如下:
<template>
<div class="gulu-toast" :class="toastClasses">
<div class="toast" ref="toast">
<div class="message">
<slot v-if="!enableHtml"></slot>
<div v-else v-html="$slots.default[0]"></div>
</div>
<div class="line" ref="line"></div>
<span class="close" v-if="closeButton" @click="onClickClose">
{{closeButton.text}}
</span>
</div>
</div>
</template><script>
//構造組件的選項
export default {
name: 'Toast',
props: {
autoClose: {
type: [Boolean, Number],
default: 5,
validator (value) {
return value === false || typeof value === 'number';
}
},
closeButton: {
type: Object,
default () {
return {
text: '關閉', callback: undefined
}
}
},
enableHtml: {
type: Boolean,
default: false
},
position: {
type: String,
default: 'top',
validator (value) {
return ['top', 'bottom', 'middle'].indexOf(value) >= 0
}
}
},
mounted () {
// 這里是為了防止不斷點擊,出現多個彈窗
const toast = document.getElementsByClassName('gulu-toast')[0]
toast && document.body.removeChild(toast)
this.updateStyles()
this.execAutoClose()
},
computed: {
toastClasses () {
return {
[`position-${this.position}`]: true
}
}
},
methods: {
updateStyles () {
this.$nextTick(() => {
this.$refs.line.style.height =
`${this.$refs.toast.getBoundingClientRect().height}px`
})
},
execAutoClose () {
if (this.autoClose) {
setTimeout(() => {
this.close()
}, this.autoClose * 1000)
}
},
close () {
this.$el.remove()
this.$emit('close')
this.$destroy()
},
onClickClose () {
this.close()
if (this.closeButton && typeof this.closeButton.callback === 'function') {
this.closeButton.callback(this)//this === toast實例
}
}
}
}
</script>接下來,就是Vue.extend()出場了。
import Toast from './src/toast.vue';
Toast.install = function (Vue) {
// 其實就是全局掛載使用
Vue.prototype.$toast = function (text, props) {
const ToastMain = Vue.extend(Toast)
const instance = new ToastMain({
propsData: props // 這里必須是propsData
})
instance.$slots.default = [text] // 插槽內容
// instance.$mount().$el 該段代碼意義為:
// 文檔之外渲染,并且獲取該實例的根DOM元素,將其插入到body元素中。
document.body.appendChild(instance.$mount().$el)
}
}
export default Toast我們在main.js入口文件中,使用Vue.use()安裝后,就可以在任何地方使用了~~。
this.$toast("關閉嗎?", {
closeButton: {
text: "關閉",
callback: () => {
console.log('已經關閉了');
},
},
autoClose: 12,
position: 'bottom'
});小結:
首先,Vue.extend 獲得是一個構造函數,可以通過實例化生成一個 Vue 實例。
實例化時可以向這個實例傳入參數,但是需要注意的是 props 的值需要通過 propsData 屬性來傳遞。
還可以通過$slots來自定義插槽內容。
以上就是“Vue中Vue.extend()如何使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。