摘要:项目介绍旨在通过项目的形式同时学习和,实现一个在线配置页面的功能。通过封装好的组件样式提供界面需要的组件,通过实现组件状态更改及页面渲染。
本文是不才在学习Vue和Bootstrap过程中遇到问题解决的一些思路,主要描述了项目搭建,组件封装、获取、编辑、更新的一步步实现,一些解决方案也没找到正确的官方API,还请大拿们多多提点。项目介绍
旨在通过项目的形式同时学习Vue和Bootstrap,实现一个在线配置页面的功能。通过Bootstrap封装好的组件样式提供界面需要的组件,通过Vue实现组件状态更改及页面渲染。
项目地址https://github.com/shixia226/bootstrap-vue-designer
项目设计
组件模块区
提供可用于拖拽到编辑区的所有组件,分类别展示
该功能与本学习目的关联不强,且其主要拖拽功能比较花时间,暂且搁置
页面编辑区
提供所有已添加到页面的组件的编辑预览,并提供组件增,删,排版,选中功能
增,删,排版功能可以与模板区的拖拽功能结合,同样暂时搁置
组件配置区
提供具体组件内部状态查看及更改功能
基本的项目搭建,创建index.html, index.js配置好webpack
Vue Demo
module.exports = { entry: "./index.js", output: { filename: "index.js" }, module: { rules: [{ test: /^[^.]+.scss$/, use: [ "style-loader", "css-loader", "sass-loader" ] }, { test: /(.js|.vue)$/, exclude: /(node_modules|bower_components)(?!.*webpack-dev-server)/, loader: "babel-loader", query: { "presets": ["env"] } }] } };
Bootstrap样式引入
Vue框架引入
运行
//node webpack-dev-server --port=9926 //Browser http://localhost:9926/第一个组件Badage Bootstrap官网例子:
9
组件分析
badge-light 样式可以替换成badge-primary等,可以设置成属性变量用于选择哪个颜色;
badge-pill 样式有和无表现是不一样的,可以设置属性变量用于控制要不该样式;
9 文本内容作为最终的展示内容,可以设置成属性变量;
组件名取 widget-badge.
Vue组件封装Vue.component("widget-badge", {
template: `{{text}}`,
props: ["theme", "pill", "text"]
});
组件展示
html
js
new Vue({ el: ".app" })组件配置
以上步骤后刷新浏览器应该是可以看到组件效果了,但该组件的所有属性都是在标签内写死的,无法在编辑页面动态设置
动态属性vue 中 props 属性是不允许动态更改的,一般都只能更改 data 中的属性值,所以需要把 props 中的所有可变属性拷贝一份到 data 中,且命名上不能相同,所以在此先规定 data 中的所有属性都以字母"v"开头;
每个可变属性加一个编辑项,对应属性名name="vpropA", 取值为当前属性值:value="vpropsA",所有的编辑项全部定义属性 editor 上。
没找到对应获取editor属性值的API,但通过分析vue对象发现可以通过vue实例vm.$options.editor获取到该定义值,暂且先就这么用着。
组件封装更改如下:
Vue.component("widget-badge", {
template: `{{vtext}}`,
props: ["theme", "pill", "text"],
editor: `
`,
data() {
return {
vtheme: this.theme || "secondary",
vpill: this.pill,
vtext: this.text || "Badge"
}
}
});
属性配置面板
点击不同的组件要展示对应的(不同的)配置面板
根据点击元素获取所属vue组件vue本来就是通过状态更新的方式更改dom的,所以很少有dom相关的api,又只得分析vue实例里的数据,发现$children好像就是直接下级组件的一个集合,且$children每一项里都又一个$el的属性对应到实际DOM元素
function getVueCmp(vm, elem) { let pelems = [], $root = vm.$el; while (elem !== $root) { pelems.push(elem); elem = elem.parentNode; } return getVueCmpByPelem(vm, pelems); } function getVueCmpByPelem(vm, pelems) { let $children = vm.$children; if ($children) { for (let i = 0, len = $children.length; i < len; i++) { let vcmp = $children[i], $el = vcmp.$el, idx = pelems.indexOf($el); if (idx !== -1) { pelems.length = idx; return getVueCmpByPelem(vcmp, pelems); } } } return vm; }增加点击事件
获取组件实时数据
根据前面的数据命名规则直接遍历$data中所有以字母"v"开头的属性
function getVueCmpData(vcmp) { if (!vcmp) return {}; let $data = vcmp.$data, data = {}; let names = Object.getOwnPropertyNames($data); for (let i = 0, len = names.length; i < len; i++) { let name = names[i]; if (name.charAt(0) === "v") { data[name.substr(1)] = $data[name]; } } return data; }数据更新
在vue根节点上设置全局监听事件,然后在属性值中定义$emit方法触发该监听事件
根节点设置监听事件,并将监听结果反馈到当前选中的组件上
created() { this.$on("changeppt", function(name, value) { if (vcmp) { let names = name.split("."), data = vcmp, len = names.length - 1; for (let i = 0; i < len; i++) { data = data[names[i]]; } data[names[len]] = value; } }) }
封装编辑器的输入框为组件如下:
Vue.component("editor-text", { template: ``, props: ["name", "value"], data() { return { vvalue: this.value } } })
更改编辑器配置如下
{ ... /* editor: ` `, */ editor: `vue最终初始化更改如下`, ... }
new Vue({ el: ".app", data: { pptCmp: undefined }, watch: { pptCmp(vcmp) { new Vue({ el: ".ppt", template: "" + (vcmp ? vcmp.$options.editor || "" : "") + "", data() { return getVueCmpData(vcmp, true); }, created() { this.$on("changeppt", function(name, value) { if (vcmp) { let names = name.split("."), data = vcmp, len = names.length - 1; for (let i = 0; i < len; i++) { data = data[names[i]]; } data[names[len]] = value; } }) } }) } }, methods: { showPpt: function(evt) { let elem = evt.target; if (!document.querySelector(".ppt").contains(elem)) { let vcmp = getVueCmp(this, elem); if (vcmp === this.$root) { vcmp = null; } this.pptCmp = vcmp; } } } }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/95544.html
摘要:项目介绍旨在通过项目的形式同时学习和,实现一个在线配置页面的功能。通过封装好的组件样式提供界面需要的组件,通过实现组件状态更改及页面渲染。 本文是不才在学习Vue和Bootstrap过程中遇到问题解决的一些思路,主要描述了项目搭建,组件封装、获取、编辑、更新的一步步实现,一些解决方案也没找到正确的官方API,还请大拿们多多提点。 项目介绍 旨在通过项目的形式同时学习Vue和Bootst...
摘要:具名插槽适用于具有一定结构且有多处不固定内容的组件此时在定义组件时其实就是预留了多个空缺位置且分别命名如果只有一个当然也可以采用具名插槽,但肯定不如默认插槽,只会徒增配置成本。然后在使用时将内容分成多块分别命名成预留空缺位置的名字。 本文主要描述不才在学习Vue和Bootstrap中遇到的关于插槽的问题及解决方案 插槽理解 vue官网和很多热心朋友又很多关于默认插槽,具名插槽,插槽作用...
摘要:具名插槽适用于具有一定结构且有多处不固定内容的组件此时在定义组件时其实就是预留了多个空缺位置且分别命名如果只有一个当然也可以采用具名插槽,但肯定不如默认插槽,只会徒增配置成本。然后在使用时将内容分成多块分别命名成预留空缺位置的名字。 本文主要描述不才在学习Vue和Bootstrap中遇到的关于插槽的问题及解决方案 插槽理解 vue官网和很多热心朋友又很多关于默认插槽,具名插槽,插槽作用...
摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...
摘要:中文官网英文官网组织发出一个问题之后,不要暂时的离开电脑,如果没有把握先不要提问。珍惜每一次提问,感恩每一次反馈,每个人工作还是业余之外抽出的时间有限,充分准备好应有的资源之后再发问,有利于问题能够高效质量地得到解决。 Vue.js资源分享 更多资源请Star:https://github.com/maidishike... 文章转自:https://github.com/maid...
阅读 1163·2021-09-10 10:51
阅读 895·2019-08-30 15:53
阅读 2723·2019-08-30 12:50
阅读 975·2019-08-30 11:07
阅读 1989·2019-08-30 10:50
阅读 3597·2019-08-29 18:47
阅读 1307·2019-08-29 18:44
阅读 1598·2019-08-29 17:01