(3)vue基础2
(3)事件
- 对于指定元素,使用v-on绑定事件,v-on可简写成@。
- 按键修饰符,一般直接写按键的名称。
- 事件修饰符
-
-
- .stop:默认事件的传递方式是冒泡,同一事件会在元素内部和外部触发,有时可能会造成事件的错误发生,需要用.stop修饰符阻止事件冒泡。
- Html标签具有自身特性,例如<a>标签在单击时会发生自动跳转。在实际开发中,如果<a>标签的默认行为与事件发生冲突,可用.prevent修饰符阻止<a>标签的默认行为。多阻止a的默认行为。
- .capture事件捕获的执行顺序书由外部结构向内部结构执行,与事件冒泡顺序相反。
- .self事件修饰符.self用来实现只有DOM元素本身会触发的事件
- .once事件修饰符,绑定的函数只会执行一次
-
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>学生列表案例</title> <script type="text/javascript" src="./vue/vue.js"></script> <style type="text/css"> .odiv1{width:80px; height: 80px; background-color: orange;} .odiv2{width:50px; height: 50px; background-color: green;} </style> </head> <body> <div id="app"> <div> <button @click="count += Math.random()">随机数</button> <p>自动生成的随机数为:{{count}}</p> </div> <!-- 事件修饰符 --> <div> <input type="text" @keyup.enter="submit"> </div> <!-- 阻止冒泡 --> <div class="stop"> <div @click="chilcPar"> <button @click="clickChild">事件冒泡</button> <button @click.stop="clickChild">阻止事件冒泡</button> </div> </div> <!-- 阻止默认行为 --> <div class="prevent"> <a href="https://www.baidu.com/" @click.prevent>阻止默认行为</a> <a href="https://www.baidu.com/">不阻止默认行为</a> </div> <!-- 事件捕获,由外部向内部执行 --> <div class="capture"> <div @click.capture="capClickPar"> <button @click="capClickChild">事件捕获</button> </div> </div> <!-- self修饰符,只有自身才能触发,第一个div盒子,点击子元素时,会发生事件冒泡,但父元素添加了self修饰符,只有自身才能触发,所以不会执行,第二个没有添加,所以会执行 --> <div class="self"> <div class="odiv1" @click.self="seClickPar">a <div class="odiv2" @click="seClicChil">b</div> </div> <div class="odiv1" @click="seClickPar">c <div class="odiv2" @click="seClicChil">d</div> </div> </div> <!-- once事件修饰符,只执行一次 --> <div class="once"> <button @click.once="onceClick">只执行一次</button> </div> </div> <script type="text/javascript"> var vm = new Vue({ el:"#app", data:{ count:0 }, methods:{ submit(){ console.log("表单提交成功!") }, chilcPar(){ console.log("父元素被点击了") }, clickChild(){ console.log("子元素被点击了") }, capClickPar(){ console.log("事件捕获的父元素") }, capClickChild(){ console.log("事件捕获的子元素"); }, seClickPar(){ console.log("判断self的父元素被点击了") }, seClicChil(){ console.log("判断self的子元素被点击了") }, onceClick(){ console.log("点击多少次,也只会执行一次") } } }) </script> </body> </html>
-
- (4)组件
- 全局组件
- 局部组件
- 父子组件间的传值
- 父组件向子组件传值:prop,用来接收父组件定义的数据,其值为数组,数组中是父组件传递的数据信息
- 子组件向父组件传值
全局组件与局部组件
组件模板

<body> <div id="app"> <my-firstcom></my-firstcom> <my-firstcom></my-firstcom> <my-firstcom></my-firstcom> <!-- 使用的时候,中间使用短横线链接,注册时使用驼峰法则 --> <sec-compon></sec-compon> </div> <script type="text/javascript"> // 注册全局组件 // 参数1:组件名称 // 参数2:组件的配置对象 Vue.component("my-firstcom",{ // 组件使用的数据 data(){ return { count:0 } }, // 组件模板:组件显示的内容 template:"<button @click='count++'>被单击了{{count}}次</button>" }) // 注册局部组件 var com1 ={ template:"<p>我是一个局部变量组件</p>" } var vm = new Vue({ el:"#app", components:{ secCompon:com1 }, data:{} }) </script> </body>

<body> <div id="app"> <p>{{title}}</p> <my-component></my-component> </div> <template id="temp1"> <p>{{title}}</p> </template> <script type="text/javascript"> // 配置全局组件 Vue.component("my-component",{ el:"#temp1", data(){ return { title:"我是注册组件的tltle" } } }) var vm = new Vue({ el:"#app", data:{ title:"我是父组件的title" } }) </script> </body>
- (1)父组件向子组件传值
- 父组件传值子组件分为多种数据情况,props定义为数组数据。其中传值数据可以为普通数据、封装数据、数组数据和对象数据。
- 数组数据在传值的过程中要注意使用v-for数据渲染的过程中,组件只允许有一个根节点,所以在定义的过程中要首先定义一个外包裹的标签元素。
- 对象数据在传递的过程中,可以仅仅传递过来数据的某个字段,其他未传过来的字段是是用不了的。

