目录

  • ---------错误---------
    • 没有Vue Component
      • 解决
  • 组件
    • UI组件
    • 开发框架
    • 实用库
    • 服务端
    • 辅助工具
    • 应用实例
    • Demo示例
  • **一、前端核心分析**
    • ***1.1、概述**
    • **1.2、前端三要素**
    • **1.3、结构层(HTML)**
    • **1.4、表现层(CSS)**
    • **1.5、行为层(JavaScript)**
      • Native 原生JS开发
      • JavaScript框架
  • **二、前端发展史**
    • **2.1、UI框架**
    • **2.2、JavaScript构建工具**
    • **2.3、三端同一**
    • **2.4、后端技术**
    • **2.5、主流前端框架**
  • **三、了解前后分离的演变史**
    • **3.1、后端为主的MVC时代**
    • **3.2、基于AJAX带来的SPA时代**
    • **3.3、前端为主的MV\*时代**
    • **3.4、Node JS带来的全栈时代**
  • **四、第一个Vue程序**
    • **4.1、什么是MVVM**
    • **4.2、为什么要使用MVVM**
      • **(1)View**
      • **(2)Model**
      • **(3)ViewModel**
    • **4.3、Vue**
      • (1)MVVM模式的实现者
      • (2)为什么要使用Vue.js
    • 4.4、第一个Vue程序
      • (1)下载地址
      • (2)代码编写
        • 1、创建一个HTML文件
        • 2、引入Vue.js
        • 3、创建一个Vue实例
        • 4、将数据绑定到页面元素
      • (3)完整的HTML
      • (4)测试
  • **五、基础语法指令**
    • 5.1、v-bind
    • 5.2、v-if, v-else
    • 5.3、v-for
    • 5.4、v-on
  • **六、表单双绑、组件**
    • 6.1、什么是双向数据绑定
      • (1)为什么要实现数据的双向绑定
    • 6.2、在表单中使用双向数据绑定
      • (1)单行文本
      • (2)多行文本
      • (3)单复选框
      • (4)多复选框
      • (6)单选按钮
      • (7)下拉框
    • 6.3、什么是组件
      • (1)第一个Vue组件
  • **七、Axios异步通信**
    • 7.1、什么是Axios
    • 7.2、为什么要使用Axios
    • 7.3、第一个Axios应用程序
    • 7.4、Vue的生命周期
  • **八、计算属性、内容分发、自定义事件**
    • 1、什么是计算属性
    • 8.2、内容分发
      • 测试
    • 8.3、自定义事件
      • 1、增加了methods对象、定义removeTodoltems的方法
      • 2-修改todo-items待办内容组件的代码,增加一个删除按钮,并且绑定事件!
      • 3-修改todo-items待办内容组件的HTML代码,
    • 8.4、Vue入门小结
  • **九、第一个vue-cli项目**
    • 9.1、什么是vue-cli
    • 9.2、需要的环境
    • 9.3、第一个vue-cli应用程序
      • 1.创建一个Vue项目,
      • 2.创建一个基于webpack模板的vue应用程序
      • 3、idea打开
  • **十、webpack使用**
    • 10.1、什么是Webpack
    • 10.2、模块化的演进
      • Script标签
      • CommonsJS
      • **AMD**
      • **RequireJS**
      • **ES6模块**
    • 10.3、安装Webpack
    • 10.4、使用webpack
      • 执行、报错
  • 十一、vue-router路由
    • 11.2、安装
    • 11.3、测试
  • 十二、实战快速上手
    • 12.1、创建工程
    • 12.2、创建登录页面
    • 12.3、路由嵌套
    • 12.4、参数传递
    • 12.5、组件重定向
    • 12.6、路由模式与 404
    • 12.5、组件重定向
    • 12.6、路由模式与 404

---------错误---------

安装vue插件

没有Vue Component

安装成功后可以右键看看有没有Vue Component

解决

  1. 点击 file 打开设置 settings,展开 Editor 找到 file and code templates
  2. 找到 Vue single file component 并选中它,然后点击copy
  3. 复制后底部出现了一个新的文件
  4. 把 Name 改成 Vue Component,然后把代码里的 “COMPONENT_ ”删掉,最后点 ok 就完事了

一定在div加id

组件

UI组件

  • element ★13489 - 饿了么出品的Vue2的web UI工具套件
  • Vux ★8133 - 基于Vue和WeUI的组件库
  • iview ★6634 - 基于 Vuejs 的开源 UI 组件库
  • mint-ui ★6253 - Vue 2的移动UI元素
  • muse-ui ★3705 - 三端样式一致的响应式 UI 库
  • vue-material ★3328 - 通过Vue Material和Vue 2建立精美的app应用
  • vuetify ★2925 - 为移动而生的Vue JS 2组件框架
  • Keen-UI ★2749 - 轻量级的基本UI组件合集
  • vonic ★1913 - 快速构建移动端单页应用
  • vue-multiselect ★1539 - Vue.js选择框解决方案
  • eme ★1529 - 优雅的Markdown编辑器
  • vueAdmin ★1455 - 基于vuejs2和element的简单的管理员模板
  • bootstrap-vue ★1267 - 应用于Vuejs2的Twitter的Bootstrap 4组件
  • Vue.Draggable ★1191 - 实现拖放和视图模型数组同步
  • eagle.js ★1128 - hacker的幻灯片演示框架
  • vue-awesome-swiper ★1012 - vue.js触摸滑动组件
  • vue-table ★1009 - 简化数据表格
  • vue-chat ★859 - vuejs和vuex及webpack的聊天示例
  • vue-blu ★850 - 帮助你轻松创建web应用
  • vue-recyclerview ★849 - 管理大列表的vue-recyclerview
  • VueCircleMenu ★838 - 漂亮的vue圆环菜单
  • vue-infinite-scroll ★779 - VueJS的无限滚动指令
  • buefy ★755 - 响应式UI组件轻量级库
  • vue-beauty ★749 - 由vue和ant design创建的优美UI组件
  • vue-waterfall ★737 - Vue.js的瀑布布局组件
  • radon-ui ★715 - 快速开发产品的Vue组件库
  • vue-loop ★701 - 无限的内容循环
  • vue-chartjs ★694 - vue中的Chartjs的封装
  • vue-carbon ★684 - 基于 vue 开发MD风格的移动端
  • vue-syntax-highlight ★655 - Sublime Text语法高亮
  • vue-echarts ★649 - VueJS的ECharts组件
  • vue-quill-editor ★615 - 基于Quill适用于Vue2的富文本编辑器
  • vue-amap ★571 - 基于Vue 2和高德地图的地图组件
  • vue-calendar ★536 - 日期选择插件
  • vue-infinite-loading ★501 - VueJS的无限滚动插件
  • vue-swipe ★481 - VueJS触摸滑块
  • vue-music-player ★451 - Vuejs写一个音乐播放器
  • vue-scroller ★444 - Vonic UI的功能性组件
  • vue-datepicker ★436 - 日历和日期选择组件
  • vue-core-image-upload ★393 - 轻量级的vue上传插件
  • vue-progressbar ★379 - vue轻量级进度条
  • Gokotta ★375 - 简单的音乐播放器
  • vue-sortable ★373 - 轻松添加拖拽排序
  • vue-picture-input ★352 - 移动友好的图片文件输入组件
  • vue-echarts-v3 ★351 - VueJS组件封装
  • markcook ★343 - 好看的markdown编辑器
  • vue-video-player ★336 - VueJS视频及直播播放器
  • vue-google-maps ★334 - 带有双向数据绑定Google地图组件
  • vue-trend ★332 - 简单优雅的星光线条
  • vuejs-datepicker ★314 - vue日期选择器组件
  • vue-fullcalendar ★313 - 基于vue.js的全日历组件
  • vue-html5-editor ★303 - html5所见即所得编辑器
  • vue-upload-component ★298 - Vuejs文件上传组件
  • DataVisualization ★298 - 数据可视化
  • vue-tables-2 ★291 - 显示数据的bootstrap样式网格
  • VueStar ★270 - 带星星动画的vue点赞按钮
  • vue-data-tables ★266 - VueJS2数据表格
  • vue-paginate ★261 - 分页数据的简约VueJS插件
  • vue-ydui ★247 - 基于Vue2的移动端和微信UI
  • vue-mugen-scroll ★239 - 无限滚动组件
  • vue-virtual-scroller ★238 - 带任意数目数据的顺畅的滚动
  • vue2-calendar ★236 - 支持lunar和日期事件的日期选择器
  • vue-dropzone ★233 - 用于文件上传的Vue组件
  • vue2-douban-market ★233 - 仿豆瓣市集webapp项目
  • vue-js-modal ★228 - 移动友好的Vuejs2的modal
  • vue-slider ★224 - vue 滑动组件
  • vue-datetime-picker ★224 - 日期时间选择控件
  • rubik ★217 - 基于Vuejs2的开源 UI 组件库
  • vue-datasource ★210 - 创建VueJS动态表格
  • vue-image-crop-upload ★205 - vue图片剪裁上传组件
  • Vueditor ★204 - 所见即所得的编辑器
  • mint-loadmore ★203 - VueJS的双向下拉刷新组件
  • vue-slider-component ★202 - 在vue1和vue2中使用滑块
  • vue-chat ★200 - Vue全家桶+Socket.io+Express/Koa2打造一个智能聊天室
  • mavonEditor ★179 - 基于Vue的markdown编辑器
  • vue-carousel-3d ★173 - VueJS的3D轮播组件
  • vue-baidu-map ★170 - 基于 Vue 2的百度地图组件库
  • sweet-modal-vue ★170 - 精美的点击提示对话框
  • vue-particles ★168 - 粒子背景的vue组件
  • vue-swiper ★167 - 易于使用的滑块组件
  • vue-simplemde ★166 - VueJS的Markdown编辑器组件
  • vue-slide ★161 - vue轻量级滑动组件
  • vue-dragula ★157 - 使拖放变得简单
  • vue-drag-and-drop-list ★156 - 创建排序列表的Vue指令
  • vue2-editor ★155 - HTML编辑器
  • vue-charts ★152 - 轻松渲染一个图表
  • vue-data-grid ★151 - VueJS复杂桌面交互示例
  • vuwe ★150 - 基于微信WeUI所开发的专用于Vue2的组件库
  • vue-progressive-image ★148 - Vue的渐进图像加载插件
  • vue-msgbox ★148 - vuejs的消息框
  • vue-lazyload-img ★147 - 移动优化的vue图片懒加载插件
  • vue-dragging ★146 - 使元素可以拖拽
  • vue-instant ★143 - 轻松创建自动提示的自定义搜索控件
  • vue-social-sharing ★142 - 社交分享组件
  • vue-images ★139 - 显示一组图片的lightbox组件
  • vue-impression ★134 - 移动Vuejs2 UI元素
  • vue-mdEditor ★131 - 基于VUE的markdown文本编辑器
  • vue-typer ★130 - 模拟用户输入选择和删除文本的Vue组件
  • vue-highcharts ★130 - HighCharts组件
  • vue-tooltip ★129 - 带绑定信息提示的提示工具
  • vue-svgicon ★127 - 创建svg图标组件的工具
  • wdui ★124 - 基于Vue2的UI组件库
  • vue2-loading-bar ★118 - 最简单的仿Youtube加载条视图
  • vue-tabs-component ★116 - 渲染tabs的Vue组件
  • MagicMusic ★113 - 不一样的音乐
  • vue-region-picker ★111 - 选择中国的省份市和地区
  • vue-datatable ★102 - 使用Vuejs创建的DataTableView
  • vue-loading ★102 - 元素中加载block的Vue指令
  • vodal ★99 - 动画的vue模态
  • vue-img-inputer ★97 - 基于Vue2的图片输入框
  • vue-video ★96 - Vue.js的HTML5视频播放器
  • vue-touch-ripple ★95 - vuejs的触摸ripple组件
  • vue-event-calendar ★91 - 简单小巧的事件日历组件
  • v-bar ★91 - 虚拟响应跨浏览器滚动条
  • vue2-timepicker ★84 - 下拉时间选择器
  • vuejs-paginate ★80 - 分页VueJS组件
  • vue-toast-mobile ★79 - VueJS的toast插件
  • vue-datepicker ★78 - 漂亮的Vue日期选择器组件
  • vue-easy-slider ★77 - Vue 2.x的滑块组件
  • vue-float-label ★76 - VueJS浮动标签模式
  • vue-scrollbar ★76 - 最简单的滚动区域组件
  • vant ★74 - 有赞出品的Vue2.0移动UI
  • vue-json-tree-view ★74 - Vue的JSON树视图
  • vue-slick ★73 - 实现流畅轮播框的vue组件
  • vue-keynote ★73 - 实现声明性代码幻灯片
  • vue-google-signin-button ★73 - 导入谷歌登录按钮
  • vue-rate ★68 - Vue评分组件
  • awesome-mask ★67 - 拥有独一无二mask的表单
  • vue-radial-progress ★65 - Vue.js放射性进度条组件
  • vue-quill ★65 - vue组件构建quill编辑器
  • vue-date-picker ★63 - VueJS日期选择器组件
  • coffeebreak ★62 - 实时编辑CSS组件工具
  • vue-good-wizard ★61 - VueJS 2.x wizard plugin
  • vue-loading ★60 - 使用SVG加载
  • datepicker ★59 - 基于flatpickr的时间选择组件
  • vue-placeholders ★58 - 处理占位符图片和乱码
  • we-vue ★55 - Vue2及weui1开发的组件
  • vue-fullcalendar ★55 - vue FullCalendar封装
  • vue-chartkick ★53 - VueJS一行代码实现优美图表
  • cxlt-vue2-toastr ★52 - 弹出提示的Vue2组件
  • vue-formly ★51 - VueJS的JS表单
  • vue2-autocomplete ★51 - vue2的自动完成组件
  • vue-morris ★50 - Vuejs组件封装Morrisjs库
  • veui ★50 - VueJS百度企业UI
  • vue-components ★49 - 移动端UI组件库
  • vue-star-rating ★49 - 简单高度自定义的星星评级组件
  • vue-tagsinput ★48 - 基于VueJS的标签组件
  • vue-tabs ★47 - 多tab页轻型框架
  • vue-popup-mixin ★47 - 用于管理弹出框的遮盖层
  • vue-ripple-directive ★45 - 使用Vue指令的Material波纹效果
  • vue-cropper ★42 - 一个简单的vue 的图片裁剪插件
  • vue-ztree ★41 - 用 vue 写的树层级组件
  • vue-touch-keyboard ★41 - VueJS虚拟键盘组件
  • cubeex ★40 - 包含一套完整的移动UI
  • vue-chart ★40 - 强大的高速的vue图表解析
  • vue-music-master ★40 - vue手机端网页音乐播放器
  • vue-bootstrap-table ★39 - 可排序可检索的表格
  • vue-emoji ★39 - 好用的emoji插件
  • handsontable ★39 - 网页表格组件
  • vue-form-2 ★37 - 全面的HTML表单管理的解决方案
  • vue-area ★37 - 省市区三级联动插件
  • vue-side-nav ★37 - 响应式的侧边导航
  • vue-image-scroll ★36 - 仿网易云音乐的vue图片滚动插件
  • vue-pull-to-refresh ★35 - Vue2的上拉下拉
  • mint-indicator ★35 - VueJS移动加载指示器插件
  • vue-image-clip ★34 - 基于vue的图像剪辑组件
  • vue-material-design ★34 - Vue MD风格组件
  • vue-simple-upload ★31 - 简单的VueJS上传组件
  • chartjs ★29 - Vue Bulma的chartjs组件
  • vue-lazy-background-images ★29 - 懒加载背景组件的Vue组件
  • vue-ripple ★29 - 制作谷歌MD风格涟漪效果的Vue组件
  • vue-scroll ★27 - vue滚动
  • laravel-vue-pagination ★26 - VueJS分页组件
  • vue-datepicker-simple ★26 - 基于vue的日期选择器
  • vue-m-carousel ★26 - vue 移动端轮播组件
  • vue-parallax ★23 - 整洁的视觉效果
  • vue-img-loader ★22 - 图片加载UI组件
  • vue-tree ★22 - vue树视图组件
  • vue-verify-pop ★22 - 带气泡提示的vue校验插件
  • vue-waves ★22 - waves的VueJS版本
  • vue-smoothscroll ★20 - smoothscroll的VueJS版本
  • vue-city ★19 - 城市选择器
  • vue-laypage ★17 - 简单的VueJS分页组件
  • vue-typewriter ★15 - vue组件类型
  • vue-ios-alertview ★14 - iOS7+ 风格的alertview服务
  • vue-cmap ★14 - Vue China map可视化组件
  • paco-ui-vue ★12 - PACOUI的vue组件
  • vue-cascading-address ★9 - vue地区选择器
  • dd-vue-component ★7 - 订单来了的公共组件库
  • vue-button ★5 - Vue按钮组件

