一、VUE介绍
vue 以数据驱动的web渐进式框架 三大主流框架: Angular React Vue 设计模式:MVVM 1.数据驱动 => 不直接操作DOM 2.单页面web应用 => 构建的网站其实只有一个页面 3.数据的双向绑定 4.虚拟DOM 文件后缀: .vue => 组件 => Vue实例 <template></template> <script></script> <style></style> 组件化开发
1、VUE实例
v-bind 挂载点
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>vue实例</title> <style type="text/css"> p { width: 200px; height: 200px; background-color: red; } </style> </head> <body> <div id="app" class="app"> <p title="你真的是P">你是P</p> <!-- v-bind: 属于vue语法:vue指令 --> <!-- 第一个title是html标签的全局属性title --> <!-- 第二个title是vue的一个变量,变量名可以随意自定义 --> <p v-bind:title="title">你就是P</p> <!-- vue的变量一般需要进行初始化(赋初值) --> </div> <div id="main"> <p v-bind:title="my_title">你还是P</p> </div> </body> <!-- 在页面中引入vue --> <script src="js/vue-2.5.17.js"></script> <!-- 拥有vue环境后可以写vue支持的语法逻辑 --> <script type="text/javascript"> // 自身代码块 // 创建vue实例 new Vue({ // 将实例与页面结构进行关联, 尽量(只允许)用id进行绑定(将唯一的对象与页面唯一的结构进行一一绑定) // 该实例只操作关联的页面结构(包含子结构) // el: "#app" el: '.app', data: { title: "你就是P..." } }); // 将一个vue实例挂载到页面的一个页面结构 new Vue({ // 挂载点 el: "#main", data: { my_title: "" } }) </script> </html>
2、Vue 实例data
插值表达式
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>vue实例之data</title> </head> <body> <div id="app"> <!-- 插值表达式 --> {{ msg }} {{ num }} <!-- 插值表达式中可以进行运算 --> {{ 1 + 2 + 3 * 4 }} </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> var app = new Vue({ el: "#app", // data: 数据 // 为挂载点内部的vue变量提供值 data: { msg: "hello world!", num: 88888 } }) </script> <script type="text/javascript"> // 普通js代码块 // 获取msg,num变量的值 // 1.得到vue实例 console.log(app); // 2.获取vue变量data: $data console.log(app.$data); // 3.获取目标变量值 console.log(app.$data.msg); // 直接获取值 console.log(app.msg); console.log(app.num); </script> </html>
3、methods
<p v-bind:title="my_title">
<p class="box" v-on:click="abcClick">{{ abc }}</p>
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>methods</title> <style type="text/css"> .box { background-color: orange } </style> </head> <body> <div id="app"> <!-- v-on: 指令,操作事件的 --> <p class="box" v-on:click="abcClick">{{ abc }}</p> <p class="box" v-on:click="defClick">{{ def }}</p> <p class="box" v-on:mouseover="action">88888</p> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> new Vue({ el: '#app', data: { abc: "12345 上山打老虎 老虎不在家 ...", def: "67890 呵呵" }, // methods为挂载点内部提供方法的实现体 methods: { abcClick: function (ev) { console.log(ev); console.log("abc is clicked"); }, defClick (ev) { console.log(ev); console.log("def is clicked"); }, action () { console.log("被悬浮"); } } }) </script> </html>
4、computed
<input type="text" name="xing" v-model="fisrt_name"></div>
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>computed</title> </head> <body> <div id="app"> <div> <!-- v-model vue进行数据双向绑定的指令 --> <label for="xing">姓:</label><input type="text" name="xing" v-model="fisrt_name"> </div> <div> <label for="ming">名:</label><input type="text" name="ming" v-model="last_name"> </div> <div> <!-- 通过插值表达式实现 --> <div>姓名: {{ fisrt_name + " " + last_name }} </div> <!-- 通过computed实现 --> <div>姓名: {{ full_name }} </div> <!-- 通过methods实现 --> <div>姓名: {{ full_name_bac() }} </div> </div> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> new Vue({ el: "#app", data: { fisrt_name: "", last_name: "", // full_name: "" }, // 一个变量依赖于多个变量 // 采用computed computed: { full_name: function () { // full_name对fisrt_name及last_name两个变量进行监听,两个值只有有一个变化,full_name就会随之变化,并且可以实时渲染到页面 return this.fisrt_name + " " + this.last_name; } }, methods: { full_name_bac: function () { return this.fisrt_name + " " + this.last_name; } } }) </script> </html>
5、监听 watch
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>watch</title> </head> <body> <div id="app"> <div> <label>姓名:</label> <input type="text" v-model="full_name"> </div> <p>姓: {{ first_name }} </p> <p>名: {{ last_name }} </p> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 多个变量依赖于一个变量, 对该变量进行监听 new Vue({ el: "#app", data: { full_name: "", first_name: "", last_name: "" }, // 监听full_name变量,通过full_name具体修改first_name,last_name watch: { full_name () { var fullName = this.full_name; console.log(fullName); this.first_name = fullName.split(" ")[0]; this.last_name = fullName.split(" ")[1]; } } }) </script> </html>
6、delimiters 修改插值表达式默认符号
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>delimiters</title> </head> <body> <div id="app"> {{ msg }} ${ msg } </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> new Vue({ el: '#app', data: { msg: 'message' }, delimiters: ['${', '}'] }) </script> </html>
7、生命周期钩子
表示一个VUE实例从创建到销毁的这个过程,将这个过程中的一些时间节点赋予了对应的钩子函数
钩子函数:满足特定条件被回调用的方法
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>生命周期钩子</title> </head> <body> <div id="app"> {{ msg }} </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> new Vue({ el: "#app", data: { msg: "message" }, beforeCreate () { console.log("实例刚刚创建"); console.log(this.msg); }, created () { console.log("实例创建成功, data, methods"); console.log(this.msg); } // 拿到需求 => 确定钩子函数 => 解决需求的逻辑代码块 }) </script> </html>
二、学习总结
vue简介 数据驱动的web渐进式框架 数据驱动(不直接操作DOM) 单页面应用(减少由加载页面产生的请求次数) 数据的双向绑定(数据间的实时动态渲染) 虚拟DOM 组件化开发,遵循MVVM设计模式 vue实例 实例 == 组件 el: 挂载点,一般采用id,vue控制html页面结构的连接点 -- #app data: 数据,为页面变量提供数据的,一般变量都需要初始化 -- {{}}: 插值表达式,可以包含变量已经表达式 methods: 方法,为页面提供逻辑的实现体 -- v-on:事件 computed: 计算,一个变量依赖于多个变量 -- 变量名: function () { return 变量的逻辑值 } watch: 监听,多个变量依赖于一个变量 -- 变量名: function () { 多个变量依赖于此变量的逻辑代码块 } delimiters: 修改插值表达式默认符号, ["${", "}"] {{}} => ${} 变量的取值 var app = new Vue({ el: "#app", data: { msg: "message" } }) app.msg app.$data.msg 生命周期钩子 在一个vue实例从创建到销毁的整个过程中一些时间节点的回调方法 课程内容 vue的指令 什么是vue的指令 vue指令有哪些,每个指令的用途 文本类操作的指令 条件指令 循环指令 涉及绑定的指令
1、文本类操作的指令
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>文本类指令</title> <style type="text/css"> p { line-height: 21px; background-color: orange } </style> </head> <body> <div id="app"> <!-- html全局属性语法: 全局属性名="属性值" --> <p v-bind:title="title" a="a" b="b">你是p</p> <!-- v-model也是对文本操作的指令,操作的是表单元素的value文本 --> <input type="text" v-model="msg"> <!-- 采用文本指令后,页面标签的内容由vue实例控制,原来用于表示标签的文本均会被替换 --> <p>{{ msg }}</p> <!-- eg:原文本会被msg替换 --> <p v-text='msg'>原文本</p> <!-- 可以解析带html标签的文本信息 --> <p v-html='msg'></p> <!-- v-once控制的标签只能被赋值一次 --> <p v-once>{{ msg }}</p> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 指令: 出现在html标签中可以被vue解析处理的全局属性 new Vue({ el: "#app", data: { title: "", msg: "message" } }) </script> </html>
2、解决页面闪烁
<div id="app" v-cloak>
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="js/vue-2.5.17.js"></script> <style type="text/css"> [v-cloak] { /*display: none;*/ } </style> </head> <body> <div id="app" v-cloak> {{ msg }} </div> </body> <!-- <script src="js/vue-2.5.17.js"></script> --> <script type="text/javascript"> new Vue({ el: "#app", data: { msg: "message" } }) </script> </html>
3、v-bind指令
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>v-bind</title> <style type="text/css"> .abc { background-color: red } </style> </head> <body> <div id="app"> <!-- v-bind: --> <!-- 该指令 绑定 的是属性(html标签的全局属性) --> <!-- 绑定后的属性的属性值可以由变量控制 --> <p v-bind:abc="abc"></p> <!-- 绑定后 操作单一变量 --> <p v-bind:title="t1">p1p1p1p1p1p1p1</p> <!-- 绑定后 操作普通字符串 --> <p v-bind:title="'t2'">p2p2p2p2p2p2p2</p> <!-- 多类名 单一变量操作 --> <p v-bind:class="t3">p3p3p3p3p3p3p3</p> <p v-bind:class="[t4, tt4]">p4p4p4p4p4p4</p> <!-- 绑定class的{}语法 {key: value} key就是实际的类名,value是该类名的显隐(true就是起作用,false就是不起作用) --> <p v-bind:class="{abc: false}">p5p5p5p5p5p5</p> <p v-bind:class="{abc: t5}" v-on:click="fn">p5p5p5p5p5p5</p> <!-- class的[] {} 结合使用 --> <!-- class的值为p6 pp6, t6 tt6是值为true|false的变量,控制p6 pp6是否起作用 --> <p v-bind:class="[{p6: t6}, {pp6: tt6}]">p6p6p6p6p6p6p6p6</p> <!-- v-bind操作class --> <!-- [a, b] a,b为变量,对其赋值的是class的具体值 --> <!-- eg: a:active b:red => class="active red" --> <!-- {a: b} a为class值, b为值为true|false的变量,控制a的显隐 --> <!-- eg: b:true => class="a" --> <!-- eg: b:false => class="" --> <!-- v-bind:指令可以简写 : --> <p :class="'simple'">简写</p> <!-- 操作style --> <!-- style一般都是多条样式 --> <div :style="div_style"></div> <div :style="{width: '100px', height: '100px', backgroundColor: 'blue'}"></div> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> new Vue({ el:"#app", data: { abc: "ABC", t1: "p1的title", t3: "p pp", t4: "p", tt4: "pp", t5: false, t6: true, tt6: true, div_style: { width: "200px", height: "200px", backgroundColor: "cyan" } }, methods: { fn () { this.t5 = !this.t5; } } }) </script> </html>
4、v-on事件
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>v-on指令</title> <style type="text/css"> p { width: 100px; height: 100px; background-color: orange } </style> </head> <body> <div id="app"> <!-- v-on: 指令 --> <!-- 简写: @ --> <!-- 绑定的是事件,操作的是事件对应的方法名 --> <p @click="fn1"></p> <!-- 直接绑定方法名,不会携带自定义参数,但回调时能取到事件参数ev --> <p @click="fn2"></p> <!-- 带()的方法绑定,只传自定义参数,回调时只能取到自定义参数,事件参数ev丢失 --> <p @click="fn3(10)"></p> <!-- 带()的方法绑定,传入自定义参数同时,显式传入事件$event,回调时可以取到自定义参数及事件参数ev --> <p @click="fn4($event, 10, 20)"></p> <p @click="fn5(10, $event, 20)"></p> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> new Vue({ el: "#app", methods: { fn1: function () { console.log("click event"); }, fn2 (ev) { console.log(ev); }, fn3 (num) { console.log(num); }, fn4 (ev, n1, n2) { console.log(ev); console.log(n1); console.log(n2); }, fn5 (n1, ev, n2) { console.log(ev); } } }) </script> </html>
5、v-mode指令
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>v-model</title> </head> <body> <div id="app"> <form action=""> <!-- 数据的双向绑定 --> <!-- v-model绑定的是value,所以省略 --> <input type="text" v-model="val1" name="usr"> <textarea v-model="val1"></textarea> <p v-text="val1"></p> <!-- 单一复选框 --> <!-- val2值为true|false的变量,控制单选框是否被选中 --> <!-- --> <input type="checkbox" v-model="val2" name="ck1"> <!-- val3值为自定义"选中"|"未选中",控制单选框是否被选中 --> <!-- 选中状态,提交给后台可以对应的value为on,为选中状态,不向后台提交value值 --> <input type="checkbox" v-model='val3' true-value="选中" false-value="未选中" name="ck2" /> <!-- 多复选框 --> <!-- 多个复选框的v-model绑定一个变量 --> <!-- 该变量为数组数据,存放的是复选框的value值(value值必须明确) --> <!-- 出现在数组中的value值对应的复选框默认为选中状态 --> <div> 篮球<input type="checkbox" value="lq" v-model="val4" name="ck3"> 足球<input type="checkbox" value="zq" v-model="val4" name="ck3"> 乒乓球<input type="checkbox" value="ppq" v-model="val4" name="ck3"> </div> <!-- 多单选框 --> <!-- 多个单选框的v-model绑定一个变量 --> <!-- 变量值为多个单选框中一个的value值,则该单选框为默认选中状态 --> <div> 男:<input type="radio" value="男" v-model='val5' name="sex" /> 女:<input type="radio" value="女" v-model='val5' name="sex" /> </div> <button type="submit">提交</button> </form> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> new Vue({ el: "#app", data: { val1: "", val2: false, val3: "选中", val4: ['lq', 'ppq'], val5: "女", } }) </script> </html>
6、条件渲染的指令
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>条件渲染</title> <script src="js/vue-2.5.17.js"></script> <style type="text/css"> .box { width: 200px; height: 200px; } .r {background-color: red} .o {background-color: orange} </style> <style type="text/css"> ul { margin: 0; padding: 0; list-style: none; } .wrap, .main { width: 500px; height: 240px; } li { float: left; background-color: #666; margin-right: 20px; } ul:after { content: ""; display: block; clear: both; } .red {background-color: red} .green {background-color: green} .blue {background-color: blue} </style> </head> <body> <div id="app"> <button @click="toggle">显隐切换</button> <!-- v-if --> <div class="box r" v-if="isShow"></div> <!-- v-show --> <div class="box o" v-show="isShow"></div> <!-- 1.条件渲染的值为true|false --> <!-- 2.true代表标签显示方式渲染 --> <!-- 3.false v-if不渲染到页面,v-show以display:none渲染到页面,但也不会显示 --> <!-- v-if v-else-if v-else --> <ul> <li @mouseover="changeWrap(0)">red</li> <li @mouseover="changeWrap(1)">green</li> <li @mouseover="changeWrap(2)">blue</li> </ul> <!-- red页面逻辑结构 --> <div class="wrap red" v-if="tag == 0" key="0">...</div> <!-- green页面逻辑结构 --> <div class="wrap green" v-else-if="tag == 1" key="1">...</div> <!-- blue页面逻辑结构 --> <div class="wrap blue" v-else key="2">...</div> <!-- v-if相关分支操作,在未显示情况下,是不会被渲染到页面中 --> <!-- 通过key全局属性操作后,渲染过的分支会建立key对应的缓存,提高下一次渲染速度 --> <ul> <li @mouseover="changeMain(0)">red</li> <li @mouseover="changeMain(1)">green</li> <li @mouseover="changeMain(2)">blue</li> </ul> <!-- red页面逻辑结构 --> <div class="main red" v-show="whoShow(0)">...</div> <!-- green页面逻辑结构 --> <div class="main green" v-show="whoShow(1)">...</div> <!-- blue页面逻辑结构 --> <div class="main blue" v-show="whoShow(2)">...</div> </div> </body> <script type="text/javascript"> new Vue({ el: "#app", data: { isShow: false, tag: 0, flag: 0 }, methods: { toggle () { this.isShow = !this.isShow; }, changeWrap (num) { this.tag = num; }, changeMain (num) { // this.flag num this.flag = num; }, whoShow (num) { // this.flag num return this.flag == num; } } }) </script> </html>
7、列表渲染指令
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>列表渲染</title> </head> <body> <div id="app"> <h1>{{ msg }}</h1> <!-- v-for="item in items" --> <!-- 遍历的对象: 数组[] 对象(字典){} --> <ul> <li>{{ list[0] }}</li> <li>{{ list[1] }}</li> <li>{{ list[2] }}</li> <li>{{ list[3] }}</li> <li>{{ list[4] }}</li> </ul> <!-- n为遍历的元素值 --> <ul> <li v-for="n in list">{{ n }}</li> </ul> <!-- 一般列表渲染需要建立缓存 --> <!-- 列表渲染是循环,需要赋值变量给key,使用key需要v-bind:处理 --> <!-- v-for变量数组[]时,接收两个值时,第一个为元素值,第二个为元素索引 --> <ul> <li v-for="(n, i) in list" :key="i">value:{{ n }} | index: {{ i }}</li> </ul> <ul> <li>{{ dic['name'] }}</li> <li>{{ dic.age }}</li> <li>{{ dic.gender }}</li> </ul> <!-- v-for变量对象{}时,接收三个值时,第一个为元素值,第二个为元素键,第三个为元素索引 --> <ul> <li v-for="(v, k, i) in dic" :key="k">value:{{ v }} | key:{{ k }} | index: {{ i }}</li> </ul> <!-- 遍历的嵌套 --> <div v-for="(person, index) in persons" :key="index" style="height: 21px;"> <div v-for="(v, k) in person" :key="k" style="float: left;">{{ k }} : {{ v }} </div> </div> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> new Vue({ el: "#app", data: { msg: "列表渲染", list: [1, 2, 3, 4, 5], dic: { name: '小VV', age: 88888, gender: '神' }, persons: [ {name: "zero", age: 8}, {name: "egon", age: 78}, {name: "liuXX", age: 77}, {name: "yXX", age: 38} ] } }) </script> </html>
8、todolist案列
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>todoList案例</title> </head> <body> <div id="app"> <div> <input type="text" v-model="val"> <button type="button" @click="submitMsg">提交</button> </div> <ul> <li v-for="(v, i) in list" :key="i" @click="removeMsg(i)">{{ v }}</li> </ul> {{ list }} </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> new Vue({ el: "#app", data: { val: "", list: [] }, methods: { submitMsg () { // 往list中添加input框中的value if (this.val) { this.list.push(this.val); this.val = "" } }, removeMsg(index) { this.list.splice(index, 1) } } }) </script> </html>
三、指令总结
vue 指令 文本操作指令 v-text <==> {{}} v-html v-once + {{}} 防止页面闪烁 v-cloak [v-cloak] { display: none; } 关键指令 v-bind: 操作的是全局属性,让属性可以绑定变量,简写 : :title :class => a(单一变量) | [a, b](两个变量) | {a: b}(b为布尔类型记得类a是否起作用) | [{a: aa}, {b: bb}] :style => {width: "200px", height: "200px"} :key => 通过唯一标识建立缓存 v-on: 操作的是事件,让事件可以绑定方法,绑定的方法可以不携带参数(方法名),也可以携带参数(方法名(参数)), 简写 @ @click="btnClick" @click="btnClick(10)" @click="btnClick($event, 10)" v-model 操作的是表单元素value值,可以完成数据的双向绑定 text v-model="val" checkbox 单一 v-model="bol" | 多个 value="lq|zq|ppq" v-model="val" val: ["lq"] radio value="male|famale" v-model="val" val: "male|famale" 条件渲染指令 v-show: 无论如何都渲染, display: block|none v-if: 显示时渲染,不显示时不渲染,可以通过key对其建立渲染缓存 v-if v-else-if v-else(条件可以省略) 条件可以直接绑定一个条件表达式 | 返回值为布尔类型的方法 列表渲染指令 v-for="item in items" items数据由vue实例的data提供,item为遍历items的元素值 数据可以为[] | {} v-for="(v, i) in []" v是元素值, i为元素索引 v-for="(v, k, i) in {}" v是元素值, k为元素键, i为元素索引 (键值对) 组件 vue实际开发的模式: 组件化开发 什么是组件 组件有哪些 组件间的通信
1、根组件
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>根组件</title> </head> <body> <p>app之上</p> <div id="app"> <h1>{{ msg }}</h1> </div> <p>app之下</p> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件) // 每个组件组件均拥有模板,template var app = new Vue({ // 根组件的模板就是挂载点 el: "#app", data : { msg: "根组件" }, // 根组件可以显式书写模板吗? 可以 // 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量 // 根组件如果不书写自身模板,那么模板就采用挂载点,如果显式书写模块,就会替换挂载点,但根组件必须拥有挂载点 template: "<div>显式模板</div>" }) // app.$template </script> </html>
2、局部组件
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>局部组件</title> <style type="text/css"> .sup { width: 100px; height: 100px; background-color: orange; } .sub { width: 100px; height: 100px; background-color: red; border-radius: 50% } </style> </head> <body> <div id="app"> <!-- 错误: html不区分大小写 --> <!-- <localTag></localTag> --> <!-- html中组件命名提倡-的链接语法 --> <!-- <local-tag></local-tag> --> <!-- 1 --> <!-- <localtag></localtag> <localtag></localtag> <localtag></localtag> --> <!-- 2 3 4 5 --> <local-tag></local-tag> <btn-tag></btn-tag> <btn-tag></btn-tag> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 如何定义一个局部组件 // 局部组件的语法规则 // 如何使用局部组件 // 为什么要使用局部组件(达到html+css+js代码块的复用) // 一个满足vue语法规则的对象就是一个组件 // 直接来定义这样的组件,用一个变量名来接收,就是创建了一个局部组件, // 变量名就是局部组件的组件名 // 通过组件名就可以使用该组件 // 局部组件要在父组件中使用,一定要提前在父组件中进行注册 // 语法规则 // 有自身模板template,有data/methods/computed/watch... var localTag = { template: "<div class='sup'><div class='sub'></div></div>" } var btnTag = { // template: "<div><button>按钮1</button><button>按钮2</button></div>" template: "<button @click='btnAction'>点击了{{ num }}下</button>", // data需要绑定方法,数据通过方法返回值进行处理,达到组件复用时,数据的私有化 data: function() { return { num: 0 } }, methods: { btnAction: function () { this.num++ } } } // 根组件 new Vue({ el: "#app", // 注册子组件 components: { // 1 // "localtag": localTag // 2 // "localTag": localTag // 3 // "local-tag": localTag // 4 // localTag: localTag // 5 ES6对象语法,key value写法相同,可以省略value localTag, btnTag, } }) </script> </html>
3、全局组件
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>全局组件</title> </head> <body> <div id="app"> <global-tag v-for="(o, i) in ls" :key="i"></global-tag> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 全局组件 // 用Vue.component("组件名", {})来创建全局组件 // 全局组件附属于Vue实例,可以不需要注册就可以使用 Vue.component("global-tag", { template: "<button @click='btnClick'>{{ n }}</button>", data () { return { n: 0 } }, methods: { btnClick () { this.n++ } } }) new Vue({ el: "#app", data: { ls: [0, 0, 0] } }) </script> </html>
4、父子组件和相互传递
1、父组件传递数据给子组件
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>父传子</title> </head> <body> <div id="app"> <local-tag :num="num" :sup_data="sup_data"></local-tag> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 父组件与子组件建立联系的关键点 // 同绑定属性的方式进行数据传输 // 1.给在父组件中出现的子组件名定义标签的全局属性 // 2.全局属性的值赋值为父组件的数据变量 // 3.在子组件内部,通过props拿到标签中的全局属性名 var localTag = { props: ['num', 'sup_data'], template: "<div @click='divActive'>{{ num }}</div>", methods: { divActive () { console.log(this.num); console.log(this.sup_data); } } } // 数据属于父组件,子组件来接收使用数据 new Vue({ el: "#app", components: { localTag }, data: { num: 10, sup_data: [1, 2, 3, 4, 5] } }) </script> </html>
2、子组件传递数据给父组件
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>子传父</title> </head> <body> <div id="app"> <global-tag @send_data="receive_data"></global-tag> {{ n }} </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 子传父: // 通过发生事件的方式进行数据传输 // 数据由子组件提供, 父组件通过事件的回调方法获取数据 // 发生数据的关键: $emit("事件名", ...args) Vue.component("global-tag", { template: "<div @click='divAction'>我是div</div>", data () { return { num: 10, arrList: [1, 2, 3, 4, 5] } }, methods: { divAction () { // 发生事件 // console.log("要发生事件,携带参数了"); this.$emit("send_data", this.num, this.arrList) } } }); new Vue({ el: "#app", data: { n: 0 }, methods: { receive_data (num, arrList) { console.log("接收到的数据:", num, arrList); this.n = num; } } }) </script> </html>
5、 todolist组件化
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>todoList案例</title> </head> <body> <div id="app"> <div> <input type="text" v-model="val"> <button type="button" @click="submitMsg">提交</button> </div> <ul> <!-- <li v-for="(v, i) in list" :key="i" @click="removeMsg(i)">{{ v }}</li> --> <todo-list v-for="(v, i) in list" :key="i" :v="v" :i="i" @delect_action="delect_action"></todo-list> </ul> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> Vue.component("todo-list", { template: "<li @click='delect_action'><span>第{{ i + 1 }}条: </span><span>{{ v }}</span></li>", props: ['v', 'i'], methods: { delect_action () { this.$emit("delect_action", this.i) } } }) new Vue({ el: "#app", data: { val: "", list: [] }, methods: { submitMsg () { // 往list中添加input框中的value if (this.val) { this.list.push(this.val); this.val = "" } }, delect_action(index) { this.list.splice(index, 1) } } }) </script> </html>