本文是不才在学习Vue和Bootstrap过程中遇到问题解决的一些思路,主要描述了项目搭建,组件封装、获取、编辑、更新的一步步实现,一些解决方案也没找到正确的官方API,还请大拿们多多提点。

项目介绍

旨在通过项目的形式同时学习Vue和Bootstrap,实现一个在线配置页面的功能。通过Bootstrap封装好的组件样式提供界面需要的组件,通过Vue实现组件状态更改及页面渲染。

项目地址

https://github.com/shixia226/bootstrap-vue-designer

项目设计

  • 组件模块区
    提供可用于拖拽到编辑区的所有组件,分类别展示

    该功能与本学习目的关联不强,且其主要拖拽功能比较花时间,暂且搁置

  • 页面编辑区
    提供所有已添加到页面的组件的编辑预览,并提供组件增,删,排版,选中功能

    增,删,排版功能可以与模板区的拖拽功能结合,同样暂时搁置

  • 组件配置区
    提供具体组件内部状态查看及更改功能

项目搭建

  1. 基本的项目搭建,创建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"]}}]}
    };
  2. Bootstrap样式引入

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

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

    //node
    webpack-dev-server --port=9926
    //Browser
    http://localhost:9926/

第一个组件Badage

Bootstrap官网例子:

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

组件分析

  • badge-light 样式可以替换成badge-primary等,可以设置成属性变量用于选择哪个颜色;
  • badge-pill 样式有和无表现是不一样的,可以设置属性变量用于控制要不该样式;
  • 9 文本内容作为最终的展示内容,可以设置成属性变量;
  • 组件名取 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'
})

组件配置

以上步骤后刷新浏览器应该是可以看到组件效果了,但该组件的所有属性都是在标签内写死的,无法在编辑页面动态设置

动态属性

  • vue 中 props 属性是不允许动态更改的,一般都只能更改 data 中的属性值,所以需要把 props 中的所有可变属性拷贝一份到 data 中,且命名上不能相同,所以在此先规定 data 中的所有属性都以字母'v'开头;
  • 每个可变属性加一个编辑项,对应属性名name="vpropA", 取值为当前属性值:value="vpropsA",所有的编辑项全部定义属性 editor 上。

    没找到对应获取editor属性值的API,但通过分析vue对象发现可以通过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'}}
});

属性配置面板

  • 点击不同的组件要展示对应的(不同的)配置面板

根据点击元素获取所属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;
}

增加点击事件

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

获取组件实时数据

根据前面的数据命名规则直接遍历$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: `<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 结合学习笔记(一)相关推荐

  1. Vue -- 指令【学习笔记】(持续更新)

    Vue – 指令[学习笔记](持续更新) 记录了Vue第三天的学习笔记 v-show 注意,v-show 不支持 <template> 元素,也不支持 v-else. 带有 v-show ...

  2. Vue + Spring Boot 学习笔记02:引入数据库实现用户登录功能

    Vue + Spring Boot 学习笔记02:引入数据库实现用户登录功能 在学习笔记01里,我们利用跨域打通了前端的Vue与后端的Spring Boot,实现了用户登录功能,但是后台的登录控制器在 ...

  3. Vue + Spring Boot 学习笔记01:实现用户登录功能

    Vue + Spring Boot 学习笔记01:实现用户登录功能 一.创建后端Spring Boot项目Book Management 二.创建前端Vue项目bm-vue 三.修改后端项目Book ...

  4. 唐金州的Vue开发实战学习笔记(基础篇)

    Vue开发实战学习笔记 简易的Vue程序 组件 事件 插槽 单文件组件 双向绑定 虚拟DOM与key属性 组件更新 状态data与属性props vue的响应式更新 计算属性和侦听器 计算属性 com ...

  5. Vue数据代理+事件处理+事件修饰符的作用+计算属性的使用,尚硅谷Vue系列教程学习笔记(2)

    尚硅谷Vue系列教程学习笔记(2) 参考课程:<尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通> 参考链接:https://www.bilibili.com/video/ ...

  6. bootstrap框架学习笔记

    bootstrap框架学习笔记 1.Bootstrap简介 2.基本使用 3.容器 4.设备划分 5.栅格系统 6.展示与隐藏 7.其他类前缀 8.组件直接参考开发文档 1.Bootstrap简介 B ...

  7. 唐金州的Vue开发实战学习笔记(生态篇)

    Vue开发实战学习笔记 Vuex Why Vuex How Vuex Vuex的核心概念和底层原理 Vuex的最佳实践 Vue Router Why Vue Router 路由类型及底层原理 Nuxt ...

  8. 6.29 Vue 第二天 学习笔记

    6.29  Vue  学习笔记 1. Vue 等框架等特点,框架解放程序员,适合做单页面程序, 2.案例学习,品牌管理案例, 主要学习有,添加操作,删除操作,搜索操作, 删除操作中的函数学习了两遍.s ...

  9. Vue 官网学习笔记

    VUE介绍 vue git 地址:https://github.com/vuejs/vue/projects Vue 官网教程地址:https://cn.vuejs.org/v2/guide/inst ...

最新文章

  1. 018:Django商城部署和数据库读写分离
  2. 我们生活在最好的时代
  3. Deepin 下安装 LAMP
  4. 图像的通道(channels)问题
  5. 杭州专场!华为机器视觉技术开放日—探索智能相机
  6. 重装华为服务器系统教程视频教程,服务器系统重装步骤
  7. vue获取tr内td里面所有内容_React中遍历多个数据tr,td
  8. 视频基础知识:浅谈视频会议中H.264编码标准的技术发展
  9. .netCore2.0 程序集DI依赖注入
  10. Java神鬼莫测之MyBatis多表操作延迟加载(四)
  11. postman post传输中文_Postman:Postman简介、安装、入门使用方法详细攻略
  12. 思潮涌动、静心前行----2020年度博客之星活动经历感悟
  13. 吉林大学计算机学院辅导员王,毕业30载 吉林大学计算机学院1982级校友重返母校...
  14. Panabit流控软件使用相关说明及配置文件说明
  15. 上海公积金贷款买房攻略详细解读
  16. 何帅:“在线”思考,王坚的云计算心理学
  17. 一加手机电池测试软件,6款手机电池续航测试:一加手机8Pro排第二 华为P40Pro倒数第三...
  18. OLE- 微软API—对象链接与嵌入
  19. 使用Htmlunit工具获取表单中的input
  20. mysql导入pet表

热门文章

  1. android 解决微信登录白屏样式问题
  2. 3.2 人工智能关键技术
  3. 1.机器学习的重要性
  4. 自建数据库MySQL和云数据库Rds MySQL的优缺点
  5. 微信小程序-视频弹幕的项目
  6. linux查看进程临时日志,Linux sed查看某时间段的系统日志
  7. Qt 读写xls文件(并将数据转为c风格
  8. 入手评测AMD锐龙r7 6800u和酷睿i7 1260p选哪个 r76800u和i71260p对比
  9. 不懂怎么搞定人的进来:年业绩千万的老销售给你几招实惠的-没有干货立即跳楼
  10. Qt--QTablewidgets 表格插入图片,且可以自动调整图片的大小