0
我是Vue.js的新手,但試圖去掌握它。到目前爲止,它已經進展順利,而且我還有很長的路要走,但我堅持擴展父母模板。Vue.js + Require.js擴展父項
我正在試圖使擴展默認小部件佈局(在Boostrap中)的儀表板小部件。請注意,下面的代碼使用Vue,Require,Underscore & Axios。
父文件 - _Global.vue
<template>
<div class="panel panel-default">
<div class="panel-heading">
<b>{{ widgetTitle }}</b>
<div class="pull-right">
<a href="#" v-on:click="toggleMinimized"
v-bind:title="(isMinimized ? 'Show widget' : 'Hide widget')">
<i class="fa fa-fw" v-bind:class="isMinimized ? 'fa-plus' : 'fa-minus'"></i>
</a>
</div>
</div>
<div class="panel-body" v-if="!isMinimized">
<div class="text-center text-muted" v-if="!isLoaded">
<i class="fa fa-spin fa-circle-o-notch"></i><br />
</div>
<parent v-if="isLoaded">
<!-- parent content should appear here when loaded -->
</parent>
</div>
</div>
</template>
<script>
export default {
// setup our widget props
props: {
'minimized': {
'default': false,
'required': false,
'type': Boolean
}
},
// define our data
data: function() {
return {
widgetTitle: 'Set widget title in data',
isLoaded: false,
isMinimized: this.$props.minimized
}
},
// when vue is mounted, open our widget
mounted: function() {
if(!this.isMinimized) {
this.opened();
}
},
// define our methods
methods: {
// store our widget state to database
storeWidgetState: function() {
// set our data to send
let data = {
'action' : 'toggleWidget',
'widget' : this.$options._componentTag,
'state' : !this.isMinimized
};
// post our data to our endpoint
axios.post(axios.endpoint, data);
},
// toggle our minimized data
toggleMinimized: function (e) {
// prevent default
e.preventDefault();
// toggle our minimized state
this.isMinimized = !this.isMinimized;
// trigger opened if we aren't minimized
if(!this.isMinimized) this.opened();
// save our widget state to database
this.storeWidgetState();
},
// triggered when opened from being minimized
opened: function() {
console.log('opened() method is where all widget logic should be placed');
}
}
}
</script>
子文件 - Example.vue 應該使用_Global.vue混入延伸,然後內.panel-body
<template>
<div>
I want this content to appear inside the .panel-body div
{{ content }}
<img v-bind:src="image.src" v-bind:alt="image.alt"
v-if="image.src" class="img-responsive" style="margin: 0 auto" />
</div>
</template>
<script>
// import our widgets globals
import Global from './_Global.vue'
export default {
components: {
'parent': {
// what can I possibly put here??
}
},
// use our global mixin for all widgets
mixins: [Global],
// setup our methods for this widget
methods: {
opened: _.debounce(function() {
// make sure this can only be opened once
if(this.hasBeenOpened) return;
this.hasBeenOpened = true;
// temporarily allow axios to make external requests
let axiosHeaders = axios.defaults.headers.common;
let vm = this;
axios.defaults.headers.common = {};
axios.get('https://yesno.wtf/api')
.then(function (res) {
// set our content
vm.content = null;
// set our image content
vm.image.src = res.data.image;
vm.image.alt = res.data.answer;
})
.catch(function (err) {
// set our error text
vm.content = String(err);
})
.then(function() {
// this will always hit..
vm.isLoaded = true;
});
// restore our axios headers for security
axios.defaults.headers.common = axiosHeaders;
}, 300)
},
// additional data
data: function() {
return {
// set our widgets title
widgetTitle: 'Test title',
// logic for the specific widget
hasBeenOpened: false,
content: 'Loaded and ready to go...',
image: {
src: false,
alt: null
}
};
},
}
</script>
目前我的顯示內容父模板只是完全覆蓋我的子視圖。我可以使用它的唯一方法是通過顯式定義組件中的模板參數 - > parent:{},但我不想這麼做......?
嘿克里斯,你已經嘗試過插槽? https://vuejs.org/v2/guide/components.html#Content-Distribution-with-Slots –
@GerardoRosciano看起來如此接近我想要的,但我不太清楚重構我現有的代碼...可以我仍然使用該mixin例如?? 我可以有很多不同名稱的模板。問題是任何時候我創建一個.vue文件標籤它只是完全覆蓋主模板... – Chris
@chis,我不確定使用混合。我會做的是顛倒組合,我會使用一個小部件組件,稱爲使用 和內部widet(_global)我會調用一個動態組件:(as在props.type中):https://vuejs.org/v2/guide/components.html#Dynamic-Components希望它有幫助! –