开发框架

  • vue.js ★56380 - 流行的轻量高效的前端组件化方案
  • vue-admin ★4612 - Vue管理面板框架
  • quasar ★2353 - 响应式网站和混合移动应用程序
  • electron-vue ★2085 - Electron及VueJS快速启动样板
  • vue-element-admin ★1986 - vue2管理系统模板
  • vuepack ★1618 - 现代VueJS启动器
  • N3-components ★656 - 快速构建页面和应用
  • VueThink ★373 - 前后端分离框架
  • vue-2.0-boilerplate ★358 - Vue2单页应用样板
  • vue-spa-template ★344 - 前后端分离后的单页应用开发
  • Framework7-Vue ★283 - VueJS与Framework7结合
  • vue-bulma ★215 - 轻量级高性能MVVM Admin UI框架
  • vuetiful ★189 - 创建业务及管理应用程序
  • vue-stack-2.0 ★155 - Vue2项目样板
  • vue2-admin-lte ★154 - vue2版本的adminLTE
  • jspangAdmin ★140 - 基于Vue2的后台管理系统
  • vue-fullstack ★140 - 实时的用户友好的后台系统
  • vue-paper-dashboard ★120 - Vue的Tim Paper 仪表盘
  • vue-webgulp ★113 - 仿VueJS Vue loader示例
  • vue-element-starter ★83 - vue启动页
  • vuemin ★17 - 基于Vue的企业级前端开发框架
  • vue-team-template ★12 - 一种构建vue项目的选择方案

实用库

  • vuex ★8043 - 专为 Vue.js 应用程序开发的状态管理模式
  • vue-loader ★1847 - Vue.js 针对Webpack的组件装载插件
  • vue-validator ★1807 - vue的验证器插件
  • vue-lazyload ★1224 - 用于懒加载的Vue模块
  • vuelidate ★1075 - 简单轻量级的基于模块的Vue.js验证
  • vue-i18n ★1053 - VueJS的多语言切换插件
  • qingcheng ★736 - qingcheng主题
  • Vue-Socketio ★533 - VueJS的socketio实现
  • vue-awesome ★532 - VueJS字体Awesome组件
  • vue-desktop ★496 - 创建管理面板网站的UI库
  • vue-axios ★491 - 将axios整合到VueJS的封装
  • vue-meta ★467 - 管理app的meta信息
  • vue-head ★396 - head标签的meta信息操作
  • meteor-vue-component ★382 - vue和meteor整合
  • avoriaz ★338 - VueJS测试实用工具库
  • portal-vue ★239 - 在组件外部渲染DOM
  • vue-flatpickr ★228 - 封装Flatpickr的Vue组件
  • vue-timeago ★195 - VueJS的时间前组件
  • blessed-vue ★181 - 编写命令行UI的VueJS运行时
  • vue-unit ★179 - 创建单元测试组件
  • vue-authenticate ★177 - 简单的VueJS身份认证库
  • vue-scrollTo ★174 - 滚动到元素的VueJS指令
  • vue-svg-icon ★157 - vue2的可变彩色svg图标方案
  • vue-focus ★148 - 可重用VueJS组件的焦点指令
  • meteor-vue ★134 - VueJS和Meteor的桥接
  • element-admin ★130 - 支持 vuecli 的 Element UI 的后台模板
  • vuep ★118 - 用实时编辑和预览来渲染Vue组件
  • vuet ★116 - 一个跨页面、跨组件的状态管理插件
  • vue-bootstrap-modal ★112 - vue的Bootstrap样式组件
  • vue-animate ★106 - 跨浏览器CSS3动画库
  • vue-property-decorator ★104 - VueJS和属性Decorator
  • vue-aplayer ★100 - 便于配置的音乐播放器vue2组件
  • vue-password-strength-meter ★97 - 交互式密码强度计
  • vue-websocket ★91 - VueJS的Websocket插件
  • vue-local-storage ★88 - 具有类型支持的Vuejs本地储存插件
  • vue-recyclist ★88 - vuejs无限滚动列表
  • vue-lazy-render ★87 - 用于Vue组件的延迟渲染
  • vue-qart ★86 - 用于qartjs的Vue2指令
  • vue-framework7 ★85 - 结合VueJS使用的Framework7组件
  • vue-cordova ★85 - Cordova的VueJS插件
  • http-vue-loader ★84 - 从html及js环境加载vue文件
  • vue-parallax ★84 - 快速60fps视差滚动效果组件
  • vue-clipboard ★84 - VueJS的剪贴板
  • vue-kindergarten ★83 - 将kindergarten集成到VueJS应用
  • vue-events ★83 - 简化事件的VueJS插件
  • vue-notifications ★80 - 非阻塞通知库
  • vue-online ★77 - reactive的在线和离线组件
  • vue-shortkey ★74 - 应用于Vue.js的Vue-ShortKey 插件
  • vue-bus ★71 - VueJS的事件总线
  • vuex-i18n ★71 - 定位插件
  • uiv ★70 - Vue实现的Bootstrap组件
  • vue-router-transition ★69 - 页面过渡插件
  • vue-gesture ★69 - VueJS的手势事件插件
  • vue-clip ★67 - 简约的破解文件上传器
  • vue-electron ★66 - 将选择的API封装到Vue对象中的插件
  • cleave ★64 - 基于cleave.js的Cleave组件
  • vuemit ★63 - 处理VueJS事件
  • vue-worker ★56 - 使用webworkers的Vue插件
  • vue-acl ★54 - VueJS访问控制列表插件
  • vue-ts-loader ★54 - 在Vue装载机检查脚本
  • Vue.resize ★51 - 检测HTML调整大小事件的vue指令
  • vuedeux ★50 - 轻量级开源实用用层
  • vue-ls ★49 - 适配Vuecontext中LocalStorage的Vue插件
  • lazy-vue ★48 - 懒加载图片
  • vue-pagination-2 ★46 - 简单通用的分页组件
  • v-media-query ★44 - vue中添加用于配合媒体查询的方法
  • vue-observe-visibility ★42 - 当元素在页面上可见或隐藏时检测
  • vue-lazy-component ★38 - 懒加载组件或者元素的Vue指令
  • vue-reactive-storage ★37 - vue插件的Reactive层
  • vue-helmet ★37 - HTML标题管理器
  • voir ★35 - 保持mutation与视图组件的分离
  • vuex-shared-mutations ★34 - 分享某种Vuex mutations
  • vue-drag-zone ★28 - 适用于Vue2的dom拖动组件
  • vue-eslint-parser ★27 - ESLint自定义解析
  • modal ★26 - Vue Bulma的modal组件
  • vue-plan ★25 - Vuex-状态管理
  • vue-file-base64 ★22 - 将文件转换为Base64的vue组件
  • vue-methods-promise ★21 - 使vue方法支持promise
  • Vue.ImagesLoaded ★20 - 检测图片加载的VueJS指令
  • Famous-Vue ★16 - Famous库的vue组件
  • leo-vue-validator ★15 - 异步的表单验证组件
  • vue-titlecase ★13 - 用于字符串titlecased的VueJS过滤器
  • Vue-Easy-Validator ★12 - 简单的表单验证
  • vue-zoombox ★12 - 一个高级zoombox
  • vue-truncate-filter ★10 - 截断字符串的VueJS过滤器
  • vue-router-storage ★9 - vue历史路由持久化的解决方案
  • vue-input-autosize ★9 - 基于内容自动调整文本输入的大小
  • vue-data-validator ★4 - Vuejs2的数据验证插件
  • vue-lazyloadImg ★4 - 图片懒加载插件

服务端

  • nuxt.js ★4564 - 用于服务器渲染Vue app的最小化框架
  • unvue ★310 - 使用简单的通用VueJS应用
  • express-vue ★302 - 简单的使用服务器端渲染vue.js
  • vue-ssr ★92 - 非常简单的VueJS服务器端渲染模板
  • doubanMovie-SSR ★85 - Vue豆瓣电影服务端渲染
  • vue-ssr ★80 - 结合Express使用Vue2服务端渲染
  • vue-easy-renderer ★44 - Nodejs服务端渲染

辅助工具

  • vue-play ★641 - 展示Vue组件的最小化框架
  • DejaVue ★635 - Vuejs可视化及压力测试
  • vscode-VueHelper ★228 - 目前vscode最好的vue代码提示插件
  • vue-generate-component ★56 - 轻松生成Vue js组件的CLI工具
  • vue-multipage-cli ★40 - 简单的多页CLI
  • VuejsStarterKit ★29 - vuejs starter套件

应用实例

  • koel ★7773 - 基于网络的个人音频流媒体服务
  • pagekit ★4225 - 轻量级的CMS建站系统
  • vue-manage-system ★2057 - 后台管理系统解决方案
  • vuedo ★1265 - 博客平台
  • jackblog-vue ★1120 - 个人博客系统
  • PJ Blog ★1018 - 开源博客
  • vue-cnode ★787 - 重写vue版cnode社区
  • vms ★629 - vuejs2管理系统
  • CMS-of-Blog ★541 - 博客内容管理器
  • goldfish ★518 - 用于HashiCorp Vault的Admin UI
  • rss-reader ★368 - 简单的rss阅读器
  • vue-ghpages-blog ★254 - 依赖GitHub Pages无需本地生成的静态博客
  • vue-blog ★143 - 使用Vue2.0 和Vuex的vue-blog
  • swoole-vue-webim ★137 - Web版的聊天应用
  • tomato5 ★134 - 实时的协作工具
  • Loopa-News ★133 - 开源社会新闻应用
  • vue2-management-platform ★74 - vue2.0+ elementUI 后台管理平台
  • vue-dashing-js ★70 - nuvo-dashing-js的fork
  • fewords ★63 - 功能极其简单的笔记本
  • adminify ★46 - 一个基于Vuetify material的Admin面板

