Web应用分类:
- 1.传统Web页面
- 2.单页应用
1.传统Web页面
1.H5(不等同于HTML5)
2.传统技术特点:
.单击某个链接,按钮或提交表单后,页面整体刷新
3.传统技术缺点:
- 1.每次页面整体刷新,都要导致浏览器重新加载对应的内容
- 2.加载内容繁多,传统页面的css/js多达上百个,每次打开页面都需要发送上百次请求,卡顿现象严重
2.单页应用(Single Page App,SPA)
- 1.整个应用只有一个主页面,其余的“页面”,实际上是一个个的“组件”
- 2.单页应用中的“页面跳转”,实际上是组件的切换,在这个过程中,只会更新局部资源,页面不会整个刷新(正是因为这个原因,当我们的前端代码有更改,重新部署之后,如果用户不主动刷新,就会发现有“资源缓存”)
1.单页应用特点
- 1.页面是局部刷新的,响应速度快,不需要每次加载所有的资源
- 2.前后端分离,前端不受后端的限制
2.单页应用框架
1.Angular
1.特点
- 1.业内第一个SPA框架
- 2.实现了前端的MVC解耦
- 3.双向绑定,Model层的数据变化会直接影响View,反之亦然
2.缺点
不易学习,文档差
2.React
1.特点
- 1.使用js一种语言就可以写前端(H5)+后端
- 2.React Native可以直接运行在手机端,性能接近原生APP
- 3.可使用组件多
2.缺点
- 1.html代码需要写在js文件中,前后端代码写在一起的风格
- 2.多语言混合式编程,代码难以理解,开发和调试
3.Vue
1.特点
- 1.基于MVVM(Model-View-ModelView)的SPA框架
- View:视图
- Model:数据
- ModelView:连接View与Model的纽带
- 2.Vue.js和微信小程序,阿里巴巴的Weex相似
3.Ajax和XML
1.概述
- 1.Ajax(Asynchronous JavaScript And XML):异步js与XML
- 2.Ajax名称本意是:异步js与XML,但是现在服务器端返回的数据几乎都使用JSON,而抛弃了XML
- 3.Ajax每次打开新的网页时,页面不会整体刷新,而是由js发起一个HTTP异步请求
2.特点
- 1.节省页面加载时间
- 2.节省了带宽
- 3.减轻客户端和服务器端的负担
Vue
Vue (读音类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架
- 1.构建用户界面:将数据通过某种方式展示到前端页面
- 2.渐进式:Vue可以自底向上逐层的应用,由浅入深,由简单到复杂(即:如果简单应用只需要引入一个轻量小巧的核心库,复杂应用可以根据需要引入各式各样的Vue插件,从一个轻量小巧的核心库逐渐递进到各式各样的Vue插件库)
简介
- 1.尤雨溪开发的一款轻量级框架
- 2.2015年正式发布Vue1.0.0
- 3.2016年正式发布Vue2.0.0
- 4.2020年正式发布Vue3.0.0
特点
- 1.采用组件化模式,提高代码复用率,且让代码更好维护
- 2.声明式编码,无需直接操作DOM,提高开发效率
//命令式编码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>原生JavaScript</title> </head> <body> <ul id="list"></ul> <script type="text/javascript"> // 需要展示的数据 let persons = [ { id: '001',name: '张三', age: 18}, { id: '002',name: '李四', age: 19}, { id: '003',name: '王五', age: 20}, ] //准备html字符串 let htmlStr = '' //遍历数据拼接html字符串 persons.forEach( p => { htmlStr += `${ p.id} - ${ p.name} - ${ p.age}`
}
)
//获取list元素
let list
= document
.
getElementById
(
‘list’
)
//操作DOM修改内容 list
.innerHTML
= htmlStr
<
/script
>
<
/body
>
<
/html
>// 声明式编码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> </head> <body> <div id="app"> <ul id="list"> <li v-for="p in persons"> { { p.id}} - { { p.name}} - { { p.age}} </li> </ul> </div> <script> new Vue({ el: "#app", // data: function(){ // return { // persons : [ // {id: '001',name: '张三', age: 18}, // {id: '002',name: '李四', age: 19}, // {id: '003',name: '王五', age: 20}, // ] // } // } data: { persons : [ { id: '001',name: '张三', age: 18}, { id: '002',name: '李四', age: 19}, { id: '003',name: '王五', age: 20}, ] } }) </script> </body> </html>
![]()
3.使用虚拟DOM+Diff算法,尽可能复用DOM节点
说明:
- 通过Diff算法比较,新数据和旧数据的区别,相同的复用,不同的修改
4.体积小:压缩后33k 5.双向数据绑定
扩展1:Diff算法
- 概念:
Diff算法是一种优化手段,将前后两个模块进行差异化对比,修补(更新)差异的过程叫做patch (打补丁)- 意义:
vue,react框架中都有diff算法
因为操作真实dom的开销很大, 某些时候修改了页面中的某个数据,如果直接渲染到真实DOM中会引起整棵树的重绘,只让我们改变过的数据映射到真实 DOM,做最少的重绘,这就是diff算法要解决的事情- virtual DOM和真实DOM的区别:
virtual DOM是将真实的 DOM 的数据抽取出来,以对象的形式模拟树形结构,diff算法比较的也是virtual DOM 代码理解
1.原生Vue
独立的Vue框架,不与Webpack等框架结合使用
1.安装与部署
1安装方式
1.直接通过
标签引入
- 1.通过src引入本地文件
<script src="../js/vue.js" type="text/javascript" charset="UTF-8"></script>说明:
- 1.引入Vue.js后,Vue会被注册成一个全局变量,通过操作这个函数可以进行后续的操作
- 2.通过src引入在线文件(使用CDN加速)
开发版本<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>生产版本
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>模板库引入(暂时未用到)
<script type="module"> import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.esm.browser.js' </script>
2.通过NPM命令行工具下载安装
2.引入类型
3.例子
- 1.在head中引入vue.js包
- 2.在body中定义一个
- 3.所有的页面都是展示在这个
中,每次改变不会全局刷新,而是通过Vue.js框架操作代码,对其中内容进行局部刷新DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue测试 title> <script src="../js/vue.js" type="text/javascript" charset="UTF-8"> script> head> <body> <div id="app"> { {hello}} div> <script> var app = new Vue({ el: "#app", data: { hello: "Hello World! This is my first test" } }) script> body> html>- 4.控制台上出现下列语句即表示成功
3.Webpack+Vue.js开发
1.概述
- 1.大部分Vue.js项目都是在Webpack的框架下进行开发的
- 2.vue-cli直接把Webpack做了集成
NVM(Node Version Manager)
NPM(Node Package Manager)
只要安装了node,就会捆绑安装该命令,它的作用与Ruby中的bundler以及Java中的maven相同,都是对第三方依赖进行管理
npm install vue vue-cli -g

main.js:没有实际的业务逻辑,但是为了支持整个Vue.js框架,很有必要存在
package.json:node项目配置文件

4.Webpack+Vue.js实战
- 默认的路由文件是src/router/index.js,将其打开后,增加两行
- import SayHello from ‘@/components/SayHello.vue’表示从当前目录下的components引入SayHello文件,其中@表示当前目录
- 然后定义路由,其中path表示对应的一个url,name表示Vue.js内部使用的名称,component表示对应的.vue页面的名字,即:每当用户访问http://localhost:8080/#/say_hello时,文件就会渲染./components/SayHello.vue文件,name:’SayHello’定义了该路由在Vue.js内部的名称,其中当path为/表示默然访问该页面
假设有lib/math.js文件
export function sum(x, y) {
return x + y } export var pi = 3.14
import * as math form "lib/math" alert("2π =" + math.sum(math.pi,math.pi))
import {
sum, pi} from "lib/math" alert("2π =" + sum(pi, pi))
可以直接调用sum()和pi
ES中的简写
<script> export default {
data () {
return {
} } } </script> 实际上是下面的简写形式 <script> export default {
data:function() {
return {
} } } </script>
.then(response => {
}) 等同于 .then(function(response) {
... })
这样写的好处是强制定义了作用域,使用=>之后,可以避免很多由作用域产生问题
hash中同名的key,value的简写
let title = 'body' return {
title: title } 等同于 let title = 'body' return {
title }
'use strict' const path = require('path') const utils = require('./utils') const config = require('../config') const vueLoaderConfig = require('./vue-loader.conf') function resolve (dir) {
return path.join(__dirname, '..', dir) } module.exports = {
context: path.resolve(__dirname, '../'), entry: {
app: './src/main.js' }, output: {
path: config.build.assetsRoot, filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath }, resolve: {
extensions: ['.js', '.vue', '.json'], alias: {
'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), } }, module: {
rules: [ {
test: /\.vue$/, loader: 'vue-loader', options: vueLoaderConfig }, {
test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] }, {
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: {
limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, {
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: {
limit: 10000, name: utils.assetsPath('media/[name].[hash:7].[ext]') } }, {
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: {
limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } ] }, node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue // source contains it (although only uses it if it's native). setImmediate: false, // prevent webpack from injecting mocks to Node native modules // that does not make sense for the client dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty' } }
module.exports = {
... entry: {
app: './src/main.js' //定义了Vue.js的入口文件 }, ...

这里的
就是将来会动态变化的内容
index.html文件是最外层的模板
new Vue({
el: '#app', // 这里的#app对应index.html中的
router, components: {
App }, template: '
' // 这里,App就是./src/App.vue })
...,该元素与index.html中的是同一个元素
所有的中的内容都会被自动替换,中的代码这是脚本代码
代码中
所有的动作都可以靠url来触发
这个技术是靠Vue.js的核心组件vue-router来实现的
不使用router的技术:邮箱,邮箱是属于url无法与某个页面一一对应的项目,所有页面的跳转都无法根据url来判断
最大的特点是不能保存页面的状态,难以调试,无法根据url进入某个页面
视图中的渲染
<template> <div class="hello"> <h1>{
{
msg }}</h1> <h1>{
{
test }}</h1> </div> </template> <script> export default {
name: 'HelloWorld', data () {
return {
msg: 'Welcome to Your Vue.js App', test: '变量渲染成功!' } } } </script>
<template> <div class="hello"> <h1>{
{
msg }}</h1> <h1>{
{
test }}</h1> <input type="button" @click="say_hi('李四')" value="点击"/> </div> </template> <script> export default {
name: 'HelloWorld', data () {
return {
msg: 'Welcome to Your Vue.js App', test: '变量渲染成功!' } }, methods: {
say_hi: function(name){
alert("Hi,"+name) } } } </script>

事件处理
在所有的Directive中,只能使用表达式
循环: v-for
<template> <div class="hello"> <ul> <li v-for="name in names"> {
{
name}} </li> </ul> </div> </template> <script> export default {
name: 'HelloWorld', data () {
return {
names: ["李四", "王五", "赵六"] } }, } </script>

判断: v-if
条件Directive是由v-if , v-else-if, v-else配合完成
<template> <div class="hello"> <p>选择姓名:</p> <div v-if="name === '王五'">王五</div> <div v-else-if="name === '赵六'">赵六</div> <div v-else="name === '李四'">李四</div> </div> </template> <script> export default {
name: 'HelloWorld', data () {
return {
name: '赵六' } }, } </script>
注意,v-if后面的引号中是===,
===是Ecmascript的语言,表示严格判断,因为js的 == 有先天缺陷,一般都是使用三个等号的形式
这里是引用
var num = 1; var str = '1'; var test = 1; test == num //true 相同类型 相同值 test === num //true 相同类型 相同值 test !== num //false test与num类型相同,其值也相同, 非运算肯定是false num == str //true 把str转换为数字,检查其是否相等。 num != str //false == 的 非运算 num === str //false 类型不同,直接返回false num !== str //true num 与 str类型不同 意味着其两者不等 非运算自然是true啦 == 和 != 比较若类型不同,先偿试转换类型,再作值比较,最后返回值比较结果 。 而 === 和 !== 只有在相同类型下,才会比较其值。 首先,== equality 等同,=== identity 恒等。 ==, 两边值类型不同的时候,要先进行类型转换,再比较。 ===,不做类型转换,类型不同的一定不等。 下面分别说明: 先说 ===,这个比较简单。下面的规则用来判断两个值是否===相等: 1、如果类型不同,就[不相等] 2、如果两个都是数值,并且是同一个值,那么[相等];(!例外)的是,如果其中至少一个是NaN,那么[不相等]。(判断一个值是否是NaN,只能用isNaN()来判断) 3、如果两个都是字符串,每个位置的字符都一样,那么[相等];否则[不相等]。 4、如果两个值都是true,或者都是false,那么[相等]。 5、如果两个值都引用同一个对象或函数,那么[相等];否则[不相等]。 6、如果两个值都是null,或者都是undefined,那么[相等]。 再说 ==,根据以下规则: 1、如果两个值类型相同,进行 === 比较。 2、如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较: a、如果一个是null、一个是undefined,那么[相等]。 b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。 c、如果任一值是 true ,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。 d、如果一个是对象,另一 个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。js核心内置类,会尝试 valueOf先于toString;例外的是Date,Date利用的是toString转换。非js核心的对象,令说(比较麻烦,我也不大懂) e、任何其他组合,都[不相等]。 举例: "1" == true 类型不等,true会先转换成数值 1,现在变成 "1" == 1,再把"1"转换成 1,比较 1 == 1, 相等。 = 赋值运算符 == 等于 === 严格等于 例: var a = 3; var b = "3"; a==b 返回 true a===b 返回 false 因为a,b的类型不一样 ===用来进行严格的比较判断 1 2 var data = ({
"val":"7","flag":"true"}); <FONT face=Verdana></FONT> 下面需要如何判断flag的值? 因为true加双引号==推测是字符串true 如果不加双引号===就是布尔值true 这个很重要,之前我一直没有搞清楚这一点 写法1 1 if(data.flag=true){
…}else{
..} 这样写怎么都是正确的,根本得不到else的值,原因是这种写法相当于 1 if(true){
…} 写法2 1 if(data.flag==true){
…}else{
..} 没有这种写法 写法3 1 if(data.flag='true'){
…}else{
..} 这样写怎么都是正确的,根本得不到else的值,原因是这种写法相当于 1 if(true){
…} 写法4 1 if(data.flag=='true'){
…}else{
..} 这个才是正确的写法 “=”:这个表示赋值,不是表示运算符 “==”:表示等于(值) “===”:表示全等于(类型和值)
v-for与v-if的优先级:
- {
{name}}

这是颜色测试!

通过v-bind把《p》元素的style的值绑定成了’color:’ + my_color表达式,当my_color的值发生变化时,对应的颜色也会变化
对于所有的属性,都可以使用v-bind
使用http请求需要为当前的SPA项目加上http请求的支持
import VueResource from 'vue-resource' Vue.use(VueResource)
设置Vue.js开发服务器的代理
正常来说,JavaScript在浏览器中是无法发送跨域请求的,我们需要在Vue.js的开发服务器上做转发配置
修改config/index.js文件,增加下列内容
module.exports = {
dev: {
'/api': {
// 1.对所有以/api开头的url做处理 target: 'http://sivei.me' // 2.转发到simwei.me上 changeOrigin: true, pathRewrite: {
'^/api': '' 3//把url中的'/api去掉' } } } }
以上代理服务器内容只能在开发模式下才能使用,在生成模式下,只能靠服务器的nginx特性来解决js跨域问题
this. h t t p 中 的 t h i s . 表 示 当 前 的 v u e 组 件 , http中的this.表示当前的vue组件, http中的this.表示当前的vue组件,http表示所有以 开 头 的 变 量 都 是 v u e 的 特 殊 变 量 , 往 往 是 v u e 框 架 自 带 , 这 里 的 开头的变量都是vue的特殊变量,往往是vue框架自带,这里的 开头的变量都是vue的特殊变量,往往是vue框架自带,这里的http就是可以发起http请求的对象
$http.get是一个方法,可以发起get请求
this.$route.query.id获取url中的id参数
修改页面的跳转方式:使用事件
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/199949.html原文链接:https://javaforall.net
