gpt4 book ai didi

javascript - Vue.js + Require.js 扩展父级

转载 作者:太空宇宙 更新时间:2023-11-04 15:35:48 24 4
gpt4 key购买 nike

我是 Vue.js 新手,但正在尝试掌握它。到目前为止,一切进展顺利,我已经取得了很大的进展,但我一直在扩展 parent 模板。

我正在尝试制作扩展默认小部件布局的仪表板小部件(在 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应使用 mixins 扩展 _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>

目前我的父模板完全覆盖了我的 subview 。我可以让它工作的唯一方法是通过在组件 ->父级:{}中显式定义模板参数,但我不想这样做......?

最佳答案

好的,感谢 Gerardo Rosciano 为我指明了正确的方向。我习惯于想出最终的解决方案。然后,我们访问父方法和数据属性,只是为了让一切正常工作。

Example.vue - 我们的示例小部件

<template>
<div>
<widget-wrapper>
<span slot="header">Example widget</span>
<div slot="content">
<img v-bind:src="image.src" v-bind:alt="image.alt"
v-if="image.src" class="img-responsive" style="margin: 0 auto" />

{{ content }}
</div>
</widget-wrapper>
</div>
</template>
<script>

// import our widgets globals
import WidgetWrapper from './_Widget.vue'

export default {

// setup our components
components: {
'widget-wrapper': WidgetWrapper
},

// set our elements props
props: {
'minimized': {
'type': Boolean,
'default': false,
'required': false
}
},

// setup our methods for this widget
methods: {

loadContent: _.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 {

// global param for parent
isLoaded: false,

// logic for the specific widget
hasBeenOpened: false,
content: 'Loaded and ready to go...',
image: {
src: false,
alt: null
}
};
},

}
</script>

_Widget.vue - 我们扩展的基本小部件

<template>
<div class="panel panel-default">
<div class="panel-heading">
<b><slot name="header">Slot header title</slot></b>
<div class="pull-right">
<a href="#" v-on:click="toggleMinimized"
v-bind:title="(minimized ? 'Show widget' : 'Hide widget')">
<i class="fa fa-fw" v-bind:class="minimized ? 'fa-plus' : 'fa-minus'"></i>
</a>
</div>
</div>
<div class="panel-body" v-if="!minimized">
<div class="text-center text-muted" v-if="!isLoaded">
<i class="fa fa-spin fa-circle-o-notch"></i><br />
Loading...
</div>
<div v-else>
<slot name="content"></slot>
</div>
</div>
</div>
</template>

<script>
export default {

// get loaded state from our parent
computed: {
isLoaded: function () {
return this.$parent.isLoaded;
}
},

// set our data element
data: function () {
return {
minimized: false
}
},

// when the widget is mounted, trigger open state
mounted: function () {
this.minimized = this.$parent.minimized;
if(!this.minimized) this.opened();
},

// methods to manipulate our widget
methods: {

// save our widget state to database
storeWidgetState: function () {

// set our data to send
let data = {
'action' : 'toggleWidget',
'widget' : this.$parent.$options._componentTag,
'state' : !this.minimized
};

// post this data to our endpoint
axios.post(axios.endpoint, data);
},

// toggle our minimized state
toggleMinimized: function (e) {

// prevent default
e.preventDefault();

// toggle our minimized state
this.minimized = !this.minimized;

// trigger opened if we aren't minimized
if(!this.minimized) this.opened();

// save our widget state to database
this.storeWidgetState();
},

// when widget is opened, load content
opened: function () {

// make sure we have a valid loadContent method
if(typeof this.$parent.loadContent === "function") {
this.$parent.loadContent();
} else {
console.log('You need to define a loadContent() method on the widget');
}
}
}
}
</script>

关于javascript - Vue.js + Require.js 扩展父级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44367877/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com