官方网站:Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)
Vue是一套用户构建用户界面的渐进式JavaScript框架
简单的说就是怎么把数据变成界面
渐进式:Vue可以自底向上逐层的应用。
简单应用:我们只需要引入一个轻量小巧的核心库即可
复杂应用:引入Vue插件
组件化模式,提高代码复用率,且让代码更好维护
加入我们想修改下图页面中"推荐活动"的内容,我们只修改Activity.vue文件即可,其他地方不用动
下面是之前操作DOM的形式:命令式编码
下面是如今形式:
原生JavaScript如下所示。
有“张三”、“李四”、“王五”这三个人,使用list.innerHTML写到页面
后面数据发生了变化,新加了一个“赵六”,其他人的信息不变,如果我们还用list.innerHTML写到页面,那“张三”、“李四”、“王五”三个人又写了一次,也就是说我们本来在页面上的“张三”、“李四”、“王五”三个人的数据并没有复用
Vue实现
Vue先把“张三”、“李四”、“王五”三个人变成虚拟DOM,最后把虚拟DOM变成页面的真实DOM
把虚拟DOM理解成内存中的数据
原生JavaScript直接把数据写到页面上,而Vue是先写到内存中,再写到页面,中间多了一个写入内存后必定会浪费时间
假如在“张三”、“李四”、“王五”数据不变的前提下,我们新增一个“赵六”的用户,这时候虚拟DOM的优势就体现出来了。
如果有个新的虚拟DOM和旧的虚拟DOM,他会把两个DOM进行Diff比较,对比会发现“张三”、“李四”、“王五”都是一样的,所以进行复用了,只会生成一个“赵六”的虚拟DOM
介绍 — Vue.js (vuejs.org)
写script标签的时候有一个属性src可以指定资源的位置,为了更好的访问src指定的资源的位置,我们就可以加一个CDN的加速
Vue提供了两个版本,一个是开发版本,一个是生产版本。
开发的时候使用开发版,如果有错误的话会有提示
生产版本是开发完了要进行上线,让文件的体积更小,我们会选择生产版本
将文件下载下来 :开发版 vue.js 生产版本 vue.min.js(生产版本会经过压缩)
引入vue.js开发文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF8" />
<title>初始vue</title>
<!--引入开发版vue.js-->
<!--引入后多了一个全局Vue对象/函数 (这个Vue可以被当做对象,也可以被当做函数)-->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
</body>
</html>
打开页面观察控制台,有一个提示:
提示1:请您下载Vue的开发工具达到一个更好的体验 (参考1.3下载即可)
提示2:您正在运行一个开发版本的Vue,请您确信在生产环境中不要这么做(参考1.4解决)
然后我们在控制台输入“Vue”,确实会出来一个Vue的构造函数。假如说我们不引入vue.js或vue.main.js时是不会有下面这个构造函数的
我们故意让程序报错,那控制台就会有提示
<script type="text/javascript" src="../js/vue.main.js">
我们故意让程序报错,那控制台少了一个友好的提示,直接提示Vue底层的提示
进入下面这个网址https://v2.cn.vuejs.org/v2/guide/installation.html,点击“Vue Devtools”
就会进入GitHub主页,下面会有一个“Installation”,如果是谷歌就下载谷歌对应的,如果是火狐就下载火狐对应的
但是不要点括号中的内容,它是开发工具的测试版,是在Vue3.0的时候使用的
假如现在是谷歌,如下图所示,点击“添加”即可
但是国内许多人无法登录到GitHub,那就采用下面的方式
比如谷歌浏览器(其他浏览器也同理,只要找到“管理扩展程序模块”搜vue即可)
如下所示
消除下面这个提示信息
方法1: 切换成生产环境就会消除提示
方法2:不让他提示
怎么不让他提示呢?查看文档
查看API文档
API — Vue.js (vuejs.org)
Vue.config都是vue对全局的配置,一次修改,在哪都能用
下面有一个“productionTip”默认是“true”开启状态
<body>
<script type="text/javascript">
Vue.config.productionTip = false
script>
body>
想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
root容器里面的代码依然符合html规范,只不过混入了一些特殊的Vue语法
root容器里面的代码被称为Vue模板
这个模板是很重要的概念
模板的解析流程: 先有的id=root的div容器,后有的new Vue实例,当Vue实例开始工作后发现el指定了id=root的容器,然后Vue实例就把对应的容器拿过来进行解析,去找找有没有一些特殊语法,比如说插值语法,如果有的话就进行替换,最后就会生成一个全新的id为root的div容器
模板经过解析就变成了正常的HTML片段
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF8" />
<title>初始vue</title>
<!--引入开发版vue.js-->
<!--引入后多了一个全局Vue对象/函数 (这个Vue可以被当做对象,也可以被当做函数)-->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备一个容器,在这个容器中呈现我们的页面-->
<div id="root">
<!--{{name}}是插值语法-->
<h1>Hello,{{name}} 你很棒!!</h1>
</div>
<script type="text/javascript">
//关闭开发环境时的生产提示
Vue.config.productionTip = false
//在整体调整productionTip后再写代码
//当我们引入vue.js文件后,我们全局就多了一个Vue函数
//创建Vue实例,并且参数只传一个配置对象。配置对象的value值、数据类型是不能随便更改的
// 比如axios中 axios({ url: "xxxx"}) 这个“url”是不能随便更改的,如果改成“ura”就不会实现对应的功能
const x = new Vue({
el: '#root', //用于指定当前Vue实例为哪个容器服务,值通常为CSS选择器字符串,比如这个地方是div标签的选择器
// el: document.getElementById('root'),我们之前是这么获取的
// data用于存储数据,数据供el所指定的容器去使用,此data先暂时写成一个对象
data: {
name: "张靖奇"
}
})
//el是element元素的简称,el: '#root'是一个id选择器,找到了id为root的标签
//假如说没有el: '#root'配置,容器和vue实例是关联不到一起的,互相不知道对方的存在。
//当写上el: '#root'配置后,容器和vue实例关联到了一起。vue实例就知道了要把页面成果展示到root所对应的标签中
</script>
</body>
</html>
假如我们页面上有俩容器,其class都是“root”,然后我们的Vue实例el='.root‘,那Vue实例会根据我们所写的选择器找容器root,会发现有两个。
那两个class=root的容器都被Vue实例给接管了,而且两个容器中都使用了插值语法{{name}}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF8" />
<title>初始vue</title>
<!--引入开发版vue.js-->
<!--引入后多了一个全局Vue对象/函数 (这个Vue可以被当做对象,也可以被当做函数)-->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="root">
<!--{{name}}是插值语法-->
<h1>Hello,{{name}} 你很棒!!</h1>
</div>
<div class="root">
<!--{{name}}是插值语法-->
<h1>Hello,{{name}} 你很棒!!</h1>
</div>
<script type="text/javascript">
//关闭开发环境时的生产提示
Vue.config.productionTip = false
const x = new Vue({
el: '.root',//class选择器
data: {
name: "张靖奇"
}
})
</script>
</body>
</html>
那按照我们的理解页面是不是会出现两个“张靖奇”?
但其实不是,如下图所示:第一个是正常的,但是第二个没有人解析(不会报错)
原因
根据我们写的el:'.root’它会找到两个容器,但是只会用第一个,不会用第二个
一个Vue实例不能去接管两个容器
<!-- 准备一个容器,在这个容器中呈现我们的页面-->
<div id="root">
<h1>Hello,{{name}} 你很棒!!</h1>
</div>
<script type="text/javascript">
//关闭开发环境时的生产提示
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
name: "张靖奇"
}
})
new Vue({
el: '#root',
data:{
name:"大帅哥"
}
})
</script>
效果如下图所示:控制台不会报错,说明是第一个Vue接管的容器
再将代码改成下面这个样子
<!-- 准备一个容器,在这个容器中呈现我们的页面-->
<div id="root">
<h1>Hello,{{name}} 你很棒!!{{address}}</h1>
</div>
<script type="text/javascript">
//关闭开发环境时的生产提示
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
name: "张靖奇"
}
})
new Vue({
el: '#root',
data:{
address:"大帅哥"
}
})
</script>
效果图,说明是第一个Vue接管的容器
控制台报错
原因:当一个Vue实例出现后,它就和id为root的容器绑定在一块,那当我们第二个Vue实例出现也要与id为root的容器绑定,显然是无法绑定的
一个容器只能被一个Vue实例接管
容器与Vue实例之间的关系是一对一
1.想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
2.root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法
3.root容器里面的代码被称为【vue模板】
4.Vue实例和容器是一一对应的
5.真实开发中只有一个Vue实例,并且会配合组件一起使用
6.{{xxx}}中xxx要写js表达式,name模板中用到该数据的地方也会自动更新
7.一旦data中的数据发生改变,那么模板中用到该数据的地方也会自动更新
在页面上使用Vue插件的时候有一个
Vue虽然没有完全遵循MVVM模型,但是Vue的设计收到了MVVM的启发
MVVM是Vue实现数据驱动视图和双向数据绑定的核心原理,把每个HTML页面都拆分成了如下三个部分:
M: 模型(Model),对应data中的数据,表示当前页面渲染时所依赖的数据源,并且data中的所有属性最终都会出现在VM身上(数据代理)。
V:视图(View),模板,表示当前页面所渲染的DOM结构
VM:视图模型ViewModel,Vue实例对象,是MVVM的核心。
vm身上所有属性及Vue原型上所有数据,在Vue模板中都可以直接使用
ViewModel里面有两条线:DOM Listeners所在线 和 Data Bindings所在线
DOM Listeners :DOM监听器,在前面的双向数据绑定案例中,我们在输入框中输入了一个数据,然后Vue实例中对应的value也会改变,也就是页面中的改变会映射回数据中的改变。
这个监听器得时时刻刻的监听这个输入框 ,还得知道监听的是什么,并且将改变后的值同步到Vue实例对象中对应的值内
DataBindings: 数据绑定,简单的来说就是我们写data的时候,不论是写对象还是写函数,里面都是一组一组的key :value,这一组组的key value经过Vue数据绑定就把数据展示在了页面的对应位置