目录
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
Vue.js是什么
vue是一套用于构建用户界面的渐进式框架。
与其他框架不同的是,Vue被设计为可以自底向上逐层应用
Vue的核心库只关注视图层
实现局部功能代码的资源集合
框架和库的区别
框架:是一套完整的解决方案,对项目的侵入性较大,项目如果需要更换框架,需要重新架构整个项目
库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现
MVVM模型
M 模型Model 对应data中的数据
V 视图View 模板(插值表达式)
VM 视图模型ViewModel Vue实例对象
插值表达式{ {}}
vm身上以及vue原型对象身上所有的属性和方法在模板里可以直接用
数据代理
Object.defineProperty
添加属性
所生成的属性不可枚举(正常遍历遍历不到,而且无法更改)
let person = {
name:'sun',
sex:'女',
}
Object.defineProperty(person,'age',{
value:18,
enumberable:true, //控制属性是否可以枚举,默认值是false
writable:true, //控制属性是否可以被修改,默认值是false
configurable:true, //控制属性是否可以被删除,默认值是false
})
当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
Object.defineProperty(person,'age',{
get:function() {
return 'hello'
},
当有人修改person的age属性时,set函数(setter)就会被调用,且值是value
set(value) {
console.log('修改了age属性,且值是',value)
}
})
数据代理
通过一个对象代理另一个对象中的属性的操作(读/写)
通过obj获取x,修改x
let obj = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj,'x',{
get() {
return obj.x
};
set(value) {
obj.x = value
}
})
通过修改obj2.x obj.x的值也会改变
vue中的数据代理
vm._data就是平时我们写的data
vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)
vue中数据代理的好处:更加方便的操作data中的数据
基本原理:通过Object.defineProperty()把data对象中所有属性添加到vm上,为每一个添加到vm上的属性都制定一个getter/setter,在getter/seter内部去操作(读/写)data中对应的属性
计算属性
data中有数据发生改变,vue实例就会重新解析
<div id="root">
姓:<input type="text" v-model = "firstName">
名:<input type="text" v-model = "lastName">
全名:<span></span>
</div>
<script>
var vm = new Vue({
el:'#root',
data:{
firstName:'sun'
lastName:'sss'
},
computed:{
fullName:{
有人读取fullName时,get会瞬间被调用,且返回值作为fullName的值
get(){
return this.firstName+this.lastName; //this是vm
}
当fullname被修改的时候调用set
set() {
} } }
})
</script>
get什么时候调用:1.初次读取fullName时。2.所依赖的数据发生变化时(computed有缓存)
计算属性定义:要用的属性不存在,要通过已有属性计算得来
原理:底层借助了Object.defineproperty方法提供个getter和setter
优势:与computed相比内部有缓存机制(复用),效率高,调试方便
计算属性最终会出现vm上,直接读取使用即可
如果计算属性要修改,必须使用set函数去响应修改,且set中要引起计算时依赖的数据发生变化
计算属性简写
简写
fullName:function(){
console.log("get被调用了")
return this.firstName+this.lastName;
}
function函数就是get函数
监视属性
绑定事件@xxx="yyy",yyy可以写一些简单语句
<body>
<div id="root">
<h2>今天天气{
{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
</body>
<script>
const vm = new Vue({
el:'#root',
data: {
isHot:true,
},
computed:{
info() {
return this.isHot ? 'hot' : 'cold'
}
},
methods: {
changeWeather() {
this.isHot = !this.isHot
}
},
watch:{
isHot:{
handler(newValue,oldValue){
console.log(newValue,oldValue);
} } } })
</script>
</html>
handler:当isHot发生改变时被调用
watch中的配置属性
immediate:true; //初始化时让handler调用一下
第二种写法
......
watch:{
// isHot:{
// immediate:true,
// handler(newValue,oldValue){
// console.log(newValue,oldValue);
// }
// }
}
})
vm.$watch('isHot',{
immediate:true,
handler(newValue,oldValue){
console.log(newValue,oldValue);
}
})
监视属性变化时,回调函数自动调用,进行相关操作
监视属性必须存在,才能进行监视
深度监视
监视多级结构中某个属性的变化
var vm = new Vue({
el:'#root'
data:{
numbers:{
a:1,
b:2
}
},
watch:{
'numbers.a':{
handler(){console.log('深层监视a')}
}
}
})
开启深度监视:deep:true;
监视多级结构中所有属性的变化
watch:{
deep:true,
number:{
handler(){console.log('深层监视a')}
}
}
vue中的watch默认不监视对象内部值的改变,只能监视一层
配置deep:true 可以检测对象内部值的改变
vue自身可以检测对象内部值的改变,但vue提供的watch默认不可以
使用watch时根据数据的具体结构决定是否采用深度监视
监视属性的简写
只有不使用immediate和deep的时候才能简写
watch:{
正常写法
isHot:{
handler(newValue,oldValue) {
console.log('isHot被修改啦',newValue,oldValue)
}
},
简写(函数当handler用)
isHot(newValue,oldValue){
console.log('isHot被修改啦',newValue,oldValue)
}
}
正常写法
vm.$watch('isHot',{
handler(newValue,oldValue) {
console.log('isHot被修改啦',newValue,oldValue)
})
简写
vm.$watch('isHot',function(newValue,oldValue) {
console.log('isHot被修改啦',newValue,oldValue)
})
watch对比computed
区别:
1.computed能完成的功能watch都可以完成
2.watch能完成的功能,例如watch可以进行异步操作,computed不能完成
两个重要的小原理:
1.所有vue管理的函数最好写成普通函数,这样this的指向才是vm或组件实例对象
2.所有不被vue所管理的函数(定时器的回调函数,ajax的回调函数等)最好写成箭头函数(定时器的回调函数的this是window,如果使用箭头函数,则this是找外边的this,就还是vm),这样this的指向才是vm或组件实例对象
watch如何监测数据变化
如何监测对象变化
Vue.set():添加响应式数据
Vue.set(vm._data.student,'sex','男')
Vue.set(vm.student,'sex','男')
vm.$set(vm._data.student,'sex','女')
vm.$set(vm.student,'sex','女')
注意:对象不能使vue实例,或者vue实例的根数据对象(_data)
监测数组
调用这几个页面会有反应
vue将被侦听的数组的变更方法(上边七个)进行了包装,所以他们会触发视图更新
(用的不多)
总结
Vue监视数据的原理
1. vue会监视data中所有层次的数据。
2.如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1).对象中后追加的属性,Vue默认不做响应式处理
(2).如需给后添加的属性做响应式,请使用如下API:
vue.set(target,propertyName/index, value)或vm.$set(target,propertyName/index, value)
3.如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:(1).调用原生对应的方法对数组进行更新。
(2).重新解析模板,进而更新页面。
4.在vue修改数组中的某个元素一定要用如下方式:
使用这些API:push() pop() shift() unshift() splice() sort() reverse()
Vue.set() 或 vm.$set()
特别注意:Vue.set() 和 vm.$set() 不能给vm或vm的根数据对象(vm._data)添加属性
Vue基本代码
var vm = new Vue({
el: '#app',
data:{
message:'hello world'
}
methonds:{
show:function() {
alert('Hello')
}
}
})
还可以使用mount挂载
vm.$mount('#root')
el:表示当前我们new的这个vue实例要控制页面上的哪个区域
data:存放的是el中要用到的数据
methods:定义了当前Vue实例所有可用的方法
vue省去了操作DOM元素的步骤
插值语法
用于解析标签体内容,{ {xxx}} xxx是js表达式,可以直接读取到data中的所有属性
v-cloak
没值
vue创建完之后会消失
解决插值表达式闪烁问题(网络慢)
[v-cloak] {
display:none;
}
与v-text 区别:
网速慢来不及渲染Vue时,v-cloak有闪烁问题
v-text会覆盖元素中原本的内容,v-cloak可以在插值表达式前后放任意内容,不会整个覆盖
<p v-cloak>+++{
{ msg }}---</p>
<h4 v-text="msg">====</h4>
v-text
像其所在的节点中渲染文本内容
<div v-text="name">你好,</div>
会替换整个div里的内容
v-html
用于输出html标签,支持结构的解析
向指定节点中渲染包含html结构的内容
与插值语法的区别
1.v-html会替换节点中所有的内容,{ {}}不会
2.v-html可以识别html结构
严重注意
v-html有安全性问题(永远不要低估用户的输入)
(1)在网站上动态渲染任意HTML是非常危险的,容易导致XSS(冒充用户之手)攻击
(2)一定要有在可信的内容上使用v-html,永远不要用在用户提交的内容上
cookie
v-bind
是Vue中提供的用于绑定指令的属性,管理标签属性
<input type="button" value="按钮" v-bind:title="mytitle">
//用v-bind之后mytitle就变成了变量,而不是字符串
v-bind指令可以简写为 :要绑定的属性
v-bind中可以写合法的JS表达式
v-on
是Vue中提供的用于绑定事件的属性
<input type="button" value="按钮" v-bind:title="mytitle" v-on:click="show">
v-on可以缩写成@
v-model
只有这唯一的指令能实现双向事件绑定
v-bind只能实现单项绑定
<div id="app">
<input type="text" v-model:value="message">
<h4>{
{ message }}</h4>
</div>
var vm = new Vue({
el: '#app',
data: {
message: '123456789',
},
})
注意:v-model只能运用在表单元素中
表单元素:input(radio、text、address、email)、select、checkbox、textarea
收集表单数据
年龄<input type="number" v-model.number="userInfo.age">
type中的number是指 只能输入数字