日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Vue Bootstrap 结合学习笔记(一)

發(fā)布時間:2024/1/8 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue Bootstrap 结合学习笔记(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本文是不才在學習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ū)的拖拽功能結合,同樣暫時擱置
  • 組件配置區(qū)
    提供具體組件內(nèi)部狀態(tài)查看及更改功能

項目搭建

  • 基本的項目搭建,創(chuàng)建index.html, index.js配置好webpack

    <!doctype html> <html lang="en"> <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>Vue Demo</title> </head> <body><script src="../index.js"></script> </body> </html> 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樣式引入

    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  • Vue框架引入

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  • 運行

    //node webpack-dev-server --port=9926 //Browser http://localhost:9926/
  • 第一個組件Badage

    Bootstrap官網(wǎng)例子:

    <span class="badge badge-light badge-pill">9</span>

    組件分析

    • badge-light 樣式可以替換成badge-primary等,可以設置成屬性變量用于選擇哪個顏色;
    • badge-pill 樣式有和無表現(xiàn)是不一樣的,可以設置屬性變量用于控制要不該樣式;
    • 9 文本內(nèi)容作為最終的展示內(nèi)容,可以設置成屬性變量;
    • 組件名取 widget-badge.

    Vue組件封裝

    Vue.component('widget-badge', {template: `<span :class="['badge', theme ? 'badge-' + theme : '', pill ? 'badge-pill' : '']">{{text}}</span>`,props: ['theme', 'pill', 'text'] });

    組件展示

    html

    <div class="app"><widget-badge></widget-badge> </div>

    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: `<span :class="['badge', 'badge-' + vtheme, vpill ? 'badge-pill' : '']">{{vtext}}</span>`,props: ['theme', 'pill', 'text'],editor: `<input name="vtheme" :value="vtheme" /><input name="vpill" :value="vpill" /><input name="vtext" :value="vtext" />`,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; }

    增加點擊事件

    <div class="app" @click="showPpt"><widget-badge></widget-badge> </div>

    獲取組件實時數(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)聽結果反饋到當前選中的組件上
    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: `<input v-model="vvalue" @change="$root.$emit('changeppt', name, vvalue)">`,props: ['name', 'value'],data() {return {vvalue: this.value}} })
    • 更改編輯器配置如下
    {.../*editor: `<input name="vtheme" :value="vtheme" /><input name="vpill" :value="vpill" /><input name="vtext" :value="vtext" />`,*/editor: `<editor-text name="vtheme" :value="theme" ></editor-text><input name="vpill" :value="pill" ></editor-text><input name="vtext" :value="text" ></editor-text>`,... }

    vue最終初始化更改如下

    new Vue({el: '.app',data: {pptCmp: undefined},watch: {pptCmp(vcmp) {new Vue({el: '.ppt',template: '<div class="ppt">' + (vcmp ? vcmp.$options.editor || '' : '') + '</div>',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;}}} }

    總結

    以上是生活随笔為你收集整理的Vue Bootstrap 结合学习笔记(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。