vue
vue数据响应
Vue是单向数据流
- 深入响应式原理/双向数据绑定
- 数据驱动视图
- 数据发生改变时,视图也会改变
- 双向绑定
- 数据改变,页面改变;页面改变,数据改变
- new Vue()得到的结果是以标签化呈现的,,称为根实例组件
数据响应原理(Vue2.0)
- Vue是通过数据劫持来对数据进行响应式拦截,通过使用es5的Object.defineProperty()中的getter和setter来进行数据劫持的
- 数据劫持的对象是Vue中的data选项,在data外定义的数据是不做响应的
- 其中:
- get是做初始化赋值的(设置数据)
- set是完成数据的重新设置,也就是修改(对象数据已修改就会触发set函数),参数的值是改变后的值
模板语法(mustache)
用法: 1. 内容里用 2.dom属性上用
- 插值表达式的属性用法就是vue的新概念:指令
- 注:属性用法是不加{{}},但是属性上要加指令
- 插值表达式js的支持性
- js基本语法
- 输出语法 ×
- console
- alert
- confirm
- document.write
- 流程控制 ×
- for循环等
- 运算符
- 支持三目运算符和短路逻辑
- 5>3 && ‘真’||‘假’ 相当于 5>3?‘真’:‘假’
- 输出语法 ×
- 支持性
- 1.插值表达式对于js数据类型是支持的(null和undefined是不会显示的)
- 2.window对象下的全局变量都不能用(因为Vue里面的内容是this.msg,只有data里面的数据才能被响应)
- eg: window.console.log window.location.xx
for…in 和 for…of的区别:
-
for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值
-
for…in
- 1.index索引为字符串型数字,不能直接进行几何运算
- 2.遍历顺序有可能不是按照实际数组的内部顺序
- 3.使用for in会遍历数组所有的可枚举属性,包括原型,所以for in更适合遍历对象,不要使用for in遍历数组
-
for…of
- 1.for of遍历的只是数组内的元素,而不包括数组的原型属性
-
for in 可以遍历到myObject的原型方法method,如果不想遍历原型方法和属性的话,可以在循环内部判断一下,hasOwnPropery方法可以判断某属性是否是该对象的实例属性
for (var key in myObject) {
if(myObject.hasOwnProperty(key)){
console.log(key);
}
}
指令
用来操作DOM
-
文本渲染
- v-html=“data中的变量” 可以识别标签
- v-text=“data中的变量”
- v-show=“布尔值” 改变display属性
-
条件渲染
- v-if 决定一个标签的存在- v-else-if
- v-else
v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
-
单向数据绑定
-
v-bind:attr=data中的变量 (数据赋值给标签的属性)
- 简写 :attr=""
-
类名的绑定(不会覆盖已存在的class)
- 对象形式
- :class="{类名:布尔值}"
对象形式键名引用变量时要加中括号
<p :class = "{[ a ]: true,[ b ]: true }"></p>
- 数组形式
- :class="[‘size’,‘bg’]" 直接加类名,要加引号,否则会当作全局变量
- :class="[flag&&‘bg’||‘blue’]"
- 对象形式
-
样式的绑定
- 对象形式
注意:样式的值要加引号,否则会当作全局变量
<p :style = "{ width: '100px', height: '100px', background: 'purple' }"> 对象形式 </p>
注:样式绑定若有-的属性名,要用大写字母代替,如backgroundColor,fontSize
- 数组形式
<p :style = "[{ width: '200px',height: '200px' },{ background: 'yellow' }]"> 数组形式 </p> <p :style = "[ chicun,yanse ]"></p>
- 对象形式
-
列表渲染
v-for (每个循环有独立的作用域)
- 渲染number/string/arr类型数据
- in 和 of都可以使用,作用相同
- 会从1到num遍历
- 索引index从0开始
- 第一个参数是值,第二个参数是索引
<ul> <li v-for="(item,index) of num" >{{item}}--{{index}}</li> </ul>
- 渲染object类型数据
第三个参数为索引
<ul> <li v-for="(value,key,index) in obj" :key="index"> <!-- 给每一个渲染的li加上key属性,不是html的属性,不会显示在Elements中 --> {{value}}--{{key}}--{{index}} </li> </ul>
- 渲染嵌套类型数据
<ul> <li v-for = " item of nest "> <h3> {{ item.type }} </h3> <ul> <li v-for = " ele of item.category"> <p> {{ ele.type }} </p> </li> </ul> </li> </ul>
- 渲染number/string/arr类型数据
key的作用:
key的作用是为了区别每一个渲染的dom结构
简单数据渲染, key可以省略- 复杂数据渲染, key必须添加(json或嵌套类型数据)
key最好使用id,次之使用index
-
-
事件
<div v-on:click="hander"><div/> <!-- 简写形式 --> <div @click="hander"><div/>
Vue事件的书写顺序
先定义【 在选项中 】在绑定
事件函数写在methods选项中,可以用到this指针,this指向vmnew Vue({ el: '#app', data:{ count:0 }, methods:{ increase(){ this.count--; }, decrease(){ this.count++; }, change(e){ this.count=e.target.value } } })
Vue中的事件为原生事件,事件对象为原生事件对象
- 事件传参和事件对象e
- 当一个事件中既有事件对象,又有普通参数,那么我们在调用这个方法时,需要传入一个$event和对象对应
<button @click="add(2,5,$event)">相加<button/>
methods:{ add(a,b,e){ console.log(a+b) console.log(e) } }
- 事件修饰符
用来修饰事件,作用时更加便捷地使用一些重复地代码,比如阻止事件冒泡 ,阻止默认事件等 eg:@click.stop=hander()
- 常用事件修饰符
- .stop 阻止事件冒泡
- .prevent 拦截默认事件
- .capture 事件捕获
- .self 自己才能触发
- .once 执行一次
- .passive 不拦截默认事件
- passive就是为了告诉浏览器,不用查询了,我们没用preventDefault阻止默认动作。
- 注:passive和prevent冲突,不能同时绑定在一个监听器上。
- 常用事件修饰符
- 按键修饰符
- .按键码 13回车 32空格
- .enter
- .tab
- .tab
- .delete (捕获“删除”和“退格”键)
- .esc
- .space
- .up
- .down
- .left
- .right
- .ctrl
- .alt
- .shift
- .meta (windows键)
- 鼠标按键修饰符
- .left
- .right
- .middle
- 事件传参和事件对象e
-
事件的订阅和发布
- 事件的发布【声明一个事件】
- vm.$on(事件名,function(参数))
- 事件的订阅【触发一个事件】
- vm.$emit(事件名[,参数])
vm.$on('vapour',function(data){console.log(data)}) methods:{ ev(data){ vm.$emit('vapour',data) } } <button @click="vapour(600)">passive</button>
- 事件的发布【声明一个事件】
-
指令
- v-pre
- 显示原始的Mustache标签
- v-cloak
- 这个指令保持在元素上直到关联实例结束编译
- 不会显示Mustache,只会显示编译后的结果
<!-- 就是vue渲染完指定的整个DOM后才进行显示。它必须和CSS样式一起使用 --> [v-cloak]{ display:none } <div v-cloak>{{message}}<div/>
- v-once
- 只渲染一次
- v-pre
<style>
#app div{
padding: 2%;
margin-bottom: 1%;
border-bottom: 1px solid #ddd;
background-color: blanchedalmond;
}
[v-cloak]{
display: none;
}
</style>
<div id="app">
<!-- 不和data数据冲突 -->
<div v-pre>{{message}}</div>
<!-- 就是vue渲染完指定的整个DOM后才进行显示。它必须和CSS样式一起使用 -->
<div v-cloak>{{message}}</div>
<!-- 只显示DOM第一次渲染的值,以后不改了 -->
<div v-once>第一次绑定的值:{{message}}</div>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
message: '漂亮'
}
})
</script>
- 双向数据绑定
- 专用于表单元素 input
- 默认绑定表达元素的value属性
- v-model
<div id="app"> 用户名:<input type="text" v-model="username"> <div>显示:{{username}}<div/> <div/> <script> new Vue({ el:"#app", data:{ username='' } }) <script/>
- 双向数据流原理
单向数据流+事件实现双向数据绑定效果
<div id="app"> <input type="text" :value="val" @input="changeVal"> <div/> <script> data:{ val } methods:{ changeVal(e){ } } <script/>
- 不响应情况(数据改变,视图不改变)
- 数组的length属性是不响应的(将数组置0,视图不变)
- 简易数组下标不响应(通过下标修改数据,视图不变)
原因:没有经过getter和setter设置
- 解决方案: Object.assign()
methods:{ change(){ //this.$set(this.arr,'0','vapour') Vue.set(this.arr,'0','vapour') } }
- 自定义指令
自定义指令名 不能是大驼峰命名
- 全局定义
- Vue.directive(指令名称,指令的配置)
- 1.el: 指令绑定的dom元素
- 2.binding: 是否绑定了修饰符或表达式(modifiers/expression 指令后可以=“表达式/内部函数”)
Vue.directive('focus',{
bind:function(el,binding){
//指令绑定到dom元素时触发
},
inserted:function(el,binding){
//当指令绑定的dom元素插入页面时触发,即在视图能看到这个元素时触发
//可以操作dom
//如果带有once修饰符,执行以下操作
if (binding.modifiers.once) {
alert(1212)
}
},
update: function(el, binding) {
// 表示元素以及子元素发生更改时触发
} ,//了解
componentUpdated: function(el, binding) {
// 表示组件以及子组件发生更改时触发
}, //了解
unbind: function(el, binding) {
//解绑时触发,指令绑定的元素被删除
}
})
- 局部定义
new Vue({
el: '#app',
data: {},
directives: {
focus: {
inserted(el) {
el.focus()
}
}
}
})
-
自定义过滤器
- 过滤器是用于格式化数据的一个封装函数
- 可复用
- 常见过滤器(用途)
- 时间
- 小数位数
- 货币符号
- 大小写
- 对图片url进行格式化
- 定义形式
- 全局定义
- Vue.filter(过滤器名称,过滤器回调函数)
- 局部定义
- filters选项
- 全局定义
<!-- 使用 --> <ul v-for="item in movie"> <li> <img :src="item.img|imgFilter(128.180)" alt=""> <li/> <ul/>
//全局定义 Vue.filter('imgFilter',(val,size)=>{ return val.replace('w.h',size) })
filters:{ imgFilter(val,size){ return val.replace('w.h',size) } }
- 过滤器是用于格式化数据的一个封装函数
-
混入
将选项中某一个或是多个单独分离出去管理,让只能更加单一高效,符合模块化思想
- 全局混入
Vue.mixin({
methods:{
aa(){
alert('aa')
},
bb(){
alert('bb')
}
},
//全局中data要写成函数形式
data(){
return {
name:'zhangsan'
}
}
})
- 局部混入
const methods={
methods: {
aa() {
alert('aa')
},
bb() {
alert('bb')
}
}
}
const data={
data:{
name:'zhangsan',
age:12
}
}
//引入
new Vue({
el:'#app',
mixins:[data,methods]
})
分出去的mixin权利是没有内部的大的