Demo示例

  • vue2-elm ★8036 - 重写饿了么webapp
  • Vue-cnodejs ★2491 - 基于vue重写Cnodejs的webapp
  • NeteaseCloudWebApp ★1549 - 高仿网易云音乐的webapp
  • vue2-happyfri ★1535 - vue2及vuex的入门练习项目
  • vue-zhihu-daily ★1010 - 知乎日报 with Vuejs
  • vue2-demo ★994 - 从零构建vue2 + vue-router + vuex 开发环境
  • vue-wechat ★939 - vue.js开发微信app界面
  • eleme ★882 - 高仿饿了么app商家详情
  • vue-demo ★755 - vue简易留言板
  • bilibili-vue ★694 - 全栈式开发bilibili首页
  • spa-starter-kit ★646 - 单页应用启动套件
  • VueDemo_Sell_Eleme ★636 - Vue2高仿饿了么外卖平台
  • vue-music ★621 - Vue 音乐搜索播放
  • douban ★606 - 基于vue全家桶的精致豆瓣DEMO
  • vue-Meizi ★604 - vue最新实战项目
  • maizuo ★603 - vue/vuex/redux仿卖座网
  • vue-WeChat ★558 - 基于Vue2高仿微信App的单页应用
  • vue-demo-kugou ★500 - vuejs仿写酷狗音乐webapp
  • vue2-manage ★457 - 基于 vue + element-ui 的后台管理系统
  • zhihudaily-vue ★455 - 知乎日报web版
  • vue-163-music ★448 - vue仿网易云音乐客户端版
  • vue-axios-github ★448 - 登录拦截登出功能
  • douban ★440 - 模仿豆瓣前端
  • vue-shopping ★404 - 蘑菇街移动端
  • vue2.0-taopiaopiao ★402 - vue2.0与express构建淘票票页面
  • xyy-vue ★396 - 大学生交流平台
  • easy-vue ★370 - 使用Vue实现简易web
  • vue2.x-douban ★360 - Vue2实现简易豆瓣电影webApp
  • vue2-MiniQQ ★351 - 基于Vue2实现的仿手机QQ单页面应用
  • mi-by-vue ★291 - VueJS仿小米官网
  • daily-zhihu ★275 - 基于Vue2的知乎日报单页应用
  • vue-leancloud-blog ★268 - 一个前后端完全分离的单页应用
  • VueMusic-PC ★260 - Vue.js高还原网易云音乐系列
  • node-vue-server-webpack ★253 - Node.js+Vue.js+webpack快速开发框架
  • beauty ★245 - 豆瓣美女clone
  • vue-adminLte-vue-router ★243 - vue和adminLte整合应用
  • vue-fis3 ★217 - 流行开源工具集成demo
  • notepad ★216 - 本地存储的记事本
  • vue-demo-maizuo ★210 - 使用Vue2全家桶仿制卖座电影
  • Pixel-Web ★198 - 一个 Vue 微博客户端
  • netease_yanxuan ★198 - vue版网易严选
  • tmdb-app ★194 - TMDbVueJS应用
  • vue-express-mongodb ★189 - 简单的前后端分离案例
  • vue-zhihudaily ★187 - 知乎日报 Web 版本
  • Vdo ★179 - VueJS与MD重构豆瓣
  • vue-blog ★171 - 单用户博客
  • Wuji ★168 - 吾记网页版
  • hello-vue-django ★160 - 使用带有Django的vuejs的样板项目
  • Zhihu-Daily-Vue.js ★157 - Vuejs单页网页应用
  • tencent-sports ★154 - Vue全家桶仿腾讯体育
  • gouyan-movie-vue ★151 - 基于vue的在线电影影讯网站
  • x-blog ★145 - 开源的个人blog项目
  • vue-musicApp ★132 - 使用vue全家桶制作的音乐播放器
  • vue-cnode ★131 - vue单页应用demo
  • webpack-vue-vueRouter ★130 - webpack及vue开发的简单项目实例
  • vue-koa-demo ★128 - 使用Vue2和Koa1的全栈demo
  • vueBlog ★127 - 前后端分离博客
  • websocket_chat ★127 - 基于vue和websocket的多人在线聊天室
  • houtai ★125 - 基于vue和Element的后台管理系统
  • vue-toutiao ★121 - vuejs高仿今日头条移动端
  • vue-cnode ★121 - 开源的CNode社区
  • vue-mini-shop ★121 - VueJS在线商店
  • photoShare ★120 - 基于图片分享的社交平台
  • iview2-management-system ★119 - 后台管理系统解决方案简单示例
  • doubanMovie ★119 - 豆瓣电影展示
  • eleme-vue2 ★112 - 仿饿了么H5纯前端Vue版
  • vue-zhihu-daily ★111 - 基于Vue全家桶开发的知乎日报
  • Vue-News ★107 - 基于vue全家桶的仿知乎日报单页应用
  • douban-movie ★107 - 仿豆瓣电影wap端
  • generator-loopback-vue ★104 - 典型前后端分离项目模板
  • vue-quasar-admin-example ★99 - 将Quasar和VueJS应用于SPA项目
  • vue-zhihudaily-2.0 ★97 - 使用Vue2.0+vue-router+vuex创建的zhihudaily
  • vue-todos ★95 - vue最新实战项目教程
  • vue-music ★91 - 网易云音乐Demo
  • vue-qqmusic ★90 - Vue全家桶+Mint-Ui打造高仿QQMusic
  • vue2.x-Cnode ★88 - 基于vue全家桶的Cnode社区
  • vue-ruby-china ★86 - VueJS框架搭建的rubychina平台
  • doubanMovie-SSR ★85 - Vue豆瓣电影服务端渲染
  • vue-jd ★76 - 京东移动web商城
  • vue-nReader ★73 - 使用vue2.0 + vue-router + vuex 的一个多页面小说阅读webapp
  • VueBlog ★73 - 前后端分离的个人博客
  • Zhihu_Daily ★73 - 基于Vue和Nodejs的Web单页应用
  • vue-koa2-login ★67 - 使用 VueJS & NodeJS 实现的登录注册
  • webApp ★64 - Vue2的移动端webApp音乐播放器
  • vue-trip ★64 - vue2做的出行webapp
  • seeMusic ★63 - 跨平台云音乐播放器
  • github-explorer ★63 - 寻找最有趣的GitHub库
  • vue-cli-multipage-bootstrap ★60 - 将vue官方在线示例整合到组件中
  • vue-XiaoMi-Shop ★59 - 高仿小米商城的项目
  • Vue-NetEaseCloudMusic ★59 - 模仿IOS版网易云音乐的手机网站
  • life-app-vue ★59 - 使用vue2完成多功能集合到小webapp
  • doubanApp ★55 - 用vue2实现仿豆瓣app
  • ios7-vue ★52 - 使用vue2.0 vue-router vuex模拟ios7
  • canvas-vue ★50 - 一个Vue+Cnavas酷炫后台管理
  • vue-bushishiren ★49 - 不是诗人应用
  • vue-ssr-boilerplate ★48 - 精简版的ofvue-hackernews-2
  • vuecommunity ★47 - vue.js中文社区
  • vue-music163 ★47 - 音乐VueJS项目
  • Vue2-MV ★45 - 仿网易云音乐MV的webapp
  • musiccloudWebapp ★44 - 用vuejs仿网易云音乐
  • cnode-vue ★40 - 基于vue和vue-router构建的cnodejs web网站SPA
  • Framework7-VueJS ★38 - 使用移动框架的示例
  • m-eleme ★37 - 基于Vue全家桶仿饿了么移动端webapp
  • sls-vuex2-demo ★37 - vuex2商城购物车demo
  • eagles ★36 - 各种组件封装
  • Todos_Vuejs ★35 - vuejs2搭建的极简的todolist
  • vue-cnode ★35 - 用 Vue 做的 CNode 官网
  • HyaReader ★35 - 移动友好的阅读器
  • Vue-Admin ★33 - 基于Vue2的Admin系统
  • vue2-hybridapp-haoshiqi ★32 - 实现单页面webapp以及hybridapp
  • zhihu-daily ★32 - 轻松查看知乎日报内容
  • gank ★32 - gankio资源的阅读应用
  • vue-h5plus ★31 - 前卫的vue及html5plus跨平台demo
  • vue-cnode-mobile ★29 - 搭建cnode社区
  • vue-weather ★26 - 基于vue.js 2.0的百度天气应用
  • vue-user-center ★26 - vuejs直播类应用web端个人中心
  • zhihu-daily-vue ★22 - 知乎日报
  • vue-cnode ★22 - 使用cNode社区提供的接口
  • vue-starter ★22 - VueJs项目的简单启动页
  • node-vue-fabaocn ★21 - 基于 node 和 vue 实现的移动官网
  • vue-memo ★20 - 用 vue写的记事本应用
  • v-notes ★20 - 简单美观的记事本
  • vue-flexible-app ★19 - vue开发的一个简易app
  • simply-calculator-vuejs ★19 - 用VueJS实现简易计算器
  • vue-dropload ★19 - 用以测试下拉加载与简单路由
  • Vuejs-SalePlatform ★19 - vuejs搭建的售卖平台demo
  • vue-shopping-mall ★16 - 基于Vue.js 2.x系列 + vue2-router + axios + iview 商城
  • qqmusic ★13 - QQ音乐vue
  • vue-weather ★12 - VueJS天气demo

一、前端核心分析

*1.1、概述

Soc原则:关注点分离原则*

Vue 的核心库只关注视图层,方便与第三方库或既有项目整合。

HTML + CSS + JS : 视图 : 给用户看,刷新后台给的数据

网络通信 : axios

页面跳转 : vue-router

状态管理:vuex

Vue-UI : ICE , Element UI

1.2、前端三要素

  • HTML(结构):超文本标记语言(Hyper Text Markup Language),决定网页的结构和内容
  • CSS(表现):层叠样式表(Cascading Style Sheets),设定网页的表现样式。
  • JavaScript(行为):是一种弱类型脚本语言,其源码不需经过编译,而是由浏览器解释运行,用于控制网页的行为

1.3、结构层(HTML)

太简单,略

1.4、表现层(CSS)

CSS层叠样式表是一门标记语言,并不是编程语言,因此不可以自定义变量,不可以引用等,换句话说就是不具备任何语法支持,它主要缺陷如下:

  • 语法不够强大,比如无法嵌套书写,导致模块化开发中需要书写很多重复的选择器;
  • 没有变量和合理的样式复用机制,使得逻辑上相关的属性值必须以字面量的形式重复输出,导致难以维护;这就导致了我们在工作中无端增加了许多工作量。为了解决这个问题,前端开发人员会使用一种称之为【CSS预处理器】的工具,提供CSS缺失的样式层复用机制、减少冗余代码,提高样式代码的可维护性。大大的提高了前端在样式上的开发效率。

什么是CSS预处理器:

CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只需要使用这种语言进行CSS的编码工作。转化成通俗易懂的话来说就是“用一种专门的编程语言,进行Web页面样式设计,再通过编译器转化为正常的CSS文件,以供项目使用”。

常用的CSS预处理器有哪些

  • SASS:基于Ruby ,通过服务端处理,功能强大。解析效率高。需要学习Ruby语言,上手难度高于LESS。
  • LESS:基于NodeJS,通过客户端处理,使用简单。功能比SASS简单,解析效率也低于SASS,但在实际开发中足够了,所以如果我们后台人员如果需要的话,建议使用LESS。

1.5、行为层(JavaScript)

JavaScript一门弱类型脚本语言,其源代码在发往客户端运行之前不需要经过编译,而是将文本格式的字符代码发送给浏览器,由浏览器解释运行。

Native 原生JS开发

原生JS开发,也就是让我们按照【ECMAScript】标准的开发方式,简称ES,特点是所有浏览器都支持。截至到当前,ES标准以发布如下版本:

  • ES3
  • ES4(内部,未正式发布)
  • ES5(全浏览器支持)
  • ES6(常用,当前主流版本:webpack打包成为ES5支持)
  • ES7
  • ES8
  • ES9(草案阶段)

