摘要:項目介紹旨在通過項目的形式同時學習和,實現(xiàn)一個在線配置頁面的功能。通過封裝好的組件樣式提供界面需要的組件,通過實現(xiàn)組件狀態(tài)更改及頁面渲染。
本文是不才在學習Vue和Bootstrap過程中遇到問題解決的一些思路,主要描述了項目搭建,組件封裝、獲取、編輯、更新的一步步實現(xiàn),一些解決方案也沒找到正確的官方API,還請大拿們多多提點。項目介紹
旨在通過項目的形式同時學習Vue和Bootstrap,實現(xiàn)一個在線配置頁面的功能。通過Bootstrap封裝好的組件樣式提供界面需要的組件,通過Vue實現(xiàn)組件狀態(tài)更改及頁面渲染。
項目地址https://github.com/shixia226/bootstrap-vue-designer
項目設計
組件模塊區(qū)
提供可用于拖拽到編輯區(qū)的所有組件,分類別展示
該功能與本學習目的關聯(lián)不強,且其主要拖拽功能比較花時間,暫且擱置
頁面編輯區(qū)
提供所有已添加到頁面的組件的編輯預覽,并提供組件增,刪,排版,選中功能
增,刪,排版功能可以與模板區(qū)的拖拽功能結(jié)合,同樣暫時擱置
組件配置區(qū)
提供具體組件內(nèi)部狀態(tài)查看及更改功能
基本的項目搭建,創(chuàng)建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官網(wǎng)例子:
9
組件分析
badge-light 樣式可以替換成badge-primary等,可以設置成屬性變量用于選擇哪個顏色;
badge-pill 樣式有和無表現(xiàn)是不一樣的,可以設置屬性變量用于控制要不該樣式;
9 文本內(nèi)容作為最終的展示內(nèi)容,可以設置成屬性變量;
組件名取 widget-badge.
Vue組件封裝Vue.component("widget-badge", {
template: `{{text}}`,
props: ["theme", "pill", "text"]
});
組件展示
html
js
new Vue({ el: ".app" })組件配置
以上步驟后刷新瀏覽器應該是可以看到組件效果了,但該組件的所有屬性都是在標簽內(nèi)寫死的,無法在編輯頁面動態(tài)設置
動態(tài)屬性vue 中 props 屬性是不允許動態(tài)更改的,一般都只能更改 data 中的屬性值,所以需要把 props 中的所有可變屬性拷貝一份到 data 中,且命名上不能相同,所以在此先規(guī)定 data 中的所有屬性都以字母"v"開頭;
每個可變屬性加一個編輯項,對應屬性名name="vpropA", 取值為當前屬性值:value="vpropsA",所有的編輯項全部定義屬性 editor 上。
沒找到對應獲取editor屬性值的API,但通過分析vue對象發(fā)現(xiàn)可以通過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"
}
}
});
屬性配置面板
點擊不同的組件要展示對應的(不同的)配置面板
根據(jù)點擊元素獲取所屬vue組件vue本來就是通過狀態(tài)更新的方式更改dom的,所以很少有dom相關的api,又只得分析vue實例里的數(shù)據(jù),發(fā)現(xiàn)$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; }增加點擊事件
獲取組件實時數(shù)據(jù)
根據(jù)前面的數(shù)據(jù)命名規(guī)則直接遍歷$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; }數(shù)據(jù)更新
在vue根節(jié)點上設置全局監(jiān)聽事件,然后在屬性值中定義$emit方法觸發(fā)該監(jiān)聽事件
根節(jié)點設置監(jiān)聽事件,并將監(jiān)聽結(jié)果反饋到當前選中的組件上
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; } } } }
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95544.html
摘要:項目介紹旨在通過項目的形式同時學習和,實現(xiàn)一個在線配置頁面的功能。通過封裝好的組件樣式提供界面需要的組件,通過實現(xiàn)組件狀態(tài)更改及頁面渲染。 本文是不才在學習Vue和Bootstrap過程中遇到問題解決的一些思路,主要描述了項目搭建,組件封裝、獲取、編輯、更新的一步步實現(xiàn),一些解決方案也沒找到正確的官方API,還請大拿們多多提點。 項目介紹 旨在通過項目的形式同時學習Vue和Bootst...
摘要:具名插槽適用于具有一定結(jié)構且有多處不固定內(nèi)容的組件此時在定義組件時其實就是預留了多個空缺位置且分別命名如果只有一個當然也可以采用具名插槽,但肯定不如默認插槽,只會徒增配置成本。然后在使用時將內(nèi)容分成多塊分別命名成預留空缺位置的名字。 本文主要描述不才在學習Vue和Bootstrap中遇到的關于插槽的問題及解決方案 插槽理解 vue官網(wǎng)和很多熱心朋友又很多關于默認插槽,具名插槽,插槽作用...
摘要:具名插槽適用于具有一定結(jié)構且有多處不固定內(nèi)容的組件此時在定義組件時其實就是預留了多個空缺位置且分別命名如果只有一個當然也可以采用具名插槽,但肯定不如默認插槽,只會徒增配置成本。然后在使用時將內(nèi)容分成多塊分別命名成預留空缺位置的名字。 本文主要描述不才在學習Vue和Bootstrap中遇到的關于插槽的問題及解決方案 插槽理解 vue官網(wǎng)和很多熱心朋友又很多關于默認插槽,具名插槽,插槽作用...
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業(yè)務工作時也會不定期更...
摘要:中文官網(wǎng)英文官網(wǎng)組織發(fā)出一個問題之后,不要暫時的離開電腦,如果沒有把握先不要提問。珍惜每一次提問,感恩每一次反饋,每個人工作還是業(yè)余之外抽出的時間有限,充分準備好應有的資源之后再發(fā)問,有利于問題能夠高效質(zhì)量地得到解決。 Vue.js資源分享 更多資源請Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/maid...
閱讀 1164·2021-09-10 10:51
閱讀 896·2019-08-30 15:53
閱讀 2724·2019-08-30 12:50
閱讀 976·2019-08-30 11:07
閱讀 1990·2019-08-30 10:50
閱讀 3598·2019-08-29 18:47
閱讀 1308·2019-08-29 18:44
閱讀 1599·2019-08-29 17:01