<body> <div id="app"> <my-parent name="title"></my-parent> </div> <script type="text/javascript"> Vue.component("my-parent",{ // 规定组件可以通过那些属性传递数据 props:["name"], template:"<div>我是父组件的{{name}}</div>" }) var vm = new Vue({ el:"#app", data:{} }) </script> </body>
- (2)子组件像父组件传值

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>组件模板</title> <script type="text/javascript" src="./vue/vue.js"></script> <style type="text/css"> </style> </head> <body> <div id="app"> <parent></parent> </div> <template id="child"> <div> <button @click="click">send</button> <input type="text" v-model="message"> </div> </template> <template id="parent"> <div> <child @childfn ="transContent"></child> <p>子组件传递过来的值为:{{message}}</p> </div> </template> <script type="text/javascript"> Vue.component("child",{ template:"#child", data(){ return { message:"子组件的message" } }, methods:{ click(){ //通过$emit调用自定义函数,然后传递数据 this.$emit("childfn",this.message) } } }) Vue.component("parent",{ template:"#parent", data(){ return { message:"" } }, methods:{ transContent(transDate){ this.message = transDate } } }) var vm = new Vue({ el:"#app", data:{} }) </script> </body> </html>
- (3)组件间的切换 v-if v-else

<body> <div id="app"> <div> <a href="#" @click.prevent="flag=true">登录</a> <a href="#" @click.prevent="flag=false">注册</a> </div> <div> <login v-if="flag"></login> <register v-else>我是注册页面</register> </div> </div> <script type="text/javascript"> Vue.component("login",{ template:"<div>我是登录页面</div>" }) Vue.component("register",{ template:"<div>我是注册页面</div>" }) var vm = new Vue({ el:"#app", data:{ flag:true } }) </script> </body>
(5)vue的生命周期
- 钩子函数
- 实例创建
- 页面挂载
- 数据更新:vue实例挂载完成后,当数据发生变化,会执行beforeUpdate和updated钩子函数
- 实例销毁
生命周期案例

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>钩子函数</title> <script type="text/javascript" src="./vue/vue.js"></script> <style type="text/css"> </style> </head> <body> <div id="app"> <p>{{msg}}</p> <div> <div v-if="show" ref="div">我是一个div标签</div> <button @click="show=!show">改变</button> </div> <!-- ref引用,可以使用$refs获取页面所有引用 --> <div ref="self">实例销毁</div> </div> <script type="text/javascript"> var vm = new Vue({ el:"#app", data:{ msg:"创建一个实例", show:true }, beforeCreate(){ console.log("实例创建之前"); // console.log(this.$data.msg) }, created(){ console.log("实例创建之后"); console.log(this.$data.msg) }, beforeMount(){ console.log("挂载前"); console.log(this.$el.innerHTML) }, mounted(){ console.log("挂载完成"); console.log(this.$el.innerHTML) }, beforeUpdate(){ //在数据发生变化时运行 console.log("数据更新之前"); console.log(this.$refs.div) }, updated(){ console.log("数据更新之后") console.log(this.$refs.div) }, beforeDestroy(){ console.log("实例销毁之前"); console.log(this.$refs.self); console.log(this.$data.msg); console.log(vm) }, destroyed(){ console.log("实例销毁之后"); console.log(this.$refs.self); console.log(this.$data.msg); console.log(vm) } }) </script> </body> </html>
注意:销毁实例不会自动执行,如果需要自行,需要在控制台手动输入vm.$destrot()
实现图片的轮流播放两种写法
<div class="wrap"> <!-- 执行在创建过程中会自动执行的生命周期钩子函数 --> <div id="app" > <img v-for="(item, index) in imgSrc" :src="item" :id="id(index)" @mouseover ="visible(index)" @mouseout="visible(index)"> </div> </div> <script type="text/javascript"> var vm = new Vue({ el:"#app", data:{ imgSrc:["./img/Jellyfish.jpg","./img/Chrysanthemum.jpg","./img/Desert.jpg","./img/Hydrangeas.jpg"], flag:[true,true,true,true] }, methods:{ visible(index){ // 获取操作的对象 var pic = document.getElementById("pic"+index); if(this.flag[index]==true){ pic.style.opacity="0.6"; this.flag[index]= !this.flag[index] }else{ pic.style.opacity="1" this.flag[index]= !this.flag[index] } }, id(value){ return "pic"+value } } }) </script>
<body> <div class="wrap"> <!-- 执行在创建过程中会自动执行的生命周期钩子函数 --> <div id="app"> <img v-for="(item, index) in imgSrc" :src="item" :id="fuc(index)" @mouseover="visible($event,1)" @mouseout="visible($event,0)"> </div> </div> <script type="text/javascript"> var vm = new Vue({ el:"#app", data:{ imgSrc:["./img/Jellyfish.jpg","./img/Chrysanthemum.jpg","./img/Desert.jpg","./img/Hydrangeas.jpg"], flag:[true,true,true,true] }, methods:{ fuc:function(index){ return "pic"+index }, visible : function(e,value){ if(value == 1){ e.target.style.opacity="0.6" }else{ e.target.style.opacity="1" } } } }) </script> </body>