区别就是逐步增加新特性。
TypeScript 微软的标准
TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集, 而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。由安德斯·海尔斯伯格(C#、Delphi、TypeScript之父; .NET创立者) 主导。该语言的特点就是除了具备ES的特性之外还纳入了许多不在标准范围内的新特性,所以会导致很多浏览器不能直接支持TypeScript语法, 需要编译后(编译成JS) 才能被浏览器正确执行。

JavaScript框架

  • JQuery:大家熟知的JavaScript库,优点就是简化了DOM操作,缺点就是DOM操作太频繁,影响前端性能;在前端眼里使用它仅仅是为了兼容IE6,7,8;
  • Angular:Google收购的前端框架,由一群Java程序员开发,其特点是将后台的MVC模式搬到了前端并增加了模块化开发的理念,与微软合作,采用了TypeScript语法开发;对后台程序员友好,对前端程序员不太友好;最大的缺点是版本迭代不合理(如1代–>2 代,除了名字,基本就是两个东西;截止发表博客时已推出了Angular6)
  • React:Facebook 出品,一款高性能的JS前端框架;特点是提出了新概念 【虚拟DOM】用于减少真实 DOM 操作,在内存中模拟 DOM操作,有效的提升了前端渲染效率;缺点是使用复杂,因为需要额外学习一门【JSX】语言;
  • Vue:一款渐进式 JavaScript 框架,所谓渐进式就是逐步实现新特性的意思,如实现模块化开发、路由、状态管理等新特性。其特点是综合了 Angular(模块化)和React(虚拟 DOM) 的优点;
  • Axios:前端通信框架;因为 Vue 的边界很明确,就是为了处理 DOM,所以并不具备通信能力,此时就需要额外使用一个通信框架与服务器交互;当然也可以直接选择使用jQuery 提供的AJAX 通信功能;

二、前端发展史

2.1、UI框架

  • Ant-Design:阿里巴巴出品,基于React的UI框架
  • ElementUI、iview、ice:饿了么出品,基于Vue的UI框架
  • BootStrap:Teitter推出的一个用于前端开发的开源工具包
  • AmazeUI:又叫“妹子UI”,一款HTML5跨屏前端框架

2.2、JavaScript构建工具

  • Babel:JS编译工具,主要用于浏览器不支持的ES新特性,比如用于编译TypeScript
  • WebPack:模块打包器,主要作用就是打包、压缩、合并及按序加载
  • 注:以上知识点已将WebApp开发所需技能全部梳理完毕

2.3、三端同一

混合开发(Hybrid App)

主要目的是实现一套代码三端统一(PC、Android:.apk、iOS:.ipa)并能够调用到设备底层硬件(如:传感器、GPS、摄像头等),打包方式主要有以下两种:

  • 云打包:HBuild -> HBuildX,DCloud 出品;API Cloud
  • 本地打包: Cordova(前身是 PhoneGap)

微信小程序

详见微信官网,这里就是介绍一个方便微信小程序UI开发的框架:WeUI

2.4、后端技术

前端人员为了方便开发也需要掌握一定的后端技术但我们Java后台人员知道后台知识体系极其庞大复杂,所以为了方便前端人员开发后台应用,就出现了Node JS这样的技术。Node JS的作者已经声称放弃Node JS(说是架构做的不好再加上笨重的node modules,可能让作者不爽了吧)开始开发全新架构的De no
既然是后台技术,那肯定也需要框架和项目管理工具, Node JS框架及项目管理工具如下:

  • Express:Node JS框架
  • Koa:Express简化版
  • NPM:项目综合管理工具,类似于Maven
  • YARN:NPM的替代方案,类似于Maven和Gradle的关系

2.5、主流前端框架

Vue.js


iView

iview是一个强大的基于Vue的UI库, 有很多实用的基础组件比element ui的组件更丰富, 主要服务于PC界面的中后台产品。使用单文件的Vue组件化开发模式基于npm+webpack+babel开发, 支持ES 2015高质量、功能丰富友好的API, 自由灵活地使用空间。

  • 官网地址
  • Github
  • iview-admin
  • 码云

备注:属于前端主流框架,选型时可考虑使用,主要特点是移动端支持较多


Element UI

Element是饿了么前端开源维护的Vue UI组件库, 组件齐全, 基本涵盖后台所需的所有组件,文档讲解详细, 例子也很丰富。主要用于开发PC端的页面, 是一个质量比较高的Vue UI组件库。

  • 官网地址

  • vue-element-admin 码云

备注:属于前端主流框架,选型时可考虑使用,主要特点是桌面端支持较多


ICE

飞冰是阿里巴巴团队基于React/Angular/Vue的中后台应用解决方案, 在阿里巴巴内部, 已经有270多个来自几乎所有BU的项目在使用。飞冰包含了一条从设计端到开发端的完整链路,帮助用户快速搭建属于自己的中后台应用。

  • 官网地址。
  • Git hub

备注:主要组件还是以React为主, 截止2019年02月17日更新博客前对Vue的支持还不太完善,目前尚处于观望阶段


VantUI

Vant UI是有赞前端团队基于有赞统一的规范实现的Vue组件库, 提供了-整套UI基础组件和业务组件。通过Vant, 可以快速搭建出风格统一的页面,提升开发效率。

官网地址
Github


AtUI

at-ui是一款基于Vue 2.x的前端UI组件库, 主要用于快速开发PC网站产品。它提供了一套n pm+web pack+babel前端开发工作流程, CSS样式独立, 即使采用不同的框架实现都能保持统一的UI风格。
·官网地址
·Git hub


Cube Ul

cube-ui是滴滴团队开发的基于Vue js实现的精致移动端组件库。支持按需引入和后编译, 轻量灵活;扩展性强,可以方便地基于现有组件实现二次开发。

  • 官网地址
  • Github

混合开发


Flutter

Flutter是谷歌的移动端UI框架, 可在极短的时间内构建Android和iOS上高质量的原生级应用。Flutter可与现有代码一起工作, 它被世界各地的开发者和组织使用, 并且Flutter是免费和开源的。

  • 官网地址

Githu
备注:Google出品, 主要特点是快速构建原生APP应用程序, 如做混合应用该框架为必选框架


loni

lonic既是一个CSS框架也是一个Javascript UI库, lonic是目前最有潜力的一款HTML 5手机应用开发框架。通过SASS构建应用程序, 它提供了很多UI组件来帮助开发者开发强大的应用。它使用JavaScript MV VM框架和Angular JS/Vue来增强应用。提供数据的双向绑定, 使用它成为Web和移动开发者的共同选择。

  • 官网地址
  • 官网文档
  • Git hub

微信小程序

mpvue

mpvue是美团开发的一个使用Vue.js开发小程序的前端框架, 目前支持微信小程序、百度智能小程序,头条小程序和支付宝小程序。框架基于Vue.js, 修改了的运行时框架runtime和代码编译器compiler实现, 使其可运行在小程序环境中, 从而为小程序开发引入了Vue.js开发体验。

  • 官网地址
  • Git hub

​ 备注:完备的Vue开发体验, 井且支持多平台的小程序开发, 推荐使用


WeUI

WeUI是一套同微信原生视觉体验一致的基础样式库, 由微信官方设计团队为微信内网页和微信小程序量身设计, 令用户的使用感知更加统一。包含button、cell、dialog、toast、article、icon等各式元素。

  • 官网地址
  • Github

三、了解前后分离的演变史

为什么需要前后分离

3.1、后端为主的MVC时代

为了降低开发的复杂度, 以后端为出发点, 比如:Struts、Spring MVC等框架的使用, 就是后端的MVC时代;
以SpringMVC流程为例:

  • 发起请求到前端控制器(Dispatcher Servlet)
  • 前端控制器请求HandlerMapping查找Handler,可以根据xml配置、注解进行查找
  • 处理器映射器HandlerMapping向前端控制器返回Handler
  • 前端控制器调用处理器适配器去执行Handler
  • 处理器适配器去执行Handler
  • Handler执行完成给适配器返回ModelAndView
  • 处理器适配器向前端控制器返回ModelAndView,ModelAndView是SpringMvc框架的一个底层对象,包括Model和View
  • 前端控制器请求视图解析器去进行视图解析,根据逻辑视图名解析成真正的视图(JSP)
  • 视图解析器向前端控制器返回View
  • 前端控制器进行视图渲染,视图渲染将模型数据(在ModelAndView对象中)填充到request域
  • 前端控制器向用户响应结果

优点
MVC是一个非常好的协作模式, 能够有效降低代码的耦合度从架构上能够让开发者明白代码应该写在哪里。为了让View更纯粹, 还可以使用Thyme leaf、Frree marker等模板引擎, 使模板里无法写入Java代码, 让前后端分工更加清晰。

缺点

  • 前端开发重度依赖开发环境,开发效率低,这种架构下,前后端协作有两种模式:
  • 第一种是前端写DEMO, 写好后, 让后端去套模板。好处是DEMO可以本地开发, 很高效。不足是还需要后端套模板,有可能套错,套完后还需要前端确定,来回沟通调整的成本比较大;
  • 另一种协作模式是前端负责浏览器端的所有开发和服务器端的View层模板开发。好处是UI相关的代码都是前端去写就好,后端不用太关注,不足就是前端开发重度绑定后端环境,环境成为影响前端开发效率的重要因素。
  • 前后端职责纠缠不清:模板引擎功能强大,依旧可以通过拿到的上下文变量来实现各种业务逻辑。这样,只要前端弱势一点,往往就会被后端要求在模板层写出不少业务代码,还有一个很大的灰色地带是Controller, 页面路由等功能本应该是前端最关注的, 但却是由后端来实现。Controller本身与Model往往也会纠缠不清,看了让人咬牙的业务代码经常会出现在Controller层。这些问题不能全归结于程序员的素养, 否则JSP就够了。
  • 对前端发挥的局限性:性能优化如果只在前端做空间非常有限,于是我们经常需要后端合作,但由于后端框架限制,我们很难使用[Comet】、【Big Pipe】等技术方案来优化性能。

注:在这期间(2005年以前) , 包括早期的JSP、PHP可以称之为Web 1.0时代。在这里想说一句, 如果你是一名Java初学者, 请你不要再把一些陈旧的技术当回事了, 比如JSP, 因为时代在变、技术在变、什么都在变(引用扎克伯格的一句话:唯一不变的是变化本身);当我们去给大学做实训时,有些同学会认为我们没有讲什么干货,其实不然,只能说是你认知里的干货对于市场来说早就过时了而已

3.2、基于AJAX带来的SPA时代

时间回到2005年A OAX(Asynchronous JavaScript And XML, 异步JavaScript和XML,老技术新用法)被正式提出并开始使用CDN作为静态资源存储, 于是出现了JavaScript王者归来(在这之前JS都是用来在网页上贴狗皮膏药广告的) 的SPA(Single Page Application) 单页面应用时代。

优点
这种模式下, **前后端的分工非常清晰, 前后端的关键协作点是AJAX接口。**看起来是如此美妙, 但回过头来看看的话, 这与JSP时代区别不大。复杂度从服务端的JSP里移到了浏览器的JavaScript,浏览器端变得很复杂。类似Spring MVC, 这个时代开始出现浏览器端的分层架构:

缺点

  • 前后端接口的约定:如果后端的接口一塌糊涂,如果后端的业务模型不够稳定,那么前端开发会很痛苦;不少团队也有类似尝试,通过接口规则、接口平台等方式来做。有了和后端一起沉淀的接口规则,还可以用来模拟数据,使得前后端可以在约定接口后实现高效并行开发。
  • 前端开发的复杂度控制:SPA应用大多以功能交互型为主,JavaScript代码过十万行很正常。大量JS代码的组织,与View层的绑定等,都不是容易的事情。

3.3、前端为主的MV*时代

此处的MV*模式如下:

  • MVC(同步通信为主) :Model、View、Controller
  • MVP(异步通信为主) :Model、View、Presenter
  • MVVM(异步通信为主):Model、View、View Model为了降低前端开发复杂度,涌现了大量的前端框架,比如:Angular JS、React、Vue.js、Ember JS等, 这些框架总的原则是先按类型分层, 比如Templates、Controllers、Models, 然后再在层内做切分,如下图:

优点

  • 前后端职责很清晰:前端工作在浏览器端,后端工作在服务端。清晰的分工,可以让开发并行,测试数据的模拟不难, 前端可以本地开发。后端则可以专注于业务逻辑的处理, 输出RESTful等接口。
  • 前端开发的复杂度可控:前端代码很重,但合理的分层,让前端代码能各司其职。这一块蛮有意思的,简单如模板特性的选择,就有很多很多讲究。并非越强大越好,限制什么,留下哪些自由,代码应该如何组织,所有这一切设计,得花一本书的厚度去说明。
  • 部署相对独立:可以快速改进产品体验缺点
  • 代码不能复用。比如后端依旧需要对数据做各种校验,校验逻辑无法复用浏览器端的代码。如果可以复用,那么后端的数据校验可以相对简单化。
  • 全异步, 对SEO不利。往往还需要服务端做同步渲染的降级方案。
  • 性能并非最佳,特别是移动互联网环境下。
  • SPA不能满足所有需求, 依旧存在大量多页面应用。URL Design需要后端配合, 前端无法完全掌控。

3.4、Node JS带来的全栈时代

前端为主的MV*模式解决了很多很多问题, 但如上所述, 依旧存在不少不足之处。随着Node JS的兴起, JavaScript开始有能力运行在服务端。这意味着可以有一种新的研发模式:

在这种研发模式下,前后端的职责很清晰。对前端来说,两个UI层各司其职:

  • Front-end Ul layer处理浏览器层的展现逻辑。通过CSS渲染样式, 通过JavaScript添加交互功能, HTML的生成也可以放在这层, 具体看应用场景。
  • Back-end Ul layer处理路由、模板、数据获取、Cookie等。通过路由, 前端终于可以自主把控URL Design, 这样无论是单页面应用还是多页面应用, 前端都可以自由调控。后端也终于可以摆脱对展现的强关注,转而可以专心于业务逻辑层的开发。通过Node, WebServer层也是JavaScript代码, 这意味着部分代码可前后复用, 需要SEO的场景可以在服务端同步渲染,由于异步请求太多导致的性能问题也可以通过服务端来缓解。前一种模式的不足,通过这种模式几乎都能完美解决掉。*与JSP模式相比, 全栈模式看起来是一种回归, 也的确是一种向原始开发模式的回归, 不过是一种螺旋上升式的回归。*基于Node JS的全栈模式, 依旧面临很多挑战:
  • 需要前端对服务端编程有更进一步的认识。比如TCP/IP等网络知识的掌握。
  • Node JS层与Java层的高效通信。Node JS模式下, 都在服务器端, RESTful HTTP通信未必高效, 通过SOAP等方式通信更高效。一切需要在验证中前行。
  • 对部著、运维层面的熟练了解,需要更多知识点和实操经验。
  • 大量历史遗留问题如何过渡。这可能是最大最大的阻力。
  • 注:看到这里,相信很多同学就可以理解,为什么我总在课堂上说:“前端想学后台很难,而我们后端程序员学任何东西都很简单”;就是因为我们后端程序员具备相对完善的知识体系。

全栈!So Easy!
3.5、总结
综上所述,模式也好,技术也罢,没有好坏优劣之分,只有适合不适合;前后分离的开发思想主要是基于Soc(关注度分离原则),上面种种模式,都是让前后端的职责更清晰,分工更合理高效。

四、第一个Vue程序

4.1、什么是MVVM

MVVM(Model-View-ViewModel)是一种软件设计模式,由微软WPF(用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于Java Applet,简单点说就是在浏览器上运行WPF)的架构师Ken Cooper和Ted Peters开发,是一种简化用户界面的事件驱动编程方式。由John Gossman(同样也是WPF和Sliverlight的架构师)与2005年在他的博客上发表。

MVVM源自于经典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。其作用如下:

  • 该层向上与视图层进行双向数据绑定
  • 向下与Model层通过接口请求进行数据交互

MVVM已经相当成熟了,主要运用但不仅仅在网络应用程序开发中。当下流行的MVVM框架有Vue.js,Anfular JS

4.2、为什么要使用MVVM

MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处

  • 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 可复用:你可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
  • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMode),设计人员可以专注于页面设计。
  • 可测试:界面素来是比较难以测试的,而现在测试可以针对ViewModel来写。

(1)View

View是视图层, 也就是用户界面。前端主要由HTH L和csS来构建, 为了更方便地展现vi eu to del或者Hodel层的数据, 已经产生了各种各样的前后端模板语言, 比如FreeMarker,Thyme leaf等等, 各大MV VM框架如Vue.js.Angular JS, EJS等也都有自己用来构建用户界面的内置模板语言。

(2)Model

Model是指数据模型, 泛指后端进行的各种业务逻辑处理和数据操控, 主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则

(3)ViewModel

ViewModel是由前端开发人员组织生成和维护的视图数据层。在这一层, 前端开发者对从后端获取的Model数据进行转换处理, 做二次封装, 以生成符合View层使用预期的视图数据模型。
  需要注意的是View Model所封装出来的数据模型包括视图的状态和行为两部分, 而Model层的数据模型是只包含状态的

  • 比如页面的这一块展示什么,那一块展示什么这些都属于视图状态(展示)
  • 页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互)

