赞
踩
Q:实际项目中实行SoC原则,何为SoC原则?
A:SoC原则:把功能分离为单独功能点,每个功能点有唯一的行为和数据,每个功能点均能被其他需要的类使用。SoC原则最大限度实现代码重用、功能重用、模块重用。
而Vue 的核心库只关注视图层( 即HTML + CSS + JS:给用户看,刷新后台给的数据),方便与第三方库或既有项目整合。例如整合以下既有项目:
注:以上知识点已将WebApp开发所需技能全部梳理完毕
云打包:HBuild -> HBuildX,DCloud 出品;API Cloud
本地打包: Cordova(前身是 PhoneGap)
前端人员为了方便开发也需要掌握一定的后端技术但我们Java后台人员知道后台知识体系极其庞大复杂,所以为了方便前端人员开发后台应用,就出现了NodeJS这样的技术。
Node JS的作者已经声称放弃Node JS(说是架构做的不好再加上笨重的nodemodules),开始开发全新架构的De no
既然是后台技术,那肯定也需要框架和项目管理工具, Node JS框架及项目管理工具如下:
Vue.js
iView
iview是一个 强大的基于Vue的UI库, 有很多实用的基础组件比element ui的组件更丰富, 主要服务于PC界面的中后台产品。使用单文件的Vue组件化开发模式基于npm+webpack+babel开发, 支持ES 2015高质量、功能丰富友好的API, 自由灵活地使用空间。链接:官网地址
iview-admin
备注:属于前端主流框架,选型时可考虑使用,主要特点是移动端支持较多。
Element UI
Element是饿了么前端开源维护的Vue UI组件库, 组件齐全, 基本涵盖后台所需的所有组件,文档讲解详细, 例子也很丰富。主要用于开发PC端的页面, 是一个质量比较高的Vue UI组件库。链接: 官网地址
备注: 属于前端主流框架,选型时可考虑使用,主要特点是桌面端支持较多
ICE
飞冰是阿里巴巴团队基于React/Angular/Vue的中后台应用解决方案, 在阿里巴巴内部, 已经有270多个来自几乎所有BU的项目在使用。飞冰包含了一条从设计端到开发端的完整链路,帮助用户快速搭建属于自己的中后台应用。
备注: 主要组件还是以React为主, 截止2019年02月17日更新博客前对Vue的支持还不太完善,目前尚处于观望阶段
VantUI
Vant UI是有赞前端团队基于有赞统一的规范实现的Vue组件库, 提供了-整套UI基础组件和业务组件。通过Vant, 可以快速搭建出风格统一的页面,提升开发效率。
AtUI
at-ui是一款基于Vue 2.x的前端UI组件库, 主要用于快速开发PC网站产品。它提供了一套n pm+web pack+babel前端开发工作流程, CSS样式独立, 即使采用不同的框架实现都能保持统一的UI风格。
Cube Ul
cube-ui是滴滴团队开发的基于Vue js实现的精致移动端组件库。支持按需引入和后编译, 轻量灵活;扩展性强,可以方便地基于现有组件实现二次开发。
混合开发
Flutter
Flutter是谷歌的移动端UI框架, 可在极短的时间内构建Android和iOS上高质量的原生级应用。Flutter可与现有代码一起工作, 它被世界各地的开发者和组织使用, 并且Flutter是免费和开源的。
备注: Google出品, 主要特点是快速构建原生APP应用程序, 如做混合应用该框架为必选框架
lonic
lonic既是一个CSS框架也是一个Javascript UI库, lonic是目前最有潜力的一款HTML 5手机应用开发框架。通过SASS构建应用程序, 它提供了很多UI组件来帮助开发者开发强大的应用。它使用JavaScript MV VM框架和Angular JS/Vue来增强应用。提供数据的双向绑定, 使用它成为Web和移动开发者的共同选择。
微信小程序
mpvue
mpvue是美团开发的一个使用Vue.js开发小程序的前端框架, 目前支持微信小程序、百度智能小程序,头条小程序和支付宝小程序。框架基于Vue.js, 修改了的运行时框架runtime和代码编译器compiler实现, 使其可运行在小程序环境中, 从而为小程序开发引入了Vue.js开发体验。
备注: 完备的Vue开发体验, 井且支持多平台的小程序开发, 推荐使用
WeUI
WeUI是一套同微信原生视觉体验一致的基础样式库, 由微信官方设计团队为微信内网页和微信小程序量身设计, 令用户的使用感知更加统一。包含button、cell、dialog、toast、article、icon等各式元素。
为了降低开发的复杂度, 以后端为出发点, 比如: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域
- 前端控制器向用户响应结果
优点
缺点
- 第一种是前端写DEMO, 写好后, 让后端去套模板。好处是DEMO可以本地开发,很高效。不足是还需要后端套模板,有可能套错,套完后还需要前端确定,来回沟通调整的成本比较大;
- 另一种协作模式是前端负责浏览器端的所有开发和服务器端的View层模板开发。好处是UI相关的代码都是前端去写就好,后端不用太关注,不足就是前端开发重度绑定后端环境,环境成为影响前端开发效率的重要因素。
时间回到2005年A OAX(Asynchronous JavaScript And XML, 异步JavaScript和XML,老技术新用法)被正式提出并开始使用CDN作为静态资源存储, 于是出现了JavaScript王者归来(在这之前JS都是用来在网页上贴狗皮膏药广告的) 的SPA(Single Page Application) 单页面应用时代。
优点
缺点
此处的MV*模式如下:
- MVC(同步通信为主) :Model、View、Controller
- MVP(异步通信为主) :Model、View、Presenter
- MVVM(异步通信为主):Model、View、View Model为了降低前端开发复杂度,涌现了大量的前端框架,比如:Angular、JS、React、Vue.js、Ember JS等, 这些框架总的原则是先按类型分层,比如Templates、Controllers、Models, 然后再在层内做切分。
优点
缺点
前端为主的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等方式通信更高效。一切需要在验证中前行。
- 对部著、运维层面的熟练了解,需要更多知识点和实操经验。
- 大量历史遗留问题如何过渡。这可能是最大最大的阻力。
综上所述,前后分离的开发思想主要是基于Soc(关注度分离原则) , 上面种种模式,都是让前后端的职责更清晰,分工更合理高效。
MVVM(Model-View-ViewModel)是一种软件设计模式,由微软WPF(用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于JavaApplet,简单点说就是在浏览器上运行WPF)的架构师Ken Cooper和Te Peters开发,是一种简化用户界面的事件驱动编程方式。由JohnGossman(同样也是WPF和Sliverlight的架构师)与2005年在他的博客上发表。
MVVM源自于经典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。其作用如下:
当下流行的MVVM框架有Vue.js,Anfular JS。
MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处:
View
View是视图层, 也就是用户界面。前端主要由html和css来构建, 为了更方便地展现vi eu to del或者Hodel层的数据,已经产生了各种各样的前后端模板语言, 比如FreeMarker,Thyme leaf等等, 各大MV VM框架如Vue.js.AngularJS, EJS等也都有自己用来构建用户界面的内置模板语言。
Model
Model是指数据模型, 泛指后端进行的各种业务逻辑处理和数据操控, 主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则
ViewModel
ViewModel是由前端开发人员组织生成和维护的视图数据层。在这一层, 前端开发者对从后端获取的Model数据进行转换处理, 做二次封装, 以生成符合View层使用预期的视图数据模型。
注意:ViewModel所封装出来的数据模型包括视图的状态和行为两部分, 而Model层的数据模型是只包含状态的
比如页面的这一块展示什么,那一块展示什么这些都属于视图状态(展示)
页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互)
视图状态和行为都封装在了View Model里。这样的封装使得View Model可以完整地去描述View层。由于实现了双向绑定, View Model的内容会实时展现在View层,前端开发者再也不必低效又麻烦地通过操纵DOM去更新视图。
MVVM框架已经把最脏最累的一块做好了, 我们开发者只需要处理和维护View Model, 更新数据视图就会自动得到相应更新,真正实现事件驱动编程。
View层展现的不是Model层的数据, 而是ViewModel的数据, 由ViewModel负责与Model层交互,获取和更新数据, 这就完全解耦了View层和Model层, 这个解耦是至关重要的, 它是前后端分离方案实施的重要一环。
Vue是一套用于构建用户界面的渐进式框架, 发布于2014年2月。与其它大型框架不同的是, Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层, 不仅易于上手, 还便于与第三方库(如:vue-router,vue-resource,vue x) 或既有项目整合。
在MVVM架构中, 是不允许数据和视图直接通信的, 只能通过ViewModel来通信, 而ViewModel就是定义了一个Observer观察者
- ViewModel能够观察到数据的变化, 并对视图对应的内容进行更新。
- ViewModel能够监听到视图的变化, 并能够通知数据发生改变 。
总结: Vue.js就是一个MVVM的实现者, 其核心就是实现了DOM监听与数据绑定。
- 轻量级, 体积小是一个重要指标。Vue.js压缩后有只有20多kb(Angular压缩后56kb+,React压缩后44kb+)
- 移动优先。更适合移动端, 比如移动端的Touch事件
- 易上手,学习曲线平稳,文档齐全
- 吸取了Angular(模块化) 和React(虚拟DOM) 的长处, 并拥有自己独特的功能,如:计算属性
- 开源,社区活跃度高
Note:IDEA可以安装Vue的插件!
注意:Vue不支持IE 8及以下版本, 因为Vue使用了IE 8无法模拟的ECMAScript5特性。但它支持所有兼容ECMAScript 5的浏览器。
开发版本
CDN
<script src=“https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js”></script>
或
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
2.引入Vue.js(min版)
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
3.创建一个Vue实例对象
<script type="text/javascript">
var MyVue = new Vue({
/*需绑定的html元素的ID*/
el:"#app",
/*Model:数据*/
data:{
message:"hello,vue!"
}
});
</script>
- MyVue:该Vue实例的名
- el:“#ID”:需绑定的视图层(本例中为html)中元素的ID
- data:{message:‘Hello Vue!’}:数据对象中有一个名为message的属性,并设置了初始值为Hello Vue!。
注意:Vue实例对象中是以,
标志某属性的结束。
<!--view层,模板-->
<div id="app">
{{message}}
</div>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> {{message}} </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script type="text/javascript"> var MyVue = new Vue({ el:"#app", /*Model:数据*/ data:{ message:"hello,vue!" } }); </script> </body> </html>
v-bind用来绑定元素特性
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <span v-bind:title="message1"> 鼠标悬停几秒钟查看此处动态绑定的提示信息! </span> <span v-bind:title="message2"> 鼠标悬停几秒钟查看此处动态绑定的提示信息! </span> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script type="text/javascript"> var MyVue = new Vue({ el:"#app", /*Model:数据*/ data:{ message1:"页面1处加载于"+ new Date().toLocaleString(), message2:"页面2处加载于"+ new Date().toLocaleString() } }); </script> </body> </html>
如果再次打开浏览器的JavaScript控制台,
输入app,message=‘新消息’,就会再一次看到这个绑定了title特性的HTML已经进行了更新。
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--view层,模板--> <div id="app"> <h1 v-if="type">Yes</h1> <h1 v-else>No</h1> </div> <!--1.导入Vue.js--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script type="text/javascript"> var MyVue = new Vue({ el:"#app", /*Model:数据*/ data:{ type: false } }); </script> </body> </html>
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--view层,模板--> <div id="app"> <h1 v-if="x==='A'">A</h1> <h1 v-else-if="x==='B'">B</h1> <h1 v-else-if="x==='D'">D</h1> <h1 v-else>C</h1> </div> <!--1.导入Vue.js--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script type="text/javascript"> var MyVue = new Vue({ el:"#app", /*Model:数据*/ data:{ x: 'B' } }); </script> </body> </html>
注:===三个等号在JS中表示绝对等于(即两者数据与类型都要相等)
<div id="app">
<li v-for="(item,index) in items">
{{item.message}}---{{index}}
</li>
</div>
注:items是数组,item是数组元素迭代的别名,index是对应元素的下标。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--view层,模板--> <div id="app"> <!--迭代数组items--> <li v-for="(item,index) in items"> <!--打印出items的元素和对应的下标--> {{item.message}}---{{index}} </li> <!--迭代数组y--> <li v-for="(x,index) in y"> <!--打印出y的元素--> {{x.message}} </li> </div> <!--1.导入Vue.js--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script type="text/javascript"> var MyVue = new Vue({ el:"#app", /*Model:数据*/ data:{ //数组名为items items:[ {message:'Java'}, {message:'python'}, {message:'Vue'} ], //数组名为y y:[ {message:'View'}, {message:'ViewModel'}, {message:'Model'} ] } }); </script> </body> </html>
MyVue.items.push({message:'C++'})
,尝试追加一条数据,你会发现浏览器中显示的内容会增加一条记录C++---3
.v-on:监听事件
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <button v-on:click="sayHi">点我</button> </div> <script src="../js/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的事件、和前端页面本身的一些事件!我们这里的click是vue的事件, 可以绑定到Vue中的methods中的方法事件!
- 指令带有前缀v以表示它们是Vue提供的特殊特性。
- 这些指令会在渲染的DOM上应用特殊的响应式行为在这里。
Vue.js是一个MVVM框架, 满足数据双向绑定, 即当数据发生变化的时候, 视图也就发生变化, 当视图发生变化的时候,数据也会跟着同步变化。
注意:
我们所说的数据双向绑定,一定是对于UI控件来说的,非UI控件不会涉及到数据双向绑定。
单向数据绑定是使用状态管理工具的前提。如果我们使用vuex,那么数据流也是单项的,这时就会和双向数据绑定有冲突。
在Vue.js中,如果使用vuex, 实际上数据还是单向的,
之所以说是数据双向绑定,这是用的UI控件来说, 对于我们处理表单,Vue.js的双向数据绑定用起来就特别舒服了。
即两者并不互斥,在全局性数据流使用单项,方便跟踪;局部性数据流使用双向,简单易操作。
注意:v-model会忽略所有表单元素的value、checked、selected特性的初始值而总是将Vue实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值!
单行文本
<!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>
多行文本
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> 多行文本:<textarea v-model="pan"></textarea> 多行文本是:{{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>
单复选框
<!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"> <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>
多复选框
<!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"> <label for="jack">Jack</label> <input type="checkbox" id="join" value="Join" v-model="checkedNames"> <label for="join">Jack</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <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>
单选按钮
<!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>
下拉框
<!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事件。
因此,推荐像上面这样提供一个值为空的禁用选项。
组件是可复用的Vue实例, 即一组可以重复使用的模板, 跟JSTL的自定义标签、Thymeleal的th:fragment等框架有着异曲同工之妙,通常一个应用会以一棵嵌套的组件树的形式来组织:
注意:在实际开发中,我们并不会用以下方式开发组件,而是采用vue-cli创建,vue模板文件的方式开发,以下方法只是为了让大家理解什么是组件。
使用Vue.component()方法注册组件
<div id="app"> <!--引用组件pan--> <pan></pan> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script type="text/javascript"> //先注册组件pan Vue.component("pan",{ template:'<li>Hello</li>' }); //再实例化Vue var vm = new Vue({ el:"#app", }); </script>
Vue.component():注册组件
“pan”:自定义组件的名字
template:组件的模板
使用props属性传递参数
一般开发中需要传递参数到组件的,此时就需要使用props属性
注意:默认规则下props属性里的值不能为大写
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--组件:传递给组件中的值:props--> <pan v-for="item in items" v-bind:panh="item"></pan> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script type="text/javascript"> //定义组件 Vue.component("pan",{ props:['panh'], template:'<li>{{panh}}</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是一个开源的可以用在浏览器端和Node JS的异步通信框架, 她的主要作用就是实现AJAX异步通信,其功能特点如下:
- 从浏览器中创建XMLHttpRequests
- 从node.js创建http请求
- 支持Promise API[JS中链式编程]
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF(跨站请求伪造)
{ "name": "狂神说Java", "url": "https://blog.kuangstudy.com", "page": 1, "isNonProfit": true, "address": { "street": "含光门", "city": "陕西西安", "country": "中国" }, "links": [ { "name": "bilibili", "url": "https://space.bilibili.com/95256449" }, { "name": "狂神说Java", "url": "https://blog.kuangstudy.com" }, { "name": "百度", "url": "https://www.baidu.com/" } ] }
<!DOCTYPE html> <html lang="en" xmlns:v-binf="http://www.w3.org/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.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script type="text/javascript"> var vm = new Vue({ el:"#vue", //data:属性;而data():方法 data(){ return{ //请求返回的参数必须和json字符串一致 info:{ name:null, address:{ country:null, city:null, street:null }, url:null } } }, mounted(){//钩子函数,链式编程 /script> </body> </html> axios .get('../resources/data.json') .then(response=>(this.info=response.data));// response=>(对response内数据即response.data的操作) } }); </script> </body> </html>
- Vue实例有一个完整的生命周期,也就是从开始创建初始化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
- 在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册JS方法,可以让我们用自己注册的JS方法控制整个大局,在这些事件响应方法中的this直接指向的是Vue的实例。
计算属性的重点突出在属性两个字上(属性是名词),
它是个属性其次这个属性具有计算的能力(计算是动词),这里的计算就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存!
<!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.net/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观察到数据变化而变化。
若方法中的值发生了变化,则缓存就会刷新。
结论:
调用方法时,每次都需要讲行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销。
在Vue.js中我们使用元素作为承载分发内容的出口,作者称其为插槽,可以应用在组合组件的场景中。
测试:
Q:准备制作一个待办事项组件(todo) , 该组件由待办标题(todo-title) 和待办内容(todo-items)组成,但这三个组件又是相互独立的,该如何操作呢?
A:第一步、定义一个待办事项的组件。
<div id="app">
<todo></todo>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/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>
第二步、通过插槽使代办事项的标题和值实现动态绑定
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}}</li>"
});
var vm = new Vue({
el:"#vue",
data:{
todoItems:['test1','test2','test3']
}
});
<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> <!--view层,模板--> <div id="vue"> <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> <!--1.导入Vue.js--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script type="text/javascript"> 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}}</li>" }); var vm = new Vue({ el:"#vue", data:{ title:"秦老师系列课程", todoItems:['test1','test2','test3'] } }); </script> </body> </html>
- Q:数据项在Vue的实例中, 但删除操作要在组件中完成, 那么组件如何才能删除Vue实例中的数据呢?
- A:此时就涉及到参数传递与事件分发了,Vue为我们提供了自定义事件的功能很好的帮助我们解决了这个问题; 使用this.$emit(‘自定义事件名’, 参数) 。
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);
}
}
});
Vue.component("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);
}
}
});
<!--增加了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> <!--view层,模板--> <div id="vue"> <todo> <todo-title slot="todo-title" :title="title_text"></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_p="item" :index_p="index" v-on:remove="removeItems(index)" :key="index"></todo-items> </todo> </div> <!--1.导入Vue.js--> <script src="../js/vue.js"></script> <script type="text/javascript"> 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_p","index_p"], template:"<li>{{index_p+1}},{{item_p}} <button @click='remove_methods'>删除</button></li>", methods:{ remove_methods:function (index) { //this.$emit 自定义事件分发 this.$emit('remove',index); } } }); var vm = new Vue({ el:"#vue", data:{ title_text:"秦老师系列课程", todoItems:['test1','test2','test3'] }, methods:{ removeItems:function(index){ console.log("删除了"+this.todoItems[index]+"OK"); this.todoItems.splice(index,1); } } }); </script> </body> </html>
- 核心:数据驱动,组件化。
- 优点:借鉴了AngularJS的模块化开发和React的虚拟Dom,虚拟Dom就是把Demo操作放到内存中执行。
常用的属性:
- v-if
- v-else-if
- v-else
- v-for
- v-on绑定事件,简写@
- v-model数据双向绑定
- v-bind给组件绑定参数
组件化:
- 组合组件slot插槽
- 组件内部绑定事件需要使用到this.$emit(“事件名”,参数);
- 计算属性的特色,缓存计算数据
注意:
预先定义好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个估计项目就是脚手架,我们的开发更加的快速。
- 统一的目录结构
- 本地调试
- 热部署
- 单元测试
- 集成打包上线
安装Node.js:
- Node.js:http://nodejs.cn/download/
- Git:https://git-scm.com/doenloads
- 镜像:https://npm.taobao.org/mirrors/git-for-windows/
确认nodejs安装成功:
安装Node.js淘宝镜像加速器(cnpm):
# -g 就是全局安装
npm install cnpm -g
# 或使用如下语句解决npm速度慢的问题
npm install --registry=https://registry.npm.taobao.org
安装的位置:C:\Users\administrator\AppData\Roaming\npm
安装vue-cli
cnpm install vue-cli-g
#测试是否安装成功#查看可以基于哪些模板创建vue应用程序,通常我们选择webpack
vue list
D:\Project\vue-study;
#1、先需要进入到对应的目录 cd D:\Project\vue-study
#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 withNightwatch:单元测试相关,选择n不安装(后期需要再手动添加)
- Should we run npm install for youafter the,project has been created:创建完成后直接初始化,选择n,我们手动执行;运行结果!
cd myvue
npm install
npm run dev
执行完成后,目录多了很多依赖
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于Vue js过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的CSS class的链接
- HTML5 历史模式或hash模式, 在IE 9中自动降级
- 自定义的滚动行为
npm install vue-router --save-dev
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter);
<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>
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 } ] });
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/>' });
<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>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。