Vue是一个MVVM框架
- M 模型 model 数据
- V 视图 view
- VM C -> P -> VM 视图模型 -> 处理逻辑
单向数据流
- 数据由父级传递给子级
Vue是一个js渐进式框架
- 渐进式: 越学越难
- 想学的容易:加强基础
Vue是使用了虚拟DOM技术
Vue拥有便利性的指令
- 指令: 操作dom的一种方式
Vue拥有组件系统
- 组件: 组件是一个html、css、js的一个聚合体
Vue - Hello World案例
<!-- vue需要一个已有的dom作为整个vue作用的范围 - 除了这个范围vue失效 -->
<div id="app">
<!-- 插值表达式 {{}} -->
{{ this.msg }}
{{ msg }}
</div>
// console.log(Vue)
const vm = new Vue({
el: '#app',
data: { // vue中用来定义数据的选项,也是MVVM中的M
msg: 'Hello World',
}
})
- 当script标签引入Vue.js时,会得到一个全局变来个Vue,它是一个构造函数,构造函数是全局变量。
- 这个构造函数需要实例化才能起作用
- 需要一个已有dom作为vue实例作用范围
- 已有dom的内容为假,这个假指的是它是虚拟DOM,这个是从选项中分离出去的,可使用this,也可以省略this
- data选项中的数据,在app范围内相当于全局变量
- 要想在dom结构中书写js,则需要一个插值表达式,也就是{{}}
Vue的数据响应
- 称呼: 深入响应式原理 、 双向数据绑定原理
- 数据响应指的是: 当数据改变时,视图也会随之改变 ,当用户输入信息时,数据也改变了
vue数据响应 【 原理 】
- Vue是通过数据劫持来对数据进行响应式拦截的,通过使用es5的Object.defineProperty中的getter和setter来进行数据劫持的(data里面的数据)
vue的插值表达式 {{ }}
1,支持js的数据类型
<p> number: {{ num }} </p>
<p> string: {{ str }} </p>
<p> boolean: {{ bool }} </p>
<p> null: {{ nul }} </p>
<p> undefined: {{ und }} </p>
<p> obj: {{ obj.name }} </p>
<p> arr: {{ arr[ 1 ] }} </p>
<p> function: {{ fn() }} </p>
2,支持js的基本语法–运算符
<p> 运算符: {{ 1 + 1 }} </p>
<p> 三目运算符: {{ 5 > 3 ? '💻' : '👜' }} </p>
<p> 短路原则: {{ 5 > 3 && '💻' || '👜' }} </p>
<p> 数组操作: {{ stri.split('').reverse().join('') }} </p>
3,不支持js的输出语法
console / alert / confirm / document.write
以及window对象下的全局变量都不能用,如window.location.xx
<div> console.log: {{console.log('vue') }} </div> //不支持
4,不支持流程控制,例如for循环
<p> for循环: {{ for( var i = 0; i < 1000; i++ ){ } }}</p> //不支持
vue的常用指令–操作DOM
1,v-html :转义输出,也就是可以解析 xml 数据
2,v-text : 非转义输出,也就是无法解析 xml 类型数据
3,v-bind:将数据和属性进行单向数据绑定: 将vue中数据赋值给属性值
<img v-bind:src="src" alt="">
<img :src="src" alt=""> //简写形式 :
类名绑定
// <p :class = "{类名:布尔值 }"> 对象形式 </p>
<p :class = "{ size: flag,bg: true }"> 对象形式 </p>
<p :class = "[ 'size',flag && 'bg' || 'blue' ]"> 数组形式 </p>
样式绑定
<p :style = "{
width: '100px',
height: '100px',
background: 'purple'
}"> 对象形式 </p>
<p :style = "[{ width: '200px',height: '200px' },{ background: 'yellow' }]"> 数组形式 </p>
4,条件渲染
- v-if / v-else-if / v-else
// 1. 单路分支 if(){}
<p v-if = "5>3"> 单路分支 </p>
// 2. 双路分支 if () {} else {}
<p v-if = "flag"> 双路分支一 </p> // flag为布尔值
<p v-else> 双路分支二 </p>
// 3. 多路分支 if () {} else if () {} else {}
<p v-if = "grade < 60 "> 不及格 </p>
<p v-else-if = " grade >= 60 && grade < 80"> 良好 </p>
<p v-else> 优秀 </p>
- v-show
<p v-show = "showFlag"> 条件展示 </p> //showFlag为布尔值
总结:
v-if 控制的是元素的存在与否
v-show 控制的是元素的 display:none 属性,推荐频繁切换用
5,v-for 指令–列表渲染
<ul>
<li v-for = " (item,index) in items " :key = "item.id">
{{ item.good_name }}
</li>
</ul>
new Vue({
el: '#app',
data: {
items: [
{ id: 1, good_name: '华为手机' },
{ id: 2, good_name: '小米手机' }
]
}
)}
总结:
- 列表渲染参数可以写三个,分别为 item key index
- key的作用,在渲染的vdom元素身上加一个key,作为这个元素唯一的标识 ,以便diff算法进行同层级比较 ,key最好是id,因为id唯一
- 循环数据,in / of 都可以使用
- 数组的length是不响应的,简易数组下标不响应
//例如:arr: [ 'a','b','c' ]
change () {
this.arr[ 0 ] = 'aaa' 视图不更新
// 解决方案 this.$set -> Object.assign()
1, this.$set( this.arr, '0', 'aaa' )
2, Vue.set( this.arr, '0', 'aaa' )
}
6,v-on 事件处理器
<div v-on:click = "handle"></div>
// 简写:@事件类型 = '方法名'
<div @click = "handle"></div>
<p> counter的值为: {{ count }} </p>
// 事件传参
<button @click = "argHandle( 10,20 )"> 事件传参 </button>
new Vue({
el: '#app',
data:{
count:0,
},
methods:{
handle(){
this.count ++
},
argHandle ( a,b ) {
alert( a + b )
},
}
)}
事件修饰符(常用)
- stop 阻止事件冒泡
<div class="big" @click.stop = 'big'>
<div class="middle" @click.stop = "middle">
<div class="small" @click.stop = "small" ></div>
</div>
</div>
-
prevent 阻止默认事件
-
once 点击一次才执行
<button @click.once = 'submit'> 提交 </button>
- 按键修饰符 - 对键盘事件的修饰符 -> 键盘码的判断 enter
<input type="text" @keyup.enter = "keyHandler">
<input type="text" @keyup.13 = "keyHandler">
7,v-model 双向数据绑定
- VM 改变 V随之改变,V改变, VM也随之改变
- 专用于表单元素: input
- 默认绑定表单元素的value属性
<div id="app">
用户名: <input type="text" v-model = "username"> <br>
密码: <input type="text" v-model = "password"> <br>
</div>
new Vue({
el: '#app',
data: {
username: '',
password: ''
},
)}