视图状态和行为都封装在了View Model里。这样的封装使得View Model可以完整地去描述View层。由于实现了双向绑定, View Model的内容会实时展现在View层, 这是激动人心的, 因为前端开发者再也不必低效又麻烦地通过操纵DOM去更新视图。
  MVVM框架已经把最脏最累的一块做好了, 我们开发者只需要处理和维护View Model, 更新数据视图就会自动得到相应更新,真正实现事件驱动编程。
  View层展现的不是Model层的数据, 而是ViewModel的数据, 由ViewModel负责与Model层交互,获取和更新数据, 这就完全解耦了View层和Model层, 这个解耦是至关重要的, 它是前后端分离方案实施的重要一环。

4.3、Vue

Vue(读音/vju/, 类似于view) 是一套用于构建用户界面的渐进式框架, 发布于2014年2月。与其它大型框架不同的是, Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层, 不仅易于上手, 还便于与第三方库(如:vue-router,vue-resource,vue x) 或既有项目整合。

(1)MVVM模式的实现者

  • Model:模型层, 在这里表示JavaScript对象
  • View:视图层, 在这里表示DOM(HTML操作的元素)
  • ViewModel:连接视图和数据的中间件, Vue.js就是MVVM中的View Model层的实现者

在MVVM架构中, 是不允许数据和视图直接通信的, 只能通过ViewModel来通信, 而View Model就是定义了一个Observer观察者

  • ViewModel能够观察到数据的变化, 并对视图对应的内容进行更新
  • ViewModel能够监听到视图的变化, 并能够通知数据发生改变

至此, 我们就明白了, Vue.js就是一个MV VM的实现者, 他的核心就是实现了DOM监听与数据绑定

(2)为什么要使用Vue.js

  • 轻量级, 体积小是一个重要指标。Vue.js压缩后有只有20多kb(Angular压缩后56kb+,React压缩后44kb+)
  • 移动优先。更适合移动端, 比如移动端的Touch事件
  • 易上手,学习曲线平稳,文档齐全
  • 吸取了Angular(模块化) 和React(虚拟DOM) 的长处, 并拥有自己独特的功能,如:计算属性
  • 开源,社区活跃度高

4.4、第一个Vue程序

【说明】IDEA可以安装Vue的插件!
  注意:Vue不支持IE 8及以下版本, 因为Vue使用了IE 8无法模拟的ECMAScript 5特性。但它支持所有兼容ECMAScript 5的浏览器。

(1)下载地址

开发版本

  • 包含完整的警告和调试模式:https://yuejs/js/vue.js
  • 删除了警告, 30.96KB min+gzip:https://vuejs/js/vue.min.js

CDN

(2)代码编写

Vue.js的核心是实现了MVVM模式, 她扮演的角色就是View Model层, 那么所谓的第一个应用程序就是展示她的数据绑定功能,操作流程如下:

1、创建一个HTML文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
</html>

2、引入Vue.js

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr/npm/vue@2.6.14/dist/vue.min.js"></script>
12

3、创建一个Vue实例

<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:数据*/
        data:{
            message:"hello,vue!"
        }
    });
</script>

说明:

  • el: '#vue':绑定元素的ID
  • data:{message:'Hello Vue!'}:数据对象中有一个名为message的属性,并设置了初始值 Hello Vue!

4、将数据绑定到页面元素

<!--view层,模板-->
<div id="app">
    {{message}}
</div>

(3)完整的HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层,模板-->
<div id="app">
    {{message}}
</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:数据*/
        data:{
            message:"hello,vue!"
        }
    });
</script>
</body>
</html>

(4)测试

为了能够更直观的体验Vue带来的数据绑定功能, 我们需要在浏览器测试一番, 操作流程如下:
  1、在浏览器上运行第一个Vue应用程序, 进入开发者工具
  2、在控制台输入vm.message=‘HelloWorld’, 然后回车, 你会发现浏览器中显示的内容会直接变成HelloWorld
  此时就可以在控制台直接输入vm.message来修改值, 中间是可以省略data的, 在这个操作中, 我并没有主动操作DOM, 就让页面的内容发生了变化, 这就是借助了Vue的数据绑定功能实现的; MV VM模式中要求View Model层就是使用观察者模式来实现数据的监听与绑定, 以做到数据与视图的快速响应。

五、基础语法指令

5.1、v-bind

我们已经成功创建了第一个Vue应用!看起来这跟渲染一个字符串模板非常类似, 但是Vue在背后做了大量工作。现在数据和DOM已经被建立了关联, 所有东西都是响应式的。我们在控制台操作对象属性,界面可以实时更新!
  我们还可以使用v-bind来绑定元素特性!

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层,模板-->
<div id="app">
    <span v-bind:title="message">
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
  </span>
</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:数据*/
        data:{
            message: '页面加载于 ' + new Date().toLocaleString()
        }
    });
</script>
</body>
</html>

你看到的v-bind等被称为指令。指令带有前缀v以表示它们是Vue提供的特殊特性。可能你已经猜到了, 它们会在渲染的DOM上应用特殊的响应式行为在这里,该指令的意思是:“将这个元素节点的title特性和Vue实例的message属性保持一致”。
  如果你再次打开浏览器的JavaScript控制台, 输入app, message=‘新消息’,就会再一次看到这个绑定了title特性的HTML已经进行了更新。

5.2、v-if, v-else

什么是条件判断语句,就不需要我说明了吧,以下两个属性!

v-if
v-else
上代码

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
    <h1 v-if="ok">Yes</h1>
    <h1 v-else>No</h1>
   
</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:数据*/
        data:{
            type: true
        }
    });
</script>
</body>
</html>

测试:
1.在浏览器上运行,打开控制台!
2.在控制台输入vm.ok=false然后回车,你会发现浏览器中显示的内容会直接变成NO
  注:使用v-*属性绑定数据是不需要双花括号包裹的

v-else-if

v-if
v-else-if
v-else
注:===三个等号在JS中表示绝对等于(就是数据与类型都要相等)上代码:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
    <h1 v-if="type==='A'">A</h1>
    <h1 v-else-if="type==='B'">B</h1>
    <h1 v-else-if="type==='D'">D</h1>
    <h1 v-else>C</h1>

</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:数据*/
        data:{
            type: 'A'
        }
    });
</script>
</body>
</html>

5.3、v-for

  • v-for

格式说明

<div id="app">
    <li v-for="(item,index) in items">
        {{item.message}}---{{index}}
    </li>

</div>
123456

注:items是数组,item是数组元素迭代的别名。我们之后学习的Thymeleaf模板引擎的语法和这个十分的相似!
  上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
    <li v-for="(item,index) in items">
        {{item.message}}---{{index}}
    </li>

</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:数据*/
        data:{
            items:[
                {message:'狂神说Java'},
                {message:'狂神说前端'},
                {message:'狂神说运维'}
            ]
        }
    });
</script>
</body>
</html>

测试:在控制台输入vm.items.push({message:'狂神说运维'}),尝试追加一条数据,你会发现浏览器中显示的内容会增加一条狂神说运维.

5.4、v-on

v-on监听事件
 emsp;事件有Vue的事件、和前端页面本身的一些事件!我们这里的click是vue的事件, 可以绑定到Vue中的methods中的方法事件!
  上代码:

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <button v-on:click="sayHi">点我</button>
</div>

<script src="https://cdn.jsdelivr/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            message:'Hello World'
        },
        methods:{
            sayHi:function(event){
                //'this'在方法里面指向当前Vue实例
                alert(this.message);
            }
        }
    });
</script>
</body>
</html>

点击测试
  Vue还有一些基本的使用方式, 大家有需要的可以再跟着官方文档看看, 因为这些基本的指令几乎我们都见过了,一通百通!掌握学习的方式!

六、表单双绑、组件

6.1、什么是双向数据绑定

Vue.js是一个MV VM框架, 即数据双向绑定, 即当数据发生变化的时候, 视图也就发生变化, 当视图发生变化的时候,数据也会跟着同步变化。这也算是Vue.js的精髓之处了。
  值得注意的是,我们所说的数据双向绑定,一定是对于UI控件来说的非UI控件不会涉及到数据双向绑定。单向数据绑定是使用状态管理工具的前提。如果我们使用vue x那么数据流也是单项的,这时就会和双向数据绑定有冲突。

(1)为什么要实现数据的双向绑定

在Vue.js中,如果使用vuex, 实际上数据还是单向的, 之所以说是数据双向绑定,这是用的UI控件来说, 对于我们处理表单, Vue.js的双向数据绑定用起来就特别舒服了。即两者并不互斥,在全局性数据流使用单项,方便跟踪;局部性数据流使用双向,简单易操作。

6.2、在表单中使用双向数据绑定

你可以用v-model指令在表单、及元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇, 但v-model本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
  注意:v-model会忽略所有表单元素的value、checked、selected特性的初始值而总是将Vue实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值!

(1)单行文本

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    输入的文本:<input type="text" v-model="message" value="hello">{{message}}
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            message:""
        }
    });
</script>
</body>
</html>

(2)多行文本

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
   多行文本:<textarea v-model="pan"></textarea>&nbsp;&nbsp;多行文本是:{{pan}}
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            message:"Hello hello!"
        }
    });
</script>
</body>
</html>

(3)单复选框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    单复选框:
    <input type="checkbox" id="checkbox" v-model="checked">
    &nbsp;&nbsp;
    <label for="checkbox">{{checked}}</label>
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            checked:false
        }
    });
</script>
</body>
</html>

(4)多复选框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    多复选框:
    <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
    &nbsp;&nbsp;
    <label for="jack">Jack</label>
    <input type="checkbox" id="join" value="Join" v-model="checkedNames">
    &nbsp;&nbsp;
    <label for="join">Jack</label>
    <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
    &nbsp;&nbsp;
    <label for="mike">Mike</label>
    <span>选中的值:{{checkedNames}}</span>
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            checkedNames:[]
        }
    });
</script>
</body>
</html>

(6)单选按钮

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    单选框按钮
    <input type="radio" id="one" value="One" v-model="picked">
    <label for="one">One</label>
    <input type="radio" id="two" value="Two" v-model="picked">
    <label for="two">Two</label>
    <span>选中的值:{{picked}}</span>
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            picked:'Two'
        }
    });
</script>
</body>
</html>

(7)下拉框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
<!--    性别:
    <input type="radio" name="sex" value="男" v-model="pan">男
    <input type="radio" name="sex" value="女" v-model="pan">女
    <p>选中了:{{pan}}</p>-->

    下拉框:
    <select v-model="pan">
        <option value="" disabled>---请选择---</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
        <option>D</option>
    </select>
    <span>value:{{pan}}</span>



</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            pan:"A"
        }
    });
</script>
</body>
</html>

注意:v-model表达式的初始值未能匹配任何选项,元系将被渲染为“未选中”状态。 在iOS中, 这会使用户无法选择第一个选项,因为这样的情况下,iOS不会触发change事件。因此,更推荐像上面这样提供一个值为空的禁用选项。

6.3、什么是组件

组件是可复用的Vue实例, 说白了就是一组可以重复使用的模板, 跟JSTL的自定义标签、Thymeleal的th:fragment等框架有着异曲同工之妙,通常一个应用会以一棵嵌套的组件树的形式来组织:

例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。

(1)第一个Vue组件

注意:在实际开发中,我们并不会用以下方式开发组件,而是采用vue-cli创建,vue模板文件的方式开发,以下方法只是为了让大家理解什么是组件。
  使用Vueponent()方法注册组件,格式如下:

<div id="app">
  <huan></huan>
</div>

<script src="https://cdn.jsdelivr/npm/vue@2.6.14/dist/vue.min.js"></script>
<script >
    //先注册组件
    Vue.component("huan",{
        
        template:'<li>Hello</li>'

    });
    //再实例化Vue
    var vm = new Vue({
        el:"#app",
    });
</script>

说明:

Vueponent():注册组件
pan:自定义组件的名字
template:组件的模板
(2)使用props属性传递参数
像上面那样用组件没有任何意义,所以我们是需要传递参数到组件的,此时就需要使用props属性了!
  注意:默认规则下props属性里的值不能为大写;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <!--组件:传递给组件中的值:props-->
    <!--组件,props传递给组件的值
        先遍历出值也就是item
        再通过bind将值绑定到xm,
        props取出绑定的值
        用template(模板)输出
        -->
  <huan v-for="item in items" v-bind:xm="item"></huan>
</div>

<script src="https://cdn.jsdelivr/npm/vue@2.6.14/dist/vue.min.js"></script>
<script type="text/javascript">
    //定义组件
    Vue.component("huan",{
        props:['xm'],
        template:'<li>{{xm}}</li>'

    });
    var vm = new Vue({
        el:"#app",
        data:{
            items:["java","Linux","前端"]
        }
    });
</script>
</body>
</html>

说明:

  • v-for=“item in items”:遍历Vue实例中定义的名为items的数组,并创建同等数量的组件
  • v-bind:panh=“item”:将遍历的item项绑定到组件中props定义名为item属性上;= 号左边的panh为props定义的属性名,右边的为item in items 中遍历的item项的值

七、Axios异步通信

7.1、什么是Axios

Axios是一个开源的可以用在浏览器端和Node JS的异步通信框架, 她的主要作用就是实现AJAX异步通信,其功能特点如下:

从浏览器中创建XMLHttpRequests
从node.js创建http请求
支持Promise API[JS中链式编程]
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换JSON数据
客户端支持防御XSRF(跨站请求伪造)

GitHub:https://github/axios/axios
  中文文档:http://www.axios-js/

7.2、为什么要使用Axios

由于Vue.js是一个视图层框架并且作者(尤雨溪) 严格准守SoC(关注度分离原则)所以Vue.js并不包含AJAX的通信功能, 为了解决通信问题, 作者单独开发了一个名为vue-resource的插件, 不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios框架。少用jQuery, 因为它操作Dom太频繁!

7.3、第一个Axios应用程序

咱们开发的接口大部分都是采用JSON格式, 可以先在项目里模拟一段JSON数据, 数据内容如下:创建一个名为data.json的文件并填入上面的内容, 放在项目的根目录下

{
  "name": "狂神说Java",
  "url": "https://blog.kuangstudy",
  "page": 1,
  "isNonProfit": true,
  "address": {
    "street": "含光门",
    "city": "陕西西安",
    "country": "中国"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://space.bilibili/95256449"
    },
    {
      "name": "狂神说Java",
      "url": "https://blog.kuangstudy"
    },
    {
      "name": "百度",
      "url": "https://www.baidu/"
    }
  ]
}

测试代码

<!DOCTYPE html>
<html lang="en" xmlns:v-binf="http://www.w3/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--v-cloak 解决闪烁问题-->
    <style>
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
<div id="vue">
    <div>地名:{{info.name}}</div>
    <div>地址:{{info.address.country}}--{{info.address.city}}--{{info.address.street}}</div>
    <div>链接:<a v-binf:href="info.url" target="_blank">{{info.url}}</a> </div>
</div>

<!--引入js文件-->
<script src="https://cdn.jsdelivr/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#vue",
        //data:属性:vm
        data(){
            return{
                info:{
                    name:null,
                    address:{
                        country:null,
                        city:null,
                        street:null
                    },
                    url:null
                }
            }
        },
        mounted(){//钩子函数
            axios
                .get('data.json')
                .then(response=>(this.info=response.data));
        }
    });
</script>
</body>
</html>

说明:

  1. 在这里使用了v-bind将a:href的属性值与Vue实例中的数据进行绑定
  2. 使用axios框架的get方法请求AJAX并自动将数据封装进了Vue实例的数据对象中
  3. 我们在data中的数据结构必须和Ajax响应回来的数据格式匹配!

7.4、Vue的生命周期

官方文档:https://cn.vuejs/v2/guide/instance.html#生命周期图示
  Vue实例有一个完整的生命周期,也就是从开始创建初女台化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
  在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册JS方法,可以让我们用自己注册的JS方法控制整个大局,在这些事件响应方法中的this直接指向的是Vue的实例。

八、计算属性、内容分发、自定义事件

1、什么是计算属性

计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
    <p>currentTime1:{{currentTime1()}}</p>
    <p>currentTime2:{{currentTime2}}</p>
</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
          message:"pan"
        },
        methods:{
            currentTime1:function(){
                return Date.now();//返回一个时间戳
            }
        },
        computed:{
            currentTime2:function(){//计算属性:methods,computed方法名不能重名,重名之后,只会调用methods的方法
                this.message;
                return Date.now();//返回一个时间戳
            }
        }
    });
</script>
</body>
</html>

注意:methods和computed里的东西不能重名
说明:

  • methods:定义方法, 调用方法使用currentTime1(), 需要带括号
  • computed:定义计算属性, 调用属性使用currentTime2, 不需要带括号:this.message是为了能够让currentTime2观察到数据变化而变化
  • 如何在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用vm.message=”q in jiang", 改变下数据的值,再次测试观察效果!
  • 结论:
  • 调用方法时,每次都需要讲行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;

8.2、内容分发

在Vue.js中我们使用元素作为承载分发内容的出口,作者称其为插槽,可以应用在组合组件的场景中;

测试

比如准备制作一个待办事项组件(todo) , 该组件由待办标题(todo-title) 和待办内容(todo-items)组成,但这三个组件又是相互独立的,该如何操作呢?
  第一步定义一个待办事项的组件

<div id="app">
    <todo></todo>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    Vue.component('todo',{
        template:'<div>\
                <div>代办事项</div>\
                <ul>\
                    <li>学习狂神说Java</li>\
                </ul>\
            </div>'
    })
</script>

第二步 我们需要让,代办事项的标题和值实现动态绑定,怎么做呢?我们可以留一个插槽!
  1-将上面的代码留出一个插槽,即slot

 Vueponent('todo',{
        template:'<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                    <slot name="todo-items"></slot>\
                </ul>\
            </div>'
    });

2-定义一个名为todo-title的待办标题组件 和 todo-items的待办内容组件

Vueponent('todo-title',{
        props:['title'],
        template:'<div>{{title}}</div>'
    });
   
12345
//这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!
    Vueponent("todo-items",{
        props:["item","index"],
        template:"<li>{{index+1}},{{item}}</li>"
    });

3-实例化Vue并初始化数据

 var vm = new Vue({
        el:"#vue",
        data:{
            todoItems:['test1','test2','test3']
        }
    });

4-将这些值,通过插槽插入

<div id="vue">
    <todo>
        <todo-title slot="todo-title" :title="秦老师系列课程"></todo-title>
        <!--<todo-items slot="todo-items" v-for="{item,index} in todoItems" v-bind:item="item"></todo-items>-->
        <!--如下为简写-->
        <todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items
    </todo>
</div>

说明:我们的todo-title和todo-items组件分别被分发到了todo组件的todo-title和todo-items插槽中
  完整代码如下:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <todo>
                <todo-title slot="todo-title" :title="title"></todo-title>
                <!--<todo-items slot="todo-items" v-for="{item,index} in todoItems" v-bind:item="item"></todo-items>-->
                <!--如下为简写-->
                <todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items>
            </todo>
        </div>
        <script src="https://cdn.jsdelivr/npm/vue@2.6.14/dist/vue.js"></script>
        <script>
            /*Vueponent('todo', {
                template: '<div>\
                    <div>代办事项</div>\
                    <ul>\
                    <li>学习狂神说Java</li>\
                </ul>\
            </div>'
            })
            
            todo为组件,------->组件中有插槽
            todo-title
            todo-items  为插槽填充数据{{}}
            */
            Vue.component('todo', {
                template: '<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                    <slot name="todo-items"></slot>\
                </ul>\
            </div>'
            });

            Vue.component('todo-title', {
                props: ['title'],
                template: '<div>{{title}}</div>'
            });

            //这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!
            Vue.component("todo-items", {
                props: ["item", "index"],
                template: "<li>{{item}}</li>"
            });
            const vm = new Vue({
                el: "#app",
                data: {
                    title: "huan老师系列课程",
                    todoItems: ['test1', 'test2', 'test3']
                },
            });
        </script>
    </body>
</html>

8.3、自定义事件

通以上代码不难发现,数据项在Vue的实例中, 但删除操作要在组件中完成, 那么组件如何才能删除Vue实例中的数据呢?此时就涉及到参数传递与事件分发了, Vue为我们提供了自定义事件的功能很好的帮助我们解决了这个问题; 使用this.$emit(‘自定义事件名’, 参数) , 操作过程如下:

1、增加了methods对象、定义removeTodoltems的方法

var vm = new Vue({
        el:"#vue",
        data:{
            title_text:"秦老师系列课程",
            todoItems:['test1','test2','test3']
        },
        methods:{
            removeItems:function(index){
                console.log("删除了"+this.todoItems[index]+"OK");
                //splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目,其中index
                this.todoItems.splice(index,1);
            }
        }
    });

2-修改todo-items待办内容组件的代码,增加一个删除按钮,并且绑定事件!

 Vueponent("todo-items",{
        props:["item_p","index_p"],
        template:"<li>{{index_p+1}},{{item_p}} <button @click='remove'>删除</button></li>",
        methods:{
            remove:function (index) {
            //这里的remove是自定义事件名称,需要在HTML中使用v-on:remove的方式
                //this.$emit 自定义事件分发
                this.$emit('remove',index);
            }
        }
    });

3-修改todo-items待办内容组件的HTML代码,

增加一个自定义事件,比如叫remove,可以和组件的方法绑定,然后绑定到vue的方法!

<!--增加了v-on:remove="removeTodoItems(index)"自定义事件,该组件会调用Vue实例中定义的-->
<todo-items slot="todo-items" v-for="(item,index) in todoItems"
                    :item_p="item" :index_p="index" v-on:remove="removeItems(index)" :key="index"></todo-items>

对上一个代码进行修改,实现删除功能

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <todo>
                <todo-title slot="todo-title" :title="title"></todo-title>
                <!--<todo-items slot="todo-items" v-for="{item,index} in todoItems" v-bind:item="item"></todo-items>-->
                <!--如下为简写-->
                <todo-items slot="todo-items" v-for="(item,index) in todoItems"
                            :item="item" :index="index" v-on:remove="removeItems(index)" :key="index">
                </todo-items>
            </todo>
        </div>
        <script src="https://cdn.jsdelivr/npm/vue@2.6.14/dist/vue.js"></script>
        <script>
            /*Vueponent('todo', {
                template: '<div>\
                    <div>代办事项</div>\
                    <ul>\
                    <li>学习狂神说Java</li>\
                </ul>\
            </div>'
            })

            todo为组件,------->组件中有插槽
            todo-title
            todo-items  为插槽填充数据{{}}
            */
            Vue.component('todo', {
                template: '<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                    <slot name="todo-items"></slot>\
                </ul>\
            </div>'
            });

            Vue.component('todo-title', {
                props: ['title'],
                template: '<div>{{title}}</div>'
            });

            //这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!
            Vue.component("todo-items", {
                props: ["item", "index"],
                template: "<li>{{index+1}},{{item}}<button @click='remove'>删除</button></li>",

                methods: {
                    remove: function (index) {
                        //这里的remove是自定义事件名称,需要在HTML中使用v-on:remove的方式
                        //this.$emit 自定义事件分发
                        this.$emit('remove', index);
                    }
                }
            });
            const vm = new Vue({
                el: "#app",
                data: {
                    title: "huan老师系列课程",
                    todoItems: ['test1', 'test2', 'test3']
                },
                methods: {
                    removeItems: function (index) {
                        console.log("删除了" + this.todoItems[index] + "OK");
                        //splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目,其中index
                        this.todoItems.splice(index, 1);
                    }
                }
            });
        </script>
    </body>
</html>

8.4、Vue入门小结

核心:数据驱动,组件化

优点:借鉴了AngularJS的模块化开发和React的虚拟Dom,虚拟Dom就是把Demo操作放到内存中执行;

常用的属性:

  • v-if
  • v-else-if
  • v-else
  • v-for
  • v-on绑定事件,简写@
  • v-model数据双向绑定
  • v-bind给组件绑定参数,简写:

组件化:

  • 组合组件slot插槽
  • 组件内部绑定事件需要使用到this.$emit(“事件名”,参数);
  • 计算属性的特色,缓存计算数据

遵循SoC关注度分离原则,Vue是纯粹的视图框架,并不包含,比如Ajax之类的通信功能,为了解决通信问题,我们需要使用Axios框架做异步通信;

说明
Vue的开发都是要基于NodeJS,实际开发采用Vue-cli脚手架开发,vue-router路由,vuex做状态管理;Vue UI,界面我们一般使用ElementUI(饿了么出品),或者ICE(阿里巴巴出品)来快速搭建前端项目~~

官网:

  • https://element.eleme/#/zh-CN
  • https://ice.work/

九、第一个vue-cli项目

9.1、什么是vue-cli

vue-cli官方提供的一个脚手架,用于快速生成一个vue的项目模板;
  预先定义好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个估计项目就是脚手架,我们的开发更加的快速;
  项目的功能

统一的目录结构
本地调试
热部署
单元测试
集成打包上线

9.2、需要的环境

Node.js:http://nodejs/download/
安装就是无脑的下一步就好,安装在自己的环境目录下
Git:https://git-scm/doenloads
镜像:https://npm.taobao/mirrors/git-for-windows/
确认nodejs安装成功:

cmd下输入node -v,查看是否能够正确打印出版本号即可!
cmd下输入npm -v,查看是否能够正确打印出版本号即可!
这个npm,就是一个软件包管理工具,就和linux下的apt软件安装差不多!

