Vue基础
vue特点
- 采用组件化模式,提高代码复用率,且让代码更好维护
- 声明式编码,让编码人员无需直接操作DOM,提高开发效率
- 使用虚拟DOM+优秀的diff算法,尽量服用DOM节点
声明式编码和命令式编码对比
-
命令式编码
// 准备html字符串 let htmlStr = '' // 遍历数据拼接html字符串 person.forEach(p => { htmlStr += `<li>${ p.id} - ${ p.name} - ${ p.age}<li>` }); // 获取list元素 let list = document.getElementById('list') // 修改内容(亲自操作DOM) list.innerHTML = htmlStr
-
声明式编码
<ul id="list"> <li v-for="p in person"> { { p.id}}--{ { p.name}}--{ { p.age}} </li> </ul>
一、引入vue
1. 下载
直接下载开发版本,包含完整的警告和调试模式
2. CDN
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
3. NPM
构建大型应用时:
npm install vue
二、创建第一个vue程序
- 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
- root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法
- root容器里的代码被称为【Vue模板】
- Vue实例和容器是一一对应的
- 真实开发中只有一个Vue实例,并且会配合着组件一起使用
{ {xxx]}
中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性- 一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新
1. 模板语法
html 中包含了一些 JS 语法代码,语法分为两种,分别为:
1.1 插值语法
- 用于解析标签体内容
- 语法: { {xxx}} ,xxxx 会作为 js 表达式解析
1.2 指令语法
- 用于解析标签(包括标签属性、标签体内容、绑定事件……)
- 举例:
v-bind:href = 'xxxx'
,xxxx
会作为 js 表达式被解析 - 说明:Vue 中有有很多的指令,此处只是用 v-bind 举个例子
2. 数据绑定
2.1 单向数据绑定(v-bind)
- 语法:
v-bind:href ="xxx"
或简写为:href
- 特点:数据只能从 data 流向页面
2.2 双向数据绑定(v-model)
-
语法:
v-mode:value="xxx"
或简写为v-model="xxx"
因为v-model默认收集的就是value值) -
特点:数据不仅能从 data 流向页面,还能从页面流向 data
- 双向绑定一般都应用在表单类元素上(如:input、select等)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue</title> <script src="./vue.js"></script> </head> <body> <!-- 1 准备好一个容器 --> <div id="root"> <!-- 插值语法 --> <h1>Hello,{ {name}}</h1> <!-- 指令语法 --> <a v-bind:href="url">百度一下</a> </div> <script type="text/javascript"> Vue.config.productionTip = false // 阻止vue在启动时生成生产提示 // 2 创建Vue实例 new Vue({ el:'#root', // el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串 data: { // data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象 name: 'Vue', url: 'http://www.baidu.com' } }) </script> </body> </html>
3. el的两种写法
-
new Vue时候配置el属性
-
先创建Vue实例,随后再通过vm.$mount(‘#root’)指定el的值
const vm = new Vue({ // el:'#root', // 第一种写法 data: { name: 'Vue' } console.log(v) vm.$mount('#root') // 第二种写法,更灵活,比如放到定时器中 })
4. data的两种写法
- 对象式:
data:{ name:'Vue'}
- 函数式:
data(){ return { name: 'Vue'} }
- 在组件中,必须使用函数式
- 由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了
5. 一个重要的原则
由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了
三、Vue核心设计理念
-
数据驱动:通过特殊的语法将数据与页面元素绑定,无需手动操作dom,只要改变数据就能使dom同步更新
-
遵循MVVM(Model–view–viewmodel)模型的框架
四、MVVM模型
-
M:Model代表数据模型,对应data中的数据
-
V:View代表UI组件,模板
-
VM:ViewModel将Model和View关联起来,Vue实例对象
数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据
观察发现:
- data中所有的属性,最后都出现在了vm身上。
- vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
MVVM框架的三要素:响应式,模板引擎,渲染
- 响应式:Vue 如何监听数据的变化?([响应式原理](何将模板转化为html代码?
- 模板:Vue 如何设置模板与我们的页面元素绑定,以及如何解析?
- 渲染:Vue 如何将模板转化为html代码?
Vue 数据的双向绑定:数据变化更新视图,视图变化更新数据
- 通过事件监听的方式来实现对view变化的监听,来更新data
- vue 数据双向绑定主要是实现了根据data的变化来更新view
对应的还有个MVC:mvc和mvvm的区别
-
Model(模型):是应用程序中用于处理应用程序数据逻辑的部分。
-
View(视图):是应用程序中处理数据显示的部分。
-
Controller(控制器):是应用程序中处理用户交互的部分。
MVC的思想:一句话描述就是Controller负责将Model的数据用View显示出来
五、数据代理
通过一个对象代理对另一个对象中属性的操作(读/写)就叫做数据代理
1. Vue中的数据代理
通过vm对象来代理data对象中属性的操作(读/写)
2. Vue中数据代理的好处
更加方便的操作data中的数据
3. 基本原理
通过Object.defineProperty()把data对象中所有属性添加到vm上;
为每一个添加到vm上的属性,都指定一个getter/setter;
在getter/setter内部去操作(读/写)data中对应的属性。
// Object.defineProperty
let person = {
name: '张三',
sex: '男'
}
// 给person添加一个属性age,通过这种方式添加的属性是不可枚举的
Object.defineProperty(person, 'age', {
value: 18,
enumerable: true, // 控制属性是否可以枚举,默认值为false
writable: true, // 控制属性是否可以被修改,默认值为false
configurable: true // 控制属性是否可以被删除,默认值为false
})
console.log(person); // {name: '张三',sex: '男',age: 18}
// 通过以下方式验证其不可枚举性
// console.log(Object.keys(person)); // ["name", "sex"]
// for (let key in person) {
// console.log(person[key]); // "张三" "男"
// }
------------------------------------------------------------------------------------
let number = 18;
let person = {
name: '张三',
sex: '男'
}
// 给person添加一个属性age,通过这种方式添加的属性是不可枚举的
Object.defineProperty(person, 'age', {
// 当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get() {
console.log('有人读取了age属性');
return number
},
// 当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value) {
console.log('有人修改了age属性,且值时', value);
number = value
}
})
--------------