Vue 是一套用于构建用户界面的渐进式框架,发布于2014年2月。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库(如: vue-router: 跳转,vue-resource: 通信,vuex: 管理)或既有项目整合。
官网: https://cn.vuejs.org/v2/guide/
略
Element是饿了么前端开源维护的Vue UI组件库,组件齐全,基本涵盖后台所需的所有组件,文档讲解详细,例子也很丰富。主要用于开发PC端的页面,是一个质量比较高的Vue UI组件库。
官网地址
Github
vue-element- admin
备注:属于前端主流框架,选型时可考虑使用,主要特点是桌面端支持较多
等…
为了降低开发的复杂度,以后端为出发点,比如: Struts、 SpringMVC 等框架的使用,就是后端的MVC时代;
以SpringMVC流程为例:
前端开发重度依赖开发环境,开发效率低,这种架构下,前后端协作有两种模式:
前后端职责纠缠不清:模板引擎功能强大,依旧可以通过拿到的上下文变量来实现各种业务逻辑。这样,只要前端弱势一点, 往往就会被后端要求在模板层写出不少业务代码。还有一个很大的灰色地带是Controller ,页面路由等功能本应该是前端最关注的,但却是由后端来实现。Controller本身与Model 往往也会纠缠不清,看了让人咬牙的业务代码经常会出现在Controller层。这些问题不能全归结于程序员的素养,否则JSP就够了。
对前端发挥的局限性:性能优化如果只在前端做空间非常有限,于是我们经常需要后端合作,但由于后端框架限制,我们很难使用[Comet] 、[BigPipe] 等技术方案来优化性能。
注:在这期间(2005年以前),包括早期的JSP、 PHP可以称之为Web 1.0时代。在这里想说一句,如果你是-名Java初学者,请你不要再把一些陈旧的技术当回事了,比如JSP,因为时代在变、技术在变、什么都在变(引用扎克伯格的一句话:唯一不变的是变化本身) ;当我们去给大学做实训时,有些同学会认为我们没有讲什么干货,其实不然,只能说是你认知里的干货对于市场来说早就过时了而已。
此处的MV*模式如下:
为了降低前端开发复杂度,涌现了大量的前端框架,比如: AngularJs、 React、 Vue.js 、EmberJs等,这些框架总的原则是先按类型分层,比如Templates、Controllers. Models, 然后再在层内做切分,如下图:
在这种研发模式下,前后端的职责很清晰。对前端来说,两个UI层各司其职:
Front-end Urlayer处理浏览器层的展现逻辑。通过CSS渲染样式,通过JavaScript 添加交互功能,HTML的生成也可以放在这层,具体看应用场景。
Back-end UI layer处理路由、模板、数据获取、Cookie等。通过路由,前端终于可以自主把控URL Design,这样无论是单页面应用还是多页面应用,前端都可以自由调控。后端也终于可以摆脱对展现的强关注,转而可以专心于业务逻辑层的开发。
通过Node, Web Server层也是JavaScript代码,这意味着部分代码可前后复用,需要SEO .的场景可以在服务端同步渲染,由于异步请求太多导致的性能问题也可以通过服务端来缓解。前一种模式的不足,通过这种模式几乎都能完美解决掉。
与JSP模式相比,全栈模式看起来是一种回归,也的确是-种向原始开发模式的回归,不过是一种螺旋上升式的回归。
基于NodeJS的全栈模式,依旧面临很多挑战:
MVVM (Model-View-ViewModel) 是一种软件架构设计模式,由微软WPF (用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight (类似于Java Applet,简单点说就是在浏览器上运行的WPF)的架构师Ken Cooper和Ted Peters开发,是一种简化用户界面的事件驱动编程方式。由John Gossman (同样也是WPF和Silverlight的架构师)于2005年在他的博客上发表。
MVVM源自于经典的MVC (Model-View-Controller) 模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用,其作用如下:
ViewModel是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的Model数据进行转换处理,做二次封装,以生成符合View层使用预期的视图数据模型。
需要注意的是ViewModel所封装出来的数据模型包括视图的状态和行为两部分,而Model层的数据模型是只包含状态的:
视图状态和行为都封装在了ViewModel里。这样的封装使得ViewModel可以完整地去描述View层。由于实现了双向绑定,ViewModel 的内容会实时展现在View层,这是激动人心的,因为前端开发者再也不必低效又麻烦地通过操纵DOM去更新视图。
MVVM框架已经把最脏最累的一块做好了,我们开发者只需要处理和维护ViewModel,更新数据视图就会自动得到相应更新,真正实现事件驱动编程。
View层展现的不是Model 层的数据,而是ViewModel 的数据,由ViewModel 负责与Model层交互这就完全解糊了View层和Model层,这个解耦是至关重要的,它是前后端分离方案实施的里要一坏。
Vue 是一套用于构建用户界面的渐进式框架,发布于2014年2月。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库(如: vue-router: 跳转,vue-resource: 通信,vuex: 管理)或既有项目整合。
开发版本
CDN
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
Vue.js的核心是实现了MVVM模式,她扮演的角色就是ViewModel层,那么所谓的第一个应用程序就是展示她的 数据绑定功能,操作流程如下: (demo1.html)
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo1title>
head>
<body>
<div id="app">
<h1>{{message}}h1>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script>
var vm = new Vue({
el:"#app",
//Model:数据
data:{
message:"hello vue!"
}
});
script>
body>
html>
说明:
测试:为了能够更直观的体验Vue带来的数据绑定功能,我们需要在浏览器测试一番, 操作流程如下:
我们已经成功创建了第一个Vue应用!看起来这跟渲染一个字 符串模板非常类似,但是Vue在背后做了大量工作。现在数据和DOM已经被建立了关联,所有东西都是响应式的。我们在控制台操作对象属性,界面可以实时更新!
我们还可以使用v-bind来绑定元素特性!
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>demo1title>
head>
<body>
<div id="app">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息
span>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script>
var vm = new Vue({
el:"#app",
//Model:数据
data:{
message:"hello vue!"
}
});
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo2title>
head>
<body>
<div id="app">
<h1 v-if="type=='A'"> A h1>
<h1 v-else-if="type=='B'"> B h1>
<h1 v-else-if="type=='C'"> C h1>
<h1 v-else> D h1>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script>
var vm = new Vue({
el:"#app",
//Model:数据
data:{
type:"A"
}
});
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo3title>
head>
<body>
<div id="app">
<li v-for="(item,index) in items">
{{item.message}} -- {{index}}
li>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script>
var vm = new Vue({
el:"#app",
data:{
items:[
{ message: "前端" },
{ message: "后台" },
{ message: "运维" }
]
}
});
script>
body>
html>
v-on
指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>demo4title>
head>
<body>
<div id="app">
<button v-on:click="sayHi">Click Mebutton>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "hello"
},
methods: {
sayHi: function (event) { //方法定义必须在 Vue的methods对象中,注意参数 event
alert(this.message);
}
}
});
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo5title>
head>
<body>
<div id="app">
输入文本:<input type="text" v-model="message"/>{{message}}
<br/>
性别:
<input type="radio" name="sex" value="男" v-model="name"/> 男
<input type="radio" name="sex" value="女" v-model="name"/> 女
<p>
选中了谁:{{name}}
p>
<br/>
下拉框:
<select v-model="selected">
<option value="" disabled>---请选择---option>
<option>Aoption>
<option>Boption>
<option>Coption>
select>
<span> value:{{selected}}span>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "hello",
name: "",
selected: ""
}
});
script>
body>
html>
在html中< div>、< p> 这些是标签, Vue组件的作用就是自己定义一个标签
组件是可复用的Vue实例,说白了就是一组可以重复使用的模板,跟JSTL的自定义标签、Thymeleaf的th:fragment 等框架有着异曲同工之妙。通常一个应用会以一棵嵌套的组件树的形式来组织:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo6title>
head>
<body>
<div id="app">
<my-li>my-li>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script>
//定义一个Vue组件
Vue.component("my-li",{
template: ' hello '
});
var vm = new Vue({
el: "#app",
});
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo6title>
head>
<body>
<div id="app">
<my-li v-for="item in items" v-bind:get="item">my-li>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script>
//定义一个Vue组件
Vue.component("my-li",{
props:['get'],
template: '{{get}} '
});
var vm = new Vue({
el: "#app",
data:{
items: ["java","linux","js"]
}
});
script>
body>
html>
{
"name": "狂神说Java",
"url": "https://www.baidu.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/"
}
]
}
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>demo7title>
<style>
[v-clock]{
display: none;
}
style>
head>
<body>
<div id="vue" v-clock>
<div>{{info.name}}div>
<div>{{info.address.city}}div>
<a v-bind:href="info.url">点我a>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script src="https://unpkg.com/axios/dist/axios.min.js">script>
<script >
var vm = new Vue({
el:"#vue",
//之前写的data:属性:是vm里面的属性
//下面这个data是方法,return 返回的是钩子函数里面的response.data
data(){
return{
//请求返回的参数格式,必须和json字符串一样(下面写的内容,也仅仅是为例表示格式)
info:{
name: null,
address: {
street: null,
city: null,
country: null
},
url: null
}
}
},
mounted(){//钩子函数
axios.get('../data.json').then(response=>(this.info=response.data));
}
});
script>
body>
html>
Ajax
响应回来的数据格式匹配!计算属性的重点突出在属性
两个字上(属性是名词),首先它是个属性
其次这个属性有计算
的能力(计算是动词),这里的计算
就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存!
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo8title>
head>
<body>
<div id="app">
<p>currentTime1 {{currentTime1()}}p>
<p>currentTime2 {{currentTime2}}p>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script>
var vm = new Vue({
el:"#app",
data:{
message:"hello,java"
},
methods:{
currentTime1:function () {
return Date.now();
}
},
computed:{
currentTime2:function(){//计算属性:methods,computed方法名不能重名,重名之后,只会调用methods的方法
this.message;
return Date.now();//返回一个时间戳
}
}
});
script>
body>
html>
methods:定义方法, 调用方法使用currentTime1(), 需要带括号
computed:定义计算属性, 调用属性使用currentTime2, 不需要带括号:this.message是为了能够让currentTime2观察到数据变化而变化
如何在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用vm.message="qqqqqq"
, 改变下数据的值,再次测试观察效果!
结论:
调用方法时,每次都需要讲行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;
等后续再说