3.安装后,检查是否安装成功
vue -V

# -g 就是全局安装---设置默认下载路径:
一般是:
npm install -gd express --registry=http://registry.npm.taobao
全局是:
npm config set registry https://registry.npm.taobao

安装的过程可能有点慢~,耐心等待!虽然安装了cnpm,但是尽量少用!
  安装的位置:C:\Users\administrator\AppData\Roaming\npm

安装vue-cli

npm install --global vue-cli-g
#测试是否安装成功#查看可以基于哪些模板创建vue应用程序,通常我们选择webpack
vue list

9.3、第一个vue-cli应用程序

1.创建一个Vue项目,

我们随便建立一个空的文件夹在电脑上,我这里在D盘下新建一个目录

cd /d F:\IJ\Vue

2.创建一个基于webpack模板的vue应用程序

#1、首先需要进入到对应的目录 cd /d F:\IJ\Vue
#2、这里的myvue是顶日名称,可以根据自己的需求起名
vue init webpack myvue

一路都选择no即可;
  说明:

Project name:项目名称,默认回车即可
Project description:项目描述,默认回车即可
Author:项目作者,默认回车即可
Install vue-router:是否安装vue-router,选择n不安装(后期需要再手动添加)
Use ESLint to lint your code:是否使用ESLint做代码检查,选择n不安装(后期需要再手动添加)
Set up unit tests:单元测试相关,选择n不安装(后期需要再手动添加)
Setupe2etests with Nightwatch:单元测试相关,选择n不安装(后期需要再手动添加)
Should we run npm install for you after the,project has been created:创建完成后直接初始化,选择n,我们手动执行;运行结果!

Project name myvue
? Project description
? Author
? Vue build (Use arrow keys)
? Vue build standalone(编译执行第一个)
? Install vue-router? No
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) no

(1)初始化并运行

cd myvue
npm install
npm run dev

执行完成后,目录多了很多依赖

当出现问题时,可以查看提示进行处理如下

3、idea打开

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jk87wUG4-1629387969201)(Vue.assets/image-20210819131644186.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eyFyE18s-1629387969202)(Vue.assets/image-20210819131741455.png)]

设置npm

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xll7KLZ1-1629387969203)(Vue.assets/image-20210819131810548.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t64clY3Y-1629387969204)(Vue.assets/image-20210819131847385.png)]

十、webpack使用

10.1、什么是Webpack

本质上, webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler) 。当webpack处理应用程序时, 它会递归地构建一个依赖关系图(dependency graph) , 其中包含应用程序需要的每个模块, 然后将所有这些模块打包成一个或多个bundle.
  Webpack是当下最热门的前端资源模块化管理和打包工具, 它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分离,等到实际需要时再异步加载。通过loader转换, 任何形式的资源都可以当做模块, 比如Commons JS、AMD、ES 6、CSS、JSON、Coffee Script、LESS等;
  伴随着移动互联网的大潮, 当今越来越多的网站已经从网页模式进化到了WebApp模式。它们运行在现代浏览器里, 使用HTML 5、CSS 3、ES 6等新的技术来开发丰富的功能, 网页已经不仅仅是完成浏览器的基本需求; WebApp通常是一个SPA(单页面应用) , 每一个视图通过异步的方式加载,这导致页面初始化和使用过程中会加载越来越多的JS代码,这给前端的开发流程和资源组织带来了巨大挑战。
  前端开发和其他开发工作的主要区别,首先是前端基于多语言、多层次的编码和组织工作,其次前端产品的交付是基于浏览器的,这些资源是通过增量加载的方式运行到浏览器端,如何在开发环境组织好这些碎片化的代码和资源,并且保证他们在浏览器端快速、优雅的加载和更新,就需要一个模块化系统,这个理想中的模块化系统是前端工程师多年来一直探索的难题。

10.2、模块化的演进

Script标签

    <script src = "module1.js"></script>
    <script src = "module2.js"></script>
    <script src = "module3.js"></script>

这是最原始的JavaScript文件加载方式,如果把每一个文件看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在window对象中,不同模块的调用都是一个作用域。
  这种原始的加载方式暴露了一些显而易见的弊端:

全局作用域下容易造成变量冲突
文件只能按照

CommonsJS


服务器端的NodeJS遵循CommonsJS规范,该规范核心思想是允许模块通过require方法来同步加载所需依赖的其它模块,然后通过exports或module.exports来导出需要暴露的接口。

require("module");
require("../module.js");
export.doStuff = function(){};
module.exports = someValue;
1234

优点:

服务器端模块便于重用
NPM中已经有超过45万个可以使用的模块包
简单易用
缺点:

同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的
不能非阻塞的并行加载多个模块
实现:

服务端的NodeJS
•Browserify,浏览器端的CommonsJS实现,可以使用NPM的模块,但是编译打包后的文件体积较大
modules-webmake,类似Browserify,但不如Browserify灵活
wreq,Browserify的前身

AMD

Asynchronous Module Definition规范其实主要一个主要接口define(id?,dependencies?,factory);它要在声明模块的时候指定所有的依赖dependencies,并且还要当做形参传到factory中,对于依赖的模块提前执行。

define(“module”,[“dep1”,“dep2”],functian(d1,d2){
return someExportedValue;
});
require([“module”,“…/file.js”],function(module,file){});

优点

适合在浏览器环境中异步加载模块
可以并行加载多个模块
缺点

提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不畅
不符合通用的模块化思维方式,是一种妥协的实现
实现

RequireJS

curl
CMD
Commons Module Definition规范和AMD很相似,尽保持简单,并与CommonsJS和NodeJS的Modules规范保持了很大的兼容性。

define(function(require,exports,module){
var $=require("jquery");
var Spinning = require("./spinning");
exports.doSomething = ...;
module.exports=...;
});

优点:

依赖就近,延迟执行
可以很容易在NodeJS中运行缺点
依赖SPM打包,模块的加载逻辑偏重
实现

Sea.js
coolie

ES6模块

EcmaScript 6标准增加了JavaScript语言层面的模块体系定义。ES 6模块的设计思想, 是尽量静态化, 使编译时就能确定模块的依赖关系, 以及输入和输出的变量。Commons JS和AMD模块,都只能在运行时确定这些东西。

import “jquery”
export function doStuff(){}
module “localModule”{}

优点

容易进行静态分析
面向未来的Ecma Script标准
缺点

原生浏览器端还没有实现该标准
全新的命令,新版的Node JS才支持
实现

Babel
大家期望的模块
  系统可以兼容多种模块风格, 尽量可以利用已有的代码, 不仅仅只是JavaScript模块化, 还有CSS、图片、字体等资源也需要模块化。

10.3、安装Webpack

WebPack是一款模块加载器兼打包工具, 它能把各种资源, 如JS、JSX、ES 6、SASS、LESS、图片等都作为模块来处理和使用。

npm install webpack -g
npm install webpack-cli -g

测试安装成功

  • webpack -v

  • webpack-cli -v

配置
创建 webpack.config.js配置文件

  • entry:入口文件, 指定Web Pack用哪个文件作为项目的入口
  • output:输出, 指定WebPack把处理完成的文件放置到指定路径
  • module:模块, 用于处理各种类型的文件
  • plugins:插件, 如:热更新、代码重用等
  • resolve:设置路径指向
  • watch:监听, 用于设置文件改动后直接打包

直接运行webpack命令打包

10.4、使用webpack

  1. 创建项目
  2. 创建一个名为modules的目录,用于放置JS模块等资源文件
  3. 在modules下创建模块文件,如hello.js,用于编写JS模块相关代码
    //暴露一个方法:sayHi
    exports.sayHi = function(){
        document.write("<div>Hello Webpack</div>");
    }
  1. 在modules下创建一个名为main.js的入口文件,用于打包时设置entry属性

  2. //require 导入一个模块,就可以调用这个模块中的方法了
    var hello = require("./hello");
    hello.sayHi();
    
    1. 在项目目录下创建webpack.config.js配置文件,使用webpack命令打包(要不然scr找不到)
module.exports = {
    entry:"./modules/main.js",
    output:{
        filename:"./js/bundle.js"
    }
}
  1. 在项目目录下创建HTML页面,如index.html,导入webpack打包后的JS文件
    <!doctype html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>狂神说Java</title>
        </head>
        <body>
            <script src="dist/js/bundle.js"></script>
        </body>
    </html>

执行、报错

  1. 在IDEA控制台中直接执行webpack;如果失败的话,就使用管理员权限运行即可!webpack.config.js

  2. The ‘mode’ option has not been set, webpack will fallback to ‘production’ for this value.
    Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for each environment.
    You can also set it to ‘none’ to disable any default behavior. Learn more: https://webpack.js/configuration/mode/

    添加   mode: 'none',
    
  3. 运行HTML看效果

# 参数--watch 用于监听变化
webpack --watch

十一、vue-router路由

学习的时候,尽量的打开官方的文档

Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成, 让构建单页面应用变得易如反掌。包含的功能有:

嵌套的路由/视图表
模块化的、基于组件的路由配置
路由参数、查询、通配符
基于Vue js过渡系统的视图过渡效果
细粒度的导航控制
带有自动激活的CSS class的链接
HTML5 历史模式或hash模式, 在IE 9中自动降级
自定义的滚动行为

11.2、安装

基于第一个vue-cli进行测试学习; 先查看node modules中是否存在vue-router
  vue-router是一个插件包, 所以我们还是需要用n pm/cn pm来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令。

npm install vue-router --save-dev	--save-dev保存到当前文件

如果在一个模块化工程中使用它,必须要通过Vue.use()明确地安装路由功能:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter);

11.3、测试

1、先删除没有用的东西
2、components 目录下存放我们自己编写的组件
3、定义一个Content.vue 的组件

<template>
    <div>
        <h1>内容页</h1>
    </div>
</template>

<script>
    export default {
        name:"Content"
    }
</script>

Main.vue组件

    <template>
    <div>
        <h1>首页</h1>
    </div>
</template>

<script>
    export default {
        name:"Main"
    }
</script>

4、安装路由,在src目录下,新建一个文件夹:router,专门存放路由,配置路由index.js,如下

import Vue from'vue'
//导入路由插件
import Router from 'vue-router'
//导入上面定义的组件
import Content from '../components/Content'
import Main from '../components/Main'
//安装路由
Vue.use(Router) ;
//配置路由
export default new Router({
    routes:[
        {
            //路由路径
            path:'/content',
            //路由名称
            name:'content',
            //跳转到组件
            component:Content
            },{
            //路由路径
            path:'/main',
            //路由名称
            name:'main',
            //跳转到组件
            component:Main
            }
        ]
    });

5、在main.js中配置路由

import Vue from 'vue'
import App from './App'

//导入上面创建的路由配置目录
import router from './router'//自动扫描里面的路由配置

//来关闭生产模式下给出的提示
Vue.config.productionTip = false;

new Vue({
    el:"#app",
    //配置路由
    router,
    components:{App},
    template:'<App/>'
});

6、在App.vue中使用路由

<template>
    <div id="app">
        <!--
            router-link:默认会被渲染成一个<a>标签,to属性为指定链接
            router-view:用于渲染路由匹配到的组件
        -->
        <router-link to="/">首页</router-link>
        <router-link to="/content">内容</router-link>
        <router-view></router-view>
    </div>
</template>

<script>
    export default{
        name:'App'
    }
</script>
<style></style>

十二、实战快速上手

我们采用实战教学模式并结合ElementUI组件库,将所需知识点应用到实际中,以最快速度带领大家掌握Vue的使用;

12.1、创建工程

注意:命令行都要使用管理员模式运行
1、创建一个名为hello-vue的工程vue init webpack hello-vue
2、安装依赖, 我们需要安装vue-router、element-ui、sass-loader和node-sass四个插件

#进入工程目录
cd hello-vue
#安装vue-routern 
npm install vue-router --save-dev
#安装element-ui
npm i element-ui -S
#安装依赖
npm install

# 安装SASS加载器(两个文件)//sass-loader依赖于node-sass  

cnpm install sass-loader node-sass --save-dev

#启功测试
npm run dev

3、Npm命令解释:

npm install moduleName:安装模块到项目目录下
npm install -g moduleName:-g的意思是将模块安装到全局,具体安装到磁盘哪个位置要看npm config prefix的位置
npm install -save moduleName:–save的意思是将模块安装到项目目录下, 并在package文件的dependencies节点写入依赖,-S为该命令的缩写
npm install -save-dev moduleName:–save-dev的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖,-D为该命令的缩写

12.2、创建登录页面

把没有用的初始化东西删掉!
  在源码目录中创建如下结构:

    • assets:用于存放资源文件
    • components:用于存放Vue功能组件
    • views:用于存放Vue视图组件
    • router:用于存放vue-router配置

  1. v-on:click=onSubmit(loginForm),不要动,不要修改,与el-form ref=loginForm 两个保持一致;

  2. methods中添加handleClose: function () { console.log(Handle Close,空函数); };

  3. 登陆FORM外嵌套el-card class=box-card/ek-card,样式表这一句就行style scoped.box-card {width: 480px;margin: auto;}/style;

  4. 因为样式出错,可以改node-sass版本为4.14.1
    错误描述:
    ERROR Failed to compile with 1 errors
    error in ./src/views/Login.vue
    Module build failed: Error: Node Sass version 5.0.0 is incompatible with ^4.0.0.
    【错误:节点Sass版本5.0.0与^4.0.0不兼容。】

    错误分析:
    node-sass版本不兼容【当前版本过高/过低】

    错误解决:

    1. 卸载当前node-sass版本
      npm uninstall node-sass
    2. 安装适合版本【个人推荐4.14.1版本】
      npm install node-sass@版本号

