赞
踩
Vue.js 是一套构建用户界面的渐进式(Progressive framework)框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用(逐步增强和逐步采用,即渐进式表现)。Vue 的核心库只关注视图层。Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。Vue 学习起来非常简单,易于上手,且便于与第三方库或既有项目整合。另一方面,当vue与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。本文参考相关网文,也采用 Vue 2.1.8 版本来阐述,官方最新稳定版本:2.6.12。
其中,渐进式代表的含义是:主张最少。每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式。Vue可能有些方面是不如React,不如Angular,但它是渐进的,没有强主张,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用;还可以用它的视图,搭配你自己设计的整个下层用。你可以在底层数据逻辑的地方用OO和设计模式的那套理念,也可以函数式,都可以,它只是个轻量视图而已,只做了自己该做的事,没有做不该做的事,仅此而已。
vue相关资源:vue官方文档、vue资源精选、vue GitHub、基于vue和element构建的后台前端解决方案
1)前后端分离总架构图
2)前端架构设计图
3)MVVM架构模式
MVVM 由 Model,View,ViewModel 三部分构成,Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
结合view来看,Vue.js 可以说是MVVM 架构的最佳实践,是一个JavaScript MVVM库,是一套构建用户界面的渐进式框架。专注于 MVVM 中的 ViewModel,不仅做到了数据双向绑定,而且也是一款相对比较轻量级的JS 库,API 简洁;
另,由于vue的双向数据绑定特性以及技术的成形,实现了项目的热加载,可实现页面代码改完能立即在浏览器方面进行效果展示,提高开发效率;下图进一步描述了mvvm分层与vue的关系:
4)vue的双向数据绑定的原理
Vue.js 是采用 Object.defineProperty 的 getter 和 setter,并结合观察者模式来实现数据绑定的。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
组件说明:
Observer 数据监听器: 能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者,内部采用Object.defineProperty的getter和setter来实现。
Compile 指令解析器: 它的作用对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数。
Watcher 订阅者: 作为连接 Observer 和 Compile 的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数。
Dep 消息订阅器: 内部维护了一个数组,用来收集订阅者(Watcher),数据变动触发notify 函数,再调用订阅者的 update 方法。
5)url到页面显示的过程
├── build # 构建相关
├── static # 静态资源
│ │── img # 图片
│ │── favicon.ico # favicon图标
│ └── index.html # html模板
│ │── Tinymce # 富文本
├── src # 源代码
│ ├── api # 所有请求
│ ├── assets # 主题 字体等静态资源
│ ├── components # 全局公用组件
│ ├── directive # 全局指令
│ ├── icons # 项目所有 svg icons
│ ├── lang # 国际化 language
│ ├── layout # 全局 layout
│ ├── router # 路由
│ ├── store # 全局 store管理
│ ├── styles # 全局样式
│ ├── utils # 全局公用方法
│ ├── views # views 所有页面
│ ├── App.vue # 入口页面
│ ├── main.js # 入口文件 加载组件 初始化等
│ └── permission.js # 权限管理
├── tests # 测试
├── .env.xxx # 环境变量配置
├── .eslintrc.js # eslint 配置项
├── .gitignore # git 配置项
├── .babelrc # babel-loader 配置
├── .travis.yml # 自动化CI配置
├── vue.config.js # vue-cli 配置
└── package.json # package.json
上面为常见的目录结构,在实际开发过程中,会因为项目的差异,有所不同;
1)build——[webpack配置]
build文件主要是webpack的配置,主要启动文件是dev-server.js,当我们输入npm run dev首先启动的就是dev-server.js,它会去检查node及npm版本,加载配置文件,启动服务。
2)config——[vue项目配置]
config文件主要是项目相关配置,我们常用的就是当端口冲突时配置监听端口,打包输出路径及命名等
3)index.html——[主页]
index.html如其他html一样,但一般只定义一个空的根节点,在main.js里面定义的实例将挂载在根节点下,内容都通过vue组件来填充
4)App.vue——[根组件]
【template】:其中模板只能包含一个父节点,也就是说顶层的div只能有一个(例如下图,父节点为#app的div,其没有兄弟节点)
<router-view></router-view>是子路由视图,后面的路由页面都显示在此处
打一个比喻吧,类似于一个插槽,跳转某个路由时,该路由下的页面就插在这个插槽中渲染显示
5)main.js——[入口文件]
main.js主要是引入vue框架,根组件及路由设置,并且定义vue实例,下图中的
components:{App}就是引入的根组件App.vue
后期还可以引入插件,当然首先得安装插件。
.vue文件的基本模板:
1、windows 环境
1)安装javascript运行环境node.js
2)安装Nodejs下的包管理器,打开windows命令窗口,执行安装:
npm install -g cnpm --registry=https://registry.npm.taobao.org
3)安装vue-cli脚手架构建工具,在cmd,执行:cnpm install -g vue-cli
4)安装完成后,cmd输入vue,验证vue已成功安装:
5)cmd内,cd 到vue的安装的路径“,然后输入:vue init webpack 项目名,创建项目:
6)cd到安装好的项目文件夹,输入:npm run dev,运行项目
7)浏览器输入:http://localhost:8080,验证运行效果
8)构架项目案例(来源网络):
案例一:
开发工具使用的是 HBuilder,先创建一个 web 项目
在 js 下创建 app.js,在 css 下创建 style.css,如下:
编写index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>VueLearn-cnblogs/xpwi</title>
<!--引入自定义的样式-->
<link rel="stylesheet" href="css/style.css" />
<!--引入 vue 核心 js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<!--vue-app 是根容器,定义一个 id,然后在 js 里操作-->
<div id="vue-app">
<!--name 具体的值是在 js 中定义的,{{}}不会显示在页面上 -->
<h2>{{name}}</h2>
</div>
<!--引入自己的 js,注意必须写在 body 标签里最后,因为必须先加载你的整个 HTML DOM,才回去执行 vue 实例-->
<script type="text/javascript" src="js/app.js" ></script>
</body>
</html>
编写app.js 代码:
/实例化 vue 对象
new Vue({
//注意代码格式
//el:element 需要获取的元素,一定是 html 中的根容器元素
el:"#vue-app",
data:{
name:"CSDN"
}
});
浏览器访问验证:
案例二:
1)app.js 文件代码:
//实例化 vue 对象
new Vue({
//注意代码格式
//el:element 需要获取的元素,一定是 html 中的根容器元素
el:"#vue-app",
data:{
name:"***"
},
//存储自己的方法
methods:{
welcome: function(){
alert(" welcome to learn with me!");
},
good: function(time){
alert("Good " + time + " " + this.name + "!" )
}
}
});
//实例化 vue 对象
new Vue({
//注意代码格式
//el:element 需要获取的元素,一定是 html 中的根容器元素
el:"#vue-app",
data:{
name:"***",
blogUrl:"https://www.cnblogs.com/xpwi",
csdnUrl:"https://blog.csdn.net/qq_40147863",
/*定义 html 代码块,在 html标签中绑定获取
【特别注意】:单引号和双引号交替使用,不然都不知道怎么蹦的
*/
csdnHtml:"<a href='https://blog.csdn.net/qq_40147863'>CSDN 地址</a>",
},
//存储自己的方法
methods:{
welcome: function(){
alert(" welcome to learn with me!");
},
good: function(time){
alert("Good " + time + " " + this.name + "!" )
}
}
});
2)html文件代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>VueLearn-cnblogs/xpwi</title>
<!--引入自定义的样式-->
<link rel="stylesheet" href="css/style.css" />
<!--引入 vue 核心 js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<!--vue-app 是根容器,定义一个 id,然后在 js 里操作-->
<div id="vue-app">
<!--welcome 具体的值是在 js 中定义的-->
{{welcome()}}
<!--方法传参数-->
{{good("afternoon")}}
</div>
<!--引入自己的 js,注意必须写在 body 标签里最后,因为必须先加载你的整个 HTML DOM,才回去执行 vue 实例-->
<script type="text/javascript" src="js/app.js" ></script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>VueLearn-cnblogs/xpwi</title>
<!--引入自定义的样式-->
<link rel="stylesheet" href="css/style.css" />
<!--引入 vue 核心 js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<!--vue-app 是根容器,定义一个 id,然后在 js 里操作-->
<div id="vue-app">
<!-- v-bind 是 vue 中给标签属性绑定 js 中定义的值 -->
<a v-bind:href="blogUrl">博客园地址</a>
<br />
<input type="text" v-bind:value="name" />
<br />
<!--v-html 是拿 js 中的数据然后将字符串转换成 html 代码-->
<p v-html="csdnHtml"></p>
</div>
<!--引入自己的 js,注意必须写在 body 标签里最后,因为必须先加载你的整个 HTML DOM,才回去执行 vue 实例-->
<script type="text/javascript" src="js/app.js" ></script>
</body>
</html>
3)效果:
2、Linux环境:
Vue项目通常通过webpack工具来构建,而webpack命令的执行是依赖node.js的环境的,所以首先要安装node.js。node.js的官方地址为:https://nodejs.org/en/download/,下载相应版本。
1)下载Nodejs软件
或直接运行:wget https://nodejs.org/download/release/v9.11.2/node-v9.11.2-linux-x64.tar.xz
2)创建Nodejs目录,执行:#mkdir -p /usr/lib/nodejs/,完成后将下载Node包解压到 新建目录,执行:
tar -xf node-v9.11.2-linux-x64.tar.xz -C /usr/lib/nodejs/
mv node-v9.11.2-linux-x64/ node-v9.11.2
cd nodejs-v9.11.2
./bin/node -v // 验证当前版本,如果新安装的话就不用了
ln -s /app/software/nodejs/bin/npm /usr/local/bin/
ln -s /app/software/nodejs/bin/node /usr/local/bin/
rm -f /usr/local/bin/node
ln -s /usr/lib/nodejs/node-v9.11.2/bin/node /usr/local/bin/
./node -v //再次验证nodejs
返回v9.11.2即表示成功
3)cnpm的安装
安装完node之后,npm包含的很多依赖包也需要一起安装,但这些安装包的下载地址在国外的服务器上,但淘宝对npm的做了镜像服务器,下面执行,利用此安装cnpm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm -v //验证
rm -f /usr/local/bin/cnpm //如果有旧环境
ln -s /usr/lib/nodejs/node-v9.11.2/bin/cnpm /usr/local/bin/cnpm
cnpm -v //再次验证
4)vue-cli(脚手架)的安装:
vue-cli是vue官方提供的一个命令行工具,可用于快速搭建大型单页应用。该工具提供开箱即用的构建工具配置,带来现代化的前端开发流程。只需一分钟即可启动带热重载、保存时静态检查以及可用于生产环境的构建配置的项目。
npm install -g vue-cli //安装vue工具
rm -f /usr/local/bin/vue
ln -s /usr/lib/nodejs/node-v9.11.2/bin/vue /usr/local/bin/vue
5)新建一个Vue项目:
新建一个项目文件夹,命名为 vue-demo,执行:
cd ./vue-demo
vue init webpack vue-demo //初始化,完成后项目目录结构如下:
npm run dev
cnpm install //装载
cnpm run dev //运行
6)待启动后,浏览器访问http:\localhost:8080
7)网页测试:
npm install -g http-server //安装http-server
http-server //启动
浏览器访问上述url,查看效果。
参考链接:https://blog.csdn.net/dingpeiqiang/article/details/87829886?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242
https://www.cnblogs.com/xpwi/p/9911541.html
1)DOM((Document Object Model)
即文档对象模型,在以往的JavaScript中,经常需要操作DOM。DOM指对文档结构化的一种描述,并将HTML页面与脚本、程序语言联系起来的逻辑对象。DOM是一种XML和HTML文档的解析标准,DOM提供相应的API(函数库,提供编程的工具)可以对节点树进行增、删、改、查,DOM的原理是将XML、XHTML文档装入内容,并以节点的形式解析为一颗节点树(节点是元素标记),利用DOM可以让JavaScript对网页中的元素进行控制,实现动态网页的功能。可以理解为DOM就是一系列页面功能的集合。通过这些功能可以对HTML文档进行动态操作,从而实现许多动态交互效果。常用的就是通过javascript对HTML DOM进行访问。DOM是HTML文档的接口。 它被浏览器用作确定在视口中呈现内容的第一步,并通过Javascript程序来修改页面的内容,结构或样式。 HTML DOM将html元素定义为对象,API以对象方法和对象属性的形式实现。 可直接调用DOM实现的方法,进行DOM操作。
在vue中,当渲染视图时候会调用render函数,render函数为每个页面组件创建虚拟DOM。通过使用虚拟dom树,就可提高view渲染效率。由于真实dom的创建、更新。插入等操作带来大量的性能消耗,从而降低渲染效率,所以使用虚拟dom树来代替真实dom。这种渲染不仅发生在组件创建时候,还会发生在视图所依赖的数据更新时;组件实例首次渲染时,会生成虚拟dom树,根据虚拟dom树创建真实dom,并把真实dom挂载到页面合适位置,此时每个虚拟dom对应一个真实dom;
DOM的优势:主要表现在易用性强,使用DOM时,将把所有的XML文档信息都存于内存中,并且遍历简单,支持XPath,增强了易用性。
DOM的缺点:主要表现在效率低,解析速度慢,内存占用量过高,对于大文件来说几乎不可能使用。另外效率低还表现在大量的消耗时间,因为使用DOM进行解析时,将为文档的每个element、attribute、processing-instrUCtion和comment都创建一个对象,这样在DOM机制中所运用的大量对象的创建和销毁无疑会影响其效率。
vue中,在虚拟dom创建过程中,都会加载到elm属性,它就是真实的dom;每个虚拟DOM都对应一个真实DOM;首次渲染时,vue比单纯创建dom元素的效率要低,vue的高效体现在响应式数据变化的虚拟dom。
当数据变化,再次渲染时,vue的虚拟DOM会对比组件依赖的数据受到响应式数据的影响,它会重新调用render函数创建虚拟dom树,用新旧虚拟dom树比较,vue会找到最小更新量,然后更新必要的虚拟dom节点,最后修改对应的真实dom。这样就保证了对真实dom达到最小的变动。vue框架中有一个compile模板,它主要负责将模板转换成为render函数,而render函数调用后将得到虚拟dom。
如果简单理解前端工作主要就是维护状态和更新视图,而更新视图和维护状态都需要操作DOM。真实的 dom 是由 节点(Node)组成,虚拟 dom 则是由虚拟节点(vNode)组成。虚拟 dom 在 vue 中主要做两件事:
1、提供与真实节点(Node)对应的虚拟节点(vNode);
2、将新的虚拟节点与旧的虚拟节点进行对比,找出需要差异,然后更新视图
MVVM使用数据双向绑定,使得开发人员完全不需要直接操作DOM了,更多关注前端的逻辑实现,只要更新了状态,视图会自动更新。更新了视图数据状态也会自动更新,这种MVVM架构使得前端的开发效率大幅提升。但是其大量的事件绑定使得其在复杂场景下的执行性能堪忧,这种背景下,Virtual DOM(虚拟DOM)的引入就是一种兼顾了开发效率和执行效率的解决方案。它利用在内存中生成与真实DOM与之对应的数据结构,这个在内存中生成的结构称之为虚拟DOM 。当数据发生变化时,能够智能地计算出重新渲染组件的最小代价并应用到DOM操作上。Virtual DOM 本质上就是在 JS(执行很快) 和 DOM 之间做了一个缓存。可以类比 CPU 和硬盘。这样,(JS)只操作内存(Virtual DOM),最后的时候再把变更写入硬盘(DOM)即可。
vue在一定程度上知道具体哪个状态发生了变化和哪些节点使用了这个状态,这样就可以通过更细粒度的绑定来更新视图。代价是粒度太细会有很多watcher同时观察某些状态,会有一些内存开销以及一些依赖追踪的开销。vue2.0采取了一个中等粒度的解决方案,状态侦测只细化到某个组件,组件内部通过虚拟DOM渲染视图,这可以大大缩减依赖数量和watcher数量。 vue通过模板描述状态和视图之间的映射关系,它会先将模板编译成渲染函数,然后执行渲染函数生成虚拟节点,使用虚拟节点更新视图。vue提供虚拟节点和对比新旧vnode,并根据对比结果进行DOM操作来更新视图。
我们来看一段HTML代码以及其对应的DOM树形结构图:
<html>
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>
<h1>标题</h1>
<ul>
<1i>
<a href="#">链接</a>
</1i>
</ul>
</body>
</html>
层层嵌套的HTML标签就是一个类似树形的DOM文档。其中,最外面的一层是标签,标签中嵌套着标签和标签,而这两个标签中也会嵌套其他标签,这样一层层的延伸很像一棵倒着的树。对应的DOM树如下:
其中,所有的元素内容都是一个节点。其中,<html>是所有内容的根节点,<body>是<h1>和<ul>的父节点。<a> 和<meta>标签下面的分支href与charset是标签的属性,在DOM中称为属性节点;标签下面的文本是属于该标签内部的文字,在DOM中称为文本节点。
2)vue中el、template、replace元素
参看官方:https://cn.vuejs.org/v2/api/#el
1>El 元素节点
类型: String | HTMLElement | Function
new Vue({
el: '#ppp',
router,
store,
render: h => h(App)
})
el 用于指明 Vue 实例的挂载目标。值可以是 CSS 选择符,或实际 HTML 元素,或返回 HTML 元素的函数。注意元素只用作挂载点。如果提供了模板则元素被替换,除非 replace 为 false。元素可以用 vm. e l 访问。如果在初始化时指定了这个选项,实例将立即进入编译过程。否则,需要调用 v m . el 访问。如果在初始化时指定了这个选项,实例将立即进入编译过程。否则,需要调用 vm. el访问。如果在初始化时指定了这个选项,实例将立即进入编译过程。否则,需要调用vm.mount(),手动开始编译。注意:如果存在 render 函数或 template 属性,则挂载元素会被 Vue 生成的 DOM 替换;否则,挂载元素所在的 HTML 会被提取出来用作模版。
2>template 元素节点
类型: String
实例模板:模板默认替换挂载元素。如果 replace 选项为 false,模板将插入挂载元素内。两种情况下,挂载元素的内容都将被忽略,除非模板有内容分发 slot。如果值以 # 开始,则它用作选项符,将使用匹配元素的 innerHTML 作为模板。常用的技巧是用<script type=“x-template”> 包含模板。
注意在一些情况下,例如如模板包含多个顶级元素,或只包含普通文本,实例将变成一个片断实例,管理多个节点而不是一个节点。片断实例的挂载元素上的非流程控制指令被忽略。
3>replace 元素节点
类型: Boolean; 默认值: true
限制: 只能与 template 选项一起用
它决定是否用模板替换挂载元素。如果设为 true(这是默认值),模板将覆盖挂载元素,并合并挂载元素和模板根节点的 attributes。如果设为 false 模板将覆盖挂载元素的内容,不会替换挂载元素自身。
3)vue生命周期的8个阶段
beforeCreate:在new一个vue实例后,只有一些默认的生命周期钩子和默认事件,其他的东西都还没创建。在beforeCreate生命周期执行的时候,data和methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和methods中的方法
create:data 和 methods都已经被初始化好了,如果要调用 methods 中的方法,或者操作 data 中的数据,最早可以在这个阶段中操作
beforeMount:执行到这个钩子的时候,在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的
mounted:执行到这个钩子的时候,就表示Vue实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。 如果我们想要通过插件操作页面上的DOM节点,最早可以在和这个阶段中进行
beforeUpdate: 当执行这个钩子时,页面中的显示的数据还是旧的,data中的数据是更新后的, 页面还没有和最新的数据保持同步
updated:页面显示的数据和data中的数据已经保持同步了,都是最新的
beforeDestory:Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁
destroyed: 这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于不可用状态。组件已经被销毁了。
4)Vue实例化
1>通过vue函数创建一个新的vue实例
一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可嵌套的、可复用的组件树组成的。
<div id="app">
<!-- {{ 插值表达式,可以赋值 取值 三元 }} --> {{ msg }}
</div><script src="./node_modules\vue\dist\vue.js"></script>
<script>
// 引入vue后 会白给你一个Vue构造函数
let vm = new Vue({ // 配置对象
el: '#app', // 告诉vue能管理那个部分,使用的是querySelector
data: { // data中的数据会被vm所代理
msg: 'hello world', // 可以通过vm.msg取到对应的内容 ,也可以赋值
}
})
</script>
之后再补充。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。