文章目录
vue - 构建页面的渐进式框架;
1、框架 和 库:
框架: 拥有完整的解决方案。核心是库,框架大一些,我们按别人的规则写好,人家来调用。vue
库:我们调用;jQuery、zepto、animate.css
渐进式框架:通过组合,完成一个完整的框架。就向vue 全家桶:核心是vuejs + vue-router(单页面应用) + vuex(状态管理) + axios(获取数据) ,这一套组合成全家桶;
2、vue特点
- 核心只关注视图(view)
- 轻量,灵活
- 实用移动端项目
- 渐进式框架
3、渐进式的理解
- 声明式渲染(不用关心如何实现)
- 组件开发
- 客户端路由(vue-router) -单页面开发
- 大规模状态管理(vuex) -方便数据管理
- 构建工具vue-cli
(less/sass/es6 只有chrome支持,要转译成es5/webpack-代码压缩合并)
vue-cli解决了全套方案,包括怎么上线,添加路径前缀,压缩文件,合并文件
4、vue 的两个核心点
- 响应式的数据变化-数据驱动
当数据发生变化 - > 视图自动更新 - 组合的视图组件
ui页面映射为组件树,划分组件可维护、复用、测试
5、MVVM模式
之前是MVC 模式 - 单向
M-model数据、V-view视图 、C-controller 控制器
上图是一个场景,单项的,用户输入通过控制层取数据库获取数据然后修改视图。不能视图一改就直接修改数据,做不到!
MVVM 模式 - 双向
M-model数据(计划好的数据)、V-view视图(dom) 、VM- viewModel 视图模型
数据 通过data bindings 直接绑在视图上,视图通过Dom监听实时映射到数据。vue主要做的就是 viewModel
6、安装vue
vue 不支持ie8及以下版本,因为用到了es5的 Object.defineProperty 没有替代方案。
- cdn方式:引入链接
- npm 安装:node package manager
进到目录下,然后初始化
npm init
初始化,在当前目录下生成一个package.json的文件,这个文件用来描述项目的依赖
初始化的时候,不能有大写、特殊字符和中文,而且不能和安装的包的名字相同
npm init -y 按默认初始化,初始化的name是所在文件夹的名字,所以也不能有大写、特殊字符和中文,而且不能和安装的包的名字相同
license:MIT MIT是开源协议
vue3安装 参考安装vue:
npm install vue
默认下载最新版本,安装完后 会在package.json 的 dependencies里记录安装的依赖及版本号。下次没有依赖的话 直接npm install
就可以了
安装的文件在node_modules -> src -> dist(目的地) -> vue.js
把源码编译好产生目标文件扫描二维码关注公众号,回复: 10929946 查看本文章安装axios boostrap等:
npm install axios bootstrap
boostrap 是框架,利用栅格化布局实现响应式,
安装vue-cli
全局生成vue项目的脚手架vue-cli(vue-cli就是一个工具,帮我们生成一个vue项目,就像http-server也是一个工具)
脚手架:保证工作过程顺利进行的工作平台(做事前准备工作)
npm install vue-cli -g
# 全局:只能在命令行用,安装的时候要加 -g 任意一个目录下都可以安装
# mac下:sudo npm install vue-cli -g
#安装完vue-cli后,命令行上就有一个vue的命令 vue-cli -V查看版本
#安装vue-cli的作用:我们用它来创建一个项目
vue init webpack 项目名称
#用vue初始化一个带有webpack的项目,项目名是项目名称
#这样生成的项目里面集成了我们需要的文件
npm install
#安装依赖
npm run dev
7、vue初始化
引入vue后 会给一个Vue的构造函数,我们new 这个构造函数,new的时候传一个对象,返回的结果是一个vm == viewModel,data中的数据最终会被vm所代理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- moustache 小胡子语法 表达式:都是取值用的,可以放赋值,取值,三元-->
{{msg==='hello' ? 1 : 0 }}
</div>
<!-- vue 可以像jq一样引入 -->
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 引入vue后 会给一个Vue的构造函数,我们new Vue() ,这个构造函数 会返给我们一个结果:viewModel
let vm = new Vue({ //new的时候传一个对象,返回的结果是一个vm == viewModel
// 所有挂在vm上的数据都可以实现双向绑定
el: '#app', //图中的dom
//用的querySelector ,当前的vue实例vm 是作用在#app 上的
//告知vue能管理哪个部分(当前哪个部分的dom 归vue管理),不能挂载html 和body,要挂载普通元素
data: { //图中的计划好的数据对象,
// data中的对象,会被vm所代理,也就是可以通过vm.msg取到对应的内容(取数据 或者 赋值)
// 用到的核心点:Object.definePrototy 定义属性
msg: 'hello'
}
})
</script>
</body>
</html>
8、MVVM
- {{}} 只能查看数据(数据控制视图),我们需要用到表单元素(input,checkbox,textarea,radio,select )来修改数据,然后结合行间的vue 指令(directive)将数据变化传递vm上
vue的指令directive 只是dom上的行间属性 ,vue给这类属性赋予了一定的意义,来实现特殊的功能,所有指令都以 v- 开头
{{msg}}
和{{this.msg}}
都是可以的,但是一般不写this
,取值表达式,里面可以写:赋值运算,计算 和 三元表达式。建议里面少写逻辑,有逻辑可以再后面的computed
里面写
- 在vue中 value 属性默认情况下会被vue忽略掉,selected,checked 都没有意义了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
{{msg}}
<!-- 如上的写法只能数据控制视图,没法视图控制数据,要实现视图控制数据,我们需要:表单元素:input,checkbox,textarea,radio,select -->
<!-- 表单元素可以更改数据,然后通过vue 指令directive -->
<!-- value 属性默认情况下会被vue忽略掉,selected,checked 都没有意义了 -->
<input type="text" v-model='msg'>
<!-- v-model 会将msg的值赋给输入框,输入框的值改变会影响数据(数据影响视图,视图改变数据) -->
<!-- vue是声明式的,根本看不到原理: -->
<!-- Object.defineProperty ES5的方法 -->
</div>
<!-- vue 可以像jq一样引入 -->
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({ //new的时候传一个对象,返回的结果是一个vm == viewModel
el: '#app', //图中的dom
data: { //图中的计划好的数据对象,
msg: 'hello'
}
})
</script>
</body>
</html>
9.MVVM 实现核心:Object.defineProperty()
目的: 把一个数据绑到输入框上,当输入框的值改变了,引起数据的变化(视图改变数据),
核心:靠的是Object.defineProperty 里的 get 和 set 方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" >
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
//目的: 把一个数据绑到输入框上,当输入框的值改变了,引起数据的变化(视图改变数据)
// 核心靠的是Object.defineProperty 里的get 和 set 方法
// obj.a = 1; 之前给对象加属性,也可以用Object.defineProperty()来加属性
// Object.defineProperty(要加属性的对象,属性名,{配置})
let obj = {}; //一个没有实际意义的对象,我们给它加属性,但内部操作的时候要操作temp,不然操作obj 会一直调用它的相应的方法;
let temp ={}; //temp 代替obj 取存取
Object.defineProperty(obj, 'name', {
// value: '1', //属性值 ****注意:这里不能写
// configurable: true, //是否可配置(可删除) 例如 delete obj.name 删除对象中的某属性,可配置就可以删,不可配置就不能删(删不掉)
// writable: true, //是否可写(可重新赋值) obj.name =1000; 无效,改不了值
enumerable: false, //是否可枚举, 不可枚举就无法遍历
//get()、set()是原生的ES5方法
get() { //取值调用:取obj的属性的时候会触发 eg:obj.name
return temp[name]; //这里return的值就是我们 取到的值
},
set(val) { //赋值调用:给obj的某属性赋值会触发get方法
//当我们赋值 obj.name='lxz' 的时候,调用set方法,值就是set的参数val
// val就是我们要赋的值,我们把它赋给obj.name
// obj.name = val; //****这里我们得到val,不能这样赋值,不然这样(有一次赋值)会再一次调用set方法,这样会一直循环下去
// 会报错:Maxumum call 最大调用,死循环了
// 这里我们可以采用第三方变量temp,我们赋值的时候不去改obj的属性,改temp属性
temp[name] = val;
oInput.value =val; //4.改变数据后,视图里也改变了
}
})
var oInput = document.getElementsByTagName('input')[0];
oInput.value = obj.name; //1.页面以加载进来,会调用get方法
oInput.addEventListener('input',function(){ //2.监听input事件
obj.name = this.value; //3.给obj.name赋值时,调用set方法
})
</script>
</body>
</html>