创建首页视图,在views目录下创建一个名为Main.vue的视图组件:

<template>
    <div>首页</div>
</template>
<script>
    export default {
            name:"Main"
    }
</script>
<style scoped>
</style>

创建登录页视图在views目录下创建名为Login.vue的视图组件,其中el-*的元素为ElementUI组件;

<template>
  <div>
    <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
      <h3 class="login-title">欢迎登录</h3>
      <el-form-item label="账号" prop="username">
        <el-input type="text" placeholder="请输入账号" v-model="form.username"/>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" placeholder="请输入密码" v-model="form.password"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" v-on:click="onsubmit('loginForm')">登录</el-button>
      </el-form-item>
    </el-form>

    <el-dialog title="温馨提示" :visible.sync="dialogVisiable" width="30%" :before-close="handleClose">
      <span>请输入账号和密码</span>
      <span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="dialogVisible = false">确定</el-button>
        </span>
    </el-dialog>
  </div>
</template>

<script>
    export default {
        name: "Login",
      data(){
          return{
            form:{
              username:'',
              password:''
            },
            //表单验证,需要在 el-form-item 元素中增加prop属性
            rules:{
              username:[
                {required:true,message:"账号不可为空",trigger:"blur"}
              ],
              password:[
                {required:true,message:"密码不可为空",tigger:"blur"}
              ]
            },

            //对话框显示和隐藏
            dialogVisible:false
          }
      },
      methods:{
          onSubmit(formName){
            //为表单绑定验证功能
            this.$refs[formName].validate((valid)=>{
              if(valid){
                //使用vue-router路由到指定界面,该方式称为编程式导航
                this.$router.push('/main');
              }else{
                this.dialogVisible=true;
                return false;
              }
            });
          }
      }
    }
</script>

<style lang="scss" scoped>
  .login-box{
    border:1px solid #DCDFE6;
    width: 350px;
    margin:180px auto;
    padding: 35px 35px 15px 35px;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    box-shadow: 0 0 25px #909399;
  }
  .login-title{
    text-align:center;
    margin: 0 auto 40px auto;
    color: #303133;
  }
</style>

创建路由,在router目录下创建一个名为index.js的vue-router路由配置文件

//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Main from "../views/Main";
import Login from "../views/Login";
//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
  routes: [
    {
      //登录页
      path: '/main',
      component: Main
    },
    //首页
    {
      path: '/login',
      component: Login
    },
  ]

})

APP.vue

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>


export default {
  name: 'App',

}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from "./router"

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(router)
Vue.use(ElementUI)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  render:h=>h(App)
})

测试:在浏览器打开 http://localhost:8080/#/login
如果出现错误: 可能是因为sass-loader的版本过高导致的编译错误,当前最高版本是8.0.2,需要退回到7.3.1 ;
去package.json文件里面的 "sass-loader"的版本更换成7.3.1,然后重新cnpm install就可以了;

12.3、路由嵌套

嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。
demo
1、 创建用户信息组件,在 views/user 目录下创建一个名为 Profile.vue 的视图组件;
Profile.vue

<template>
  <h1>个人信息</h1>
</template>
<script>
  export default {
    name: "UserProfile"
  }
</script>
<style scoped>
</style>

2、在用户列表组件在 views/user 目录下创建一个名为 List.vue 的视图组件;
List.vue

<template>
  <h1>用户列表</h1>
</template>
<script>
  export default {
    name: "UserList"
  }
</script>
<style scoped>
</style>

3、 修改首页视图,我们修改 Main.vue 视图组件,此处使用了 ElementUI 布局容器组件,代码如下:
Main.vue

<template>
    <div>
      <el-container>
        <el-aside width="200px">
          <el-menu :default-openeds="['1']">
            <el-submenu index="1">
              <template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
              <el-menu-item-group>
                <el-menu-item index="1-1">
                <!--插入的地方-->
                  <router-link to="/user/profile">个人信息</router-link>
                </el-menu-item>
                <el-menu-item index="1-2">
                <!--插入的地方-->
                  <router-link to="/user/list">用户列表</router-link>
                </el-menu-item>
              </el-menu-item-group>
            </el-submenu>
            <el-submenu index="2">
              <template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
              <el-menu-item-group>
                <el-menu-item index="2-1">分类管理</el-menu-item>
                <el-menu-item index="2-2">内容列表</el-menu-item>
              </el-menu-item-group>
            </el-submenu>
          </el-menu>
        </el-aside>

        <el-container>
          <el-header style="text-align: right; font-size: 12px">
            <el-dropdown>
              <i class="el-icon-setting" style="margin-right: 15px"></i>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item>个人信息</el-dropdown-item>
                <el-dropdown-item>退出登录</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </el-header>
          <el-main>
          <!--在这里展示视图-->
            <router-view />
          </el-main>
        </el-container>
      </el-container>
    </div>
</template>
<script>
    export default {
        name: "Main"
    }
</script>
<style scoped lang="scss">
  .el-header {
    background-color: #B3C0D1;
    color: #333;
    line-height: 60px;
  }
  .el-aside {
    color: #333;
  }
</style>

4、 配置嵌套路由修改 router 目录下的 index.js 路由配置文件,使用children放入main中写入子模块,代码如下
index.js

//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Main from "../views/Main";
import Login from "../views/Login";
//导入子模块
import UserList from "../views/user/List";
import UserProfile from "../views/user/Profile";

//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
  routes: [
    {
      //登录页
      path: '/main',
      component: Main,
      //  写入子模块
      children: [
        {
          path: '/user/profile',
          component: UserProfile,
        }, {
          path: '/user/list',
          component: UserList,
        },
      ]
    },
    //首页
    {
      path: '/login',
      component: Login

    },
  ]
})

5、 路由嵌套实战效果图

图 路由嵌套效果图

12.4、参数传递

这里演示如果请求带有参数该怎么传递
demo
 用的还是上述例子的代码 修改一些代码 这里不放重复的代码了
第一种取值方式
1、 修改路由配置, 主要是router下的index.js中的 path 属性中增加了 :id 这样的占位符

{
    path: '/user/profile/:id', 
    name:'UserProfile', 
    component: UserProfile
}

2、传递参数
 此时我们在Main.vue中的route-link位置处 to 改为了 :to,是为了将这一属性当成对象使用,注意 router-link 中的 name 属性名称 一定要和 路由中的 name 属性名称 匹配,因为这样 Vue 才能找到对应的路由路径;

<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>

3、在要展示的组件Profile.vue中接收参数 使用 {{$route.params.id}}来接收
Profile.vue 部分代码

<template>
  <!--  所有的元素必须在根节点下-->
  <div>
    <h1>个人信息</h1>
    {{$route.params.id}}
  </div>
</template>

第二种取值方式 使用props 减少耦合
1、修改路由配置 , 主要在router下的index.js中的路由属性中增加了 props: true 属性

{
    path: '/user/profile/:id', 
    name:'UserProfile', 
    component: UserProfile, 
    props: true
}

2、传递参数和之前一样 在Main.vue中修改route-link地址

<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>

3、在Profile.vue接收参数为目标组件增加 props 属性
Profile.vue

<template>
  <div>
    个人信息
    {{ id }}
  </div>
</template>
<script>
    export default {
      props: ['id'],
      name: "UserProfile"
    }
</script>
<style scoped>
</style>

12.5、组件重定向

重定向的意思大家都明白,但 Vue 中的重定向是作用在路径不同但组件相同的情况下,比如:
在router下面index.js的配置

{
  path: '/main',
  name: 'Main',
  component: Main
},
{
  path: '/goHome',
  redirect: '/main'
}

说明:这里定义了两个路径,一个是 /main ,一个是 /goHome,其中 /goHome 重定向到了 /main 路径,由此可以看出重定向不需要定义组件;

使用的话,只需要在Main.vue设置对应路径即可;

<el-menu-item index="1-3">
    <router-link to="/goHome">回到首页</router-link>
</el-menu-item>

12.6、路由模式与 404

路由模式有两种

  • hash:路径带 # 符号,如 http://localhost/#/login
  • history:路径不带 # 符号,如 http://localhost/login

修改路由配置,代码如下:

export default new Router({
  mode: 'history',
  routes: [
  ]
});

404 demo
1.创建一个NotFound.vue视图组件
NotFound.vue

<template>
    <div>
      <h1>404,你的页面走丢了</h1>
    </div>
</template>
<script>
    export default {
        name: "NotFound"
    }
</script>
<style scoped>
</style>

2.修改路由配置index.js

import NotFound from '../views/NotFound'
{
   path: '*',
   component: NotFound
}

3.效果图

图 404效果图

路由钩子与异步请求

beforeRouteEnter:在进入路由前执行
beforeRouteLeave:在离开路由前执行

在Profile.vue中写

  export default {
    name: "UserProfile",
    beforeRouteEnter: (to, from, next) => {
      console.log("准备进入个人信息页");
      next();
    },
    beforeRouteLeave: (to, from, next) => {
      console.log("准备离开个人信息页");
      next();
    }
  }

参数说明:
to:路由将要跳转的路径信息
from:路径跳转前的路径信息
next:路由的控制参数
next() 跳入下一个页面
next(’/path’) 改变路由的跳转方向,使其跳到另一个路由
next(false) 返回原来的页面
next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例

在钩子函数中使用异步请求

1、安装 Axios

cnpm install --save vue-axios

2、main.js引用 Axios

import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)

3、准备数据 : 只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下。
数据和之前用的json数据一样 需要的去上述axios例子里

// 静态数据存放的位置
static/mock/data.json
4.在 beforeRouteEnter 中进行异步请求
Profile.vue
  export default {
    //第二种取值方式
    // props:['id'],
    name: "UserProfile",
    //钩子函数 过滤器
    beforeRouteEnter: (to, from, next) => {
      //加载数据
      console.log("进入路由之前")
      next(vm => {
        //进入路由之前执行getData方法
        vm.getData()
      });
    },
    beforeRouteLeave: (to, from, next) => {
      console.log("离开路由之前")
      next();
    },
    //axios
    methods: {
      getData: function () {
        this.axios({
          method: 'get',
          url: 'http://localhost:8080/static/mock/data.json'
        }).then(function (response) {
          console.log(response)
        })
      }
    }
  }

5.路由钩子和axios结合图

名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定–>
个人信息


3、在Profile.vue接收参数为目标组件增加 props 属性
Profile.vue



个人信息 {{ id }} ```

[外链图片转存中…(img-2kF9Arl6-1629387969210)]

12.5、组件重定向

重定向的意思大家都明白,但 Vue 中的重定向是作用在路径不同但组件相同的情况下,比如:
在router下面index.js的配置

{
  path: '/main',
  name: 'Main',
  component: Main
},
{
  path: '/goHome',
  redirect: '/main'
}

说明:这里定义了两个路径,一个是 /main ,一个是 /goHome,其中 /goHome 重定向到了 /main 路径,由此可以看出重定向不需要定义组件;

使用的话,只需要在Main.vue设置对应路径即可;

<el-menu-item index="1-3">
    <router-link to="/goHome">回到首页</router-link>
</el-menu-item>

12.6、路由模式与 404

路由模式有两种

  • hash:路径带 # 符号,如 http://localhost/#/login
  • history:路径不带 # 符号,如 http://localhost/login

修改路由配置,代码如下:

export default new Router({
  mode: 'history',
  routes: [
  ]
});

404 demo
1.创建一个NotFound.vue视图组件
NotFound.vue

<template>
    <div>
      <h1>404,你的页面走丢了</h1>
    </div>
</template>
<script>
    export default {
        name: "NotFound"
    }
</script>
<style scoped>
</style>

2.修改路由配置index.js

import NotFound from '../views/NotFound'
{
   path: '*',
   component: NotFound
}

3.效果图

[外链图片转存中…(img-Uffw1sL7-1629387969212)]

图 404效果图

路由钩子与异步请求

beforeRouteEnter:在进入路由前执行
beforeRouteLeave:在离开路由前执行

在Profile.vue中写

  export default {
    name: "UserProfile",
    beforeRouteEnter: (to, from, next) => {
      console.log("准备进入个人信息页");
      next();
    },
    beforeRouteLeave: (to, from, next) => {
      console.log("准备离开个人信息页");
      next();
    }
  }

参数说明:
to:路由将要跳转的路径信息
from:路径跳转前的路径信息
next:路由的控制参数
next() 跳入下一个页面
next(’/path’) 改变路由的跳转方向,使其跳到另一个路由
next(false) 返回原来的页面
next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例

在钩子函数中使用异步请求

1、安装 Axios

cnpm install --save vue-axios

2、main.js引用 Axios

import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)

3、准备数据 : 只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下。
数据和之前用的json数据一样 需要的去上述axios例子里

// 静态数据存放的位置
static/mock/data.json
4.在 beforeRouteEnter 中进行异步请求
Profile.vue
  export default {
    //第二种取值方式
    // props:['id'],
    name: "UserProfile",
    //钩子函数 过滤器
    beforeRouteEnter: (to, from, next) => {
      //加载数据
      console.log("进入路由之前")
      next(vm => {
        //进入路由之前执行getData方法
        vm.getData()
      });
    },
    beforeRouteLeave: (to, from, next) => {
      console.log("离开路由之前")
      next();
    },
    //axios
    methods: {
      getData: function () {
        this.axios({
          method: 'get',
          url: 'http://localhost:8080/static/mock/data.json'
        }).then(function (response) {
          console.log(response)
        })
      }
    }
  }

5.路由钩子和axios结合图

更多推荐

Vue~~