前端 => 页面
html: 页面架构
css: 样式布局
js:操作数据,页面行为(前后端交互)
jq:js的封装,及其方便的完成页面特效
vue:js的框架
1.数据驱动
2.数据的双向绑定
3.虚拟DOM
1 认识vue
2 引入vue
3 vue实例
4 实例生命周期钩子
5 视图常规操作
6 条件渲染
7 列表渲染
8 重要指令 v-bind v-on v-model
9 案列 todolist
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>vue导入</title> </head> <body> <div id="app"> <p title="普通p">p标签</p> <!-- v-bind vue的指令,可以被vue解析并处理 --> <!-- 第一个title:html标签的属性名(系统预定义的) --> <!-- 第二个titile:vue的变量 --> <p v-bind:title='title'>p标签</p> </div> </body> <!-- 引入外部vue js --> <script type="text/javascript" src="./js/vue.js"></script> <!-- 自身 js --> <script type="text/javascript"> // 创建vue实例,需要一个对象参数 new Vue({ el: '#app', data: { title: 'vue p' } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue实例之el</title> </head> <body> <div id="root"></div> <!-- <p v-bind:class="title" v-on:dblclick='action' v-model='abc' v-for="it in its"></p> --> <p v-bind:title='title'>p标签</p> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> // el: vue实例的挂载目标 // 表示vue创建的该实例只对挂载点内部的模块进行处理 new Vue({ el: '#root', data: { title: 'vue p' } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue data</title> </head> <body> <div id="app"> <p>{{ msg }}</p> <!-- 出现在模块中的变量,一般都需要默认初始值 --> <p v-text='txt'></p> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el: '#app', // data为模块中的变量提供数据 data: { msg: 'vue 控制的 文本1', txt: 'vue 控制的 文本2', } }); console.log(app) // el | data 为 vue变量 => 以$开头,区别普通变量 console.log(app.$data) console.log(app.$data.msg) // 所有在模块中产生的变量,也可以通过vue的实例直接访问 console.log(app.msg) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue data</title> <style type="text/css"> .p1 { width: 300px; height: 100px; border: 1px solid #333; } </style> </head> <body> <div id="app"> <!-- v-on指令用于绑定事件 --> <!-- 事件对应逻辑由vue实例的methods处理 --> <!-- 绑定的事件(函数)需不需要携带参数列表: 无=>无需传参 有=>需要传参 --> <!-- 需要操作事件(需要事件对象)无需传参,传参后会都是事件 --> <p class="p1" v-on:click='func'>{{ msg }}</p> <p class="p1" v-on:click='fn("zero", 88888)'>{{ msg }}</p> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { msg: 'vue context' }, methods: { func: function (obj) { // alert('呵呵') // this: vue实例 => app // alert(this.msg) console.log(obj) }, fn: function (name, salary) { console.log(name) console.log(salary) } } }); </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>computed</title> </head> <body> <div id="app"> <div> 姓:<input type="text" v-model='first_name' /> </div> <div> 名:<input type="text" v-model='last_name' /> </div> <!-- <p>姓名:{{ full_name() }}</p> --> <!-- 采用计算方式的变量可以不在data中赋初值 --> <p>姓名:{{ full_name }}</p> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { first_name: '', last_name: '' }, // methods: { // full_name: function () { // return this.first_name + " " + this.last_name; // } // }, // 一个变量依赖于多个变量,一般对该变量采用计算处理 computed: { full_name: function () { return this.first_name + " " + this.last_name; } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>computed</title> </head> <body> <div id="app"> <div> 姓名:<input type="text" v-model='full_name' placeholder="姓与名以空格隔开" /> </div> <p>姓:{{ first_name }}</p> <p>名:{{ last_name }}</p> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { full_name: '', first_name: '', last_name: '' }, watch: { full_name: function () { // 监听full_name,然后拆分为姓与名 var fname = this.full_name; var arr = fname.split(' '); this.first_name = arr[0]; this.last_name = arr[1]; } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>delimiters</title> </head> <body> <div id="app"> {{ msg }} [[ msg ]] ${ msg } </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { msg: '数据' }, // delimiters配置自定义绑定符号 // 值为拥有两个元素的数组,元素为字符串形式 delimiters: ['${', '}'] }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>生命周期钩子</title> </head> <body> <div id="app"> {{ msg }} </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { msg: '数据' }, // 该钩子方法触发:vue实例刚被创建(只拥有内存位置),其他任何操作都未执行 // 就满足的beforeCreate钩子的触发条件,系统就会回调该方法的实现 // 用户在该触发条件情况下想去完成某些逻辑,那么就去实现该钩子 beforeCreate: function () { }, /* // 系统内部调用 if (beforeCreate) { beforeCreate() } // ... // ... if (created) { created() } if (beforeMount) { beforeMount() } // ... */ // 数据与事件加载完毕,el并没有进行挂载 created: function () { // 获取想要的数据(请求后台) // 事件的解绑或换绑或重新绑定 // 对虚拟DOM进行修改 }, // DOM树加载完毕,el渲染完毕 mounted:function () { // 可能需要对DOM进行操作(交给模块处理) } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>视图</title> <style type="text/css"> p { border: 1px solid #ff6700; height: 30px; line-height: 30px; } .abc { border-color: yellowgreen; } [class] { border-width: 5px; } [v-cloak] { display: none; } </style> <script type="text/javascript" src="js/vue.js"></script> </head> <body> <!-- <div id="app" v-cloak> --> <div id="app"> <!-- v-model实现数据的双向绑定 --> <input type="text" v-model='msg'> <input type="text" v-model='msg'> <p>{{ msg }}</p> <p v-text='msg'></p> <!-- 只赋值一次 --> <p v-once>{{ msg }}</p> <!-- 可以解析html语法的标签 --> <p v-html='msg'></p> <!-- 属性的绑定:属性值有变量控制 v-bind:属性名 :属性名 --> <!-- <p class="active"></p> --> <!-- <p v-bind:class='active'></p> --> <p :class='active'></p> <!-- 事件的绑定:事件值为函数名(带或不带参数列表) v-on:事件名 @事件名 --> <p @dblclick='func'></p> </div> </body> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { msg: '初值', active: 'abc' }, methods: { func: function () { alert('呵呵') } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主要指令v-bind</title> <script type="text/javascript" src="js/vue.js"></script> <style type="text/css"> .a { background-color: red; } .b { color: green; } </style> </head> <body> <div id="app"> <!-- v-bind:绑定系统预定义属性 --> <!-- 字符串abc --> <p title="abc">p段落</p> <!-- 1、变量abc,需要初始化 --> <p v-bind:title="abc">p段落</p> <!-- 2、如何直接将abc作为字符串绑定到属性 --> <p v-bind:title="'abc'">p段落</p> <!-- 3、v-bind简写为: --> <p :title="'ABC'">p段落</p> <!-- 4、绑定多个变量 --> <!-- i:以数组形式进行赋值 --> <!-- a, b为两个变量 --> <!-- 变量值可以有data提供 --> <!-- <div :class="[a, b]">12345</div> --> <!-- ii:以对象形式进行赋值 --> <!-- a,b为两个class值 --> <!-- class值只取true | false --> <!-- 非空均视为true,否则视为false --> <!-- <div :class="{a: 'A', b: 'B'}">67890</div> --> <!-- <div :class="{a: true, b: true}">67890</div> --> <!-- iii --> <div :class="[{a: true}, {b: true}]">呵呵嘻嘻哈哈</div> <!-- 总结 --> <!-- [], 中出现的值,作为变量,变量值来源于data,且最终将来源于data的数据作为属性值赋值给v-bind绑定的属性 --> <!-- {}, 中出现的键(key),直接作为v-bind绑定的属性的值,而键(key)对应的值(value)是决定键是否起效,值(value)的取值只为true|false --> <a :style="color" href="">百度</a> <a :style="{color: 'red', backgroundColor: 'black'}" href="">京东</a> </div> </body> <script type="text/javascript"> new Vue({ el: '#app', data: { abc: 'ABC', a: 'a', b: 'b', // color: 'color: red' color: { color: 'red', // 支持驼峰命名法 backgroundColor: 'orange' } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主要指令v-on</title> <script type="text/javascript" src="js/vue.js"></script> <style type="text/css"> </style> </head> <body> <div id="app"> <!-- 1、绑定系统预定义事件,事件值为函数 --> <div v-on:click="fn1">{{ msg }}</div> <!-- 2、v-on简写 --> <div @click="fn2">{{ msg }}</div> <!-- 3、传值 -- 默认传值 -- 事件 event --> <div @click='fn3'>{{ msg }}</div> <!-- 4、传值 -- 自定义值 --> <div @click="fn4(msg, 88888)">{{ msg }}</div> <!-- 5、传参 -- 自定义值 + 事件 --> <div @click="fn5($event, msg)">{{ msg }}</div> </div> </body> <script type="text/javascript"> new Vue({ el: '#app', data: { msg: '默认值' }, methods: { fn1: function () { alert('呵呵') }, fn2 () { alert('嘻嘻') }, fn3 (obj) { console.log(obj) }, fn4 (obj, num) { console.log(obj, num) console.log(this.msg) }, fn5 (ev, msg) { console.log(ev, msg) } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主要指令v-model</title> <script type="text/javascript" src="js/vue.js"></script> <style type="text/css"> </style> </head> <body> <div id="app"> <!-- v-model针对于表单元素 --> <form action="" method="get"> <!-- 1、双向绑定:服务于文本输入框 --> <!-- v-model存储的值为输入框的value值 --> <div> <input type="text" name="usr" v-model="in_val"> <input type="password" name="ps" v-model="in_val" > <textarea name="info" v-model="in_val"></textarea> </div> <!-- 2、单选框 --> <div> <!-- 单选框是以name进行分组,同组中只能发生单选 --> <!-- v-model存储的值为单选框的value值 --> 男:<input type="radio" name="sex" value="男" v-model="ra_val"> 女:<input type="radio" name="sex" value="女" v-model="ra_val"> {{ ra_val }} </div> <!-- 3、单一复选框 --> <!-- v-model存储的值为true|false --> <!-- 或者为自定义替换的值 --> <div> <input type="checkbox" v-model='sin_val' true-value="选中" false-value="未选中" /> {{ sin_val }} </div> <!-- 4、多复选框 --> <!-- v-model存储的值为存储值多复选框value的数组 --> <div> <input type="checkbox" value="喜好男的" name="cless" v-model='more_val' /> <input type="checkbox" value="喜好女的" name="cless" v-model='more_val' /> <input type="checkbox" value="不挑" name="cless" v-model='more_val' /> {{ more_val }} </div> <input type="submit"> </form> </div> </body> <script type="text/javascript"> new Vue({ el: '#app', data: { in_val: '', // 默认值可以决定单选框默认选项 ra_val: '男', // 默认值为true,单一复选框为选中,反之false为不选中 sin_val: '', // 数组中存在的值对应的复选框默认为选中状态 more_val: ['喜好女的','不挑'] } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>条件渲染</title> <script type="text/javascript" src="js/vue.js"></script> <style type="text/css"> .box { width: 200px; height: 200px; background-color: red; border-radius: 50%; } .bb { width: 50px; height: 50px; border: 1px solid black; border-radius: 50%; font: 400 20px/50px 'STSong'; text-align: center; user-select: none; float: left; margin-left: 20px; } .wrap:after { content: ''; display: block; clear: both; } .a { width: 300px; height: 200px; } .r {background: red} .g {background: green} .b {background: blue} </style> </head> <body> <div id="app"> <button @click="btnClick">切换</button> <!-- 1、v-if取值为true|false --> <!-- true将会被渲染|false不会被渲染(页面中不存在该标签) --> <!-- <div class="box" v-if="isShow"></div> --> <!-- 2、v-show取值为true|false --> <!-- true为渲染并显示,false虽然渲染到DOM上,但display以none形式存在 --> <div class="box" v-show='false'></div> <!-- 3、v-if、v-else-if、v-else --> <!-- 多分支条件 --> <div class="wrap"> <!-- .bb.b$*3 --> <div class="bb b1" @click='changeColor(0)'>红</div> <div class="bb b2" @click='changeColor(1)'>绿</div> <div class="bb b3" @click='changeColor(2)'>蓝</div> </div> <div> <!-- 多分支一定存在判断,判断便会产生比较变量 --> <div class="r a" v-if='tag == 0'></div> <div class="g a" v-else-if='tag == 1'></div> <div class="b a" v-else></div> </div> </div> </body> <script type="text/javascript"> new Vue({ el: '#app', data: { isShow: false, tag: 0 }, methods: { // 通过方法控制绑定给v-if的值 btnClick: function () { this.isShow = !this.isShow; }, changeColor (num) { this.tag = num; } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>列表渲染</title> <script type="text/javascript" src="js/vue.js"></script> </head> <body> <div id="app"> <ul> <li>{{list[0]}}</li> <li>{{list[1]}}</li> <li>{{list[2]}}</li> <li>{{list[3]}}</li> <li>{{list[4]}}</li> <li>{{list[5]}}</li> <li>{{list[6]}}</li> </ul> <!-- 迭代数组 --> <ul> <!-- 变量it为集合list中被迭代出的元素 --> <!-- 由v-for指令控制的标签会随元素的个数动态渲染 --> <li v-for='it in list'>{{ it }}</li> </ul> <!-- 迭代对象 --> <div v-for='value in dic'>{{ value }}</div> <!-- 迭代除取值外的其他可迭代到的值 --> <ul> <li v-for="(v, i) in list">索引:{{i}} 名字:{{v}}</li> </ul> <ul> <li v-for="(v, k, i) in dic">{{i}} {{k}} {{v}}</li> </ul> </div> </body> <script type="text/javascript"> new Vue({ el: '#app', data: { list: ["张三", "李四", "王五", "赵六", "钱七", "egon", "monkey"], dic: {'name': 'zero', 'age': 8, 'salary': 88888} } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>列表渲染</title> <script type="text/javascript" src="js/vue.js"></script> </head> <body> <!-- key属性:可以提高效率(通过不同的唯一key值建立缓存) --> <div id="app"> <div v-for='(item,index) in list' :key='index' style="height: 30px"> <div v-for='(value, key, index) in item' :key='index + 10' style="float: left;"> {{key}} : {{value}} </div> </div> </div> </body> <script type="text/javascript"> new Vue({ el: '#app', data: { list: [ {'name': 'egon', 'age': 108}, {'name': 'monkey', 'age': 77}, {'name': 'zero', 'age': 8} ] } }) // items: [{'name': '张三'}, {'age': 18}, {'sex': '男'}] // 通过[索引]取出数组中对应的值 // 通过.key取出对象中对应的值 </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>todoList</title> <script type="text/javascript" src="js/vue.js"></script> </head> <body> <!-- 录入用户输入的数据,更新到指定的list中,通过vue的数据驱动特效,实时渲染到页面 --> <div id="app"> <div> <input type="text" v-model='value'> <!-- 提交:将数据添加到list中 --> <button @click='pushAction'>提交</button> </div> <ul> <!-- 点击指定的li,将自身数据从list中移除,完成自身删除 --> <li @click='deleteAction(index)' v-for='(item,index) in list' :key="index">{{ item }}</li> </ul> </div> </body> <script type="text/javascript"> new Vue({ el: '#app', // vue目前不支持索引直接操作数据,但可以通过数据类型对应的操作方法 data: { value: '', list: [] }, methods: { pushAction () { this.list.push(this.value); this.value = '' }, deleteAction (index) { // alert(index) this.list.splice(index, 1) } } }) </script> </html>
一: 认识vue
优点:
1、可以完全通过客户端浏览器渲染页面,服务器端只提供数据
2、方便构建单页面应用程序(SPA)
四: 实例生命周期钩子
定义:
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
钩子方法:
beforeCreate:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created:在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount:在挂载开始之前被调用:相关的 render 函数首次被调用。
mounted:el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。
beforeUpdate:数据更新时调用,发生在虚拟 DOM 打补丁之前。
updated:数据更新时调用,发生在虚拟 DOM 打补丁之前。
activated:keep-alive 组件激活时调用。
deactivated:keep-alive 组件停用时调用。
beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed:Vue实例销毁后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
errorCaptured:2.5.0+ 新增,当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
重点钩子:
created:实例完全创建完毕(属性与方法都准备就绪)。可以进行数据操作(请求后台数据,重新渲染最新数据)
mounted:虚拟DOM构建完毕,并完成实例的el挂载。可以重新操作页面DOM
6 条件渲染 v-if v-show
v-if:值true会被渲染,值false不会被渲染
<div id="app"> <div v-if='isShow'>div div div</div> <button @click='isShow = !isShow'>改变</button> </div> <script> new Vue({ el: '#app', data: { isShow: true } }) </script>
v-else:与v-if结合使用形成对立面
<div id="app"> <div v-if='isShow'>div div div</div> <div v-else='isShow'>DIV DIV DIV</div> <button @click='isShow = !isShow'>改变</button> </div> <script> new Vue({ el: '#app', data: { isShow: true } }) </script>
v-else-if:变量的多情况值判断
<div id="app"> <div v-if='tag == 0'>if if if</div> <div v-else-if='tag == 1'>else if else</div> <div v-else='tag == 2'>else else else</div> <input type='number' min='0' max='2' v-model='tag' /> </div> <script> new Vue({ el: '#app', data: { tag: 0 } }) </script>
template:不被渲染的vue结构标签
<template v-if="isShow"> <p>用template嵌套</p> <p>可以为多行文本</p> <p>同时显隐</p> <p>且template标签不会被vue渲染到页面</p> </template>
v-show:一定会被渲染到页面,以display属性控制显隐
key:为v-if方式的显隐创建缓存,提高效率
<div id="app"> <div v-if='tag == 0' key='0'>if if if</div> <div v-else-if='tag == 1' key='1'>else if else</div> <div v-else='tag == 2' key='2'>else else else</div> <input type='number' min='0' max='2' v-model='tag' /> </div> <script> new Vue({ el: '#app', data: { tag: 0 } }) </script>
7 列表渲染 v-for
v-for:循环渲染列表
<div id="app"> <ul> <li v-for='item in items'>{{ item }}</li> </ul> <button @click='click'>改变</button> </div> <script> new Vue({ el: '#app', data: { items: ['张三', '李四', '王五'] }, methods: { click: function () { this.items.splice(1, 1, '李大大'); this.items.pop(); this.items.push('赵六') } } }) </script>
遍历数组
// items: ['张三', '李四', '王五'] // 值 <ul> <li v-for='item in items'>{{ item }}</li> </ul> // 值, 索引 <ul> <li v-for='(item, index) in items'>{{ index }} - {{ item }}</li> </ul>
遍历对象
// {'name': '张三', 'age': 18, 'sex': '男'} // 值 <div v-for="value in object"> {{ value }} </div> // 值, 键 <div v-for="(value, key) in object"> {{ key }}: {{ value }} </div> // 值, 键, 索引 <div v-for="(value, key, index) in object"> {{ index }}. {{ key }}: {{ value }} </div>
复杂数据渲染
// items: [{'name': '张三'}, {'age': 18}, {'sex': '男'}] <div> <div>{{ items[0].name }}</div> <div>{{ items[1].age }}</div> <div>{{ items[2].sex }}</div> </div>
8 重要指令 v-bind v-on v-model
v-bind
<!-- 值a --> <div v-bind:class='"a"'></div> <!-- 变量a --> <div v-bind:class='a'></div> <!-- 变量a, b --> <div v-bind:class='[a, b]'></div> <!-- a为class值,isA决定a是否存在(ture | false) --> <div v-bind:class='{a: isA}'></div> <!-- 多class值,是否存在 --> <div v-bind:class='{a: isA, b: isB}'></div> <!-- 多style值,my_color为变量,cyan为普通值 --> <div :style='{color:my_color, background:"cyan"}'></div>
v-on
<!-- 绑定函数fn1,并将事件event传递过去 --> <div v-on:click='fn1'></div> <!-- 绑定函数fn2,并将自定义参数10传递过去 --> <div v-on:click='fn2(10)'></div> <!-- 绑定函数fn3,并将事件event与自定义参数10传递过去 --> <div v-on:click='fn2($event, 10)'></div>
v-model
<!-- 文本输入框:数据的双向绑定 --> <input type="text" v-model='val' /> <textarea v-model='val'></textarea> <!-- 单个复选框:选中与否val默认值为true|false --> <input type="checkbox" v-model='val' /> <!-- 通过true-value|false-value修改默认值为true|false --> <input type="checkbox" v-model='val' true-value="选中" false-value="未选中" /> <!-- 多个复选框:val作为数组[]来使用,可以存储选中元素的value值,反之数组有对应value代表该选框选中 --> <input type="checkbox" value="男" v-model='val' /> <input type="checkbox" value="女" v-model='val' /> <!-- 单选框:val存储选中的单选框的value值 --> <input type="radio" value="男" v-model='val' /> <input type="radio" value="女" v-model='val' />
9 案列
v-show
<style type="text/css"> .btn_wrap { width: 660px; margin: 0 auto; } .btn_wrap:after { content: ''; display: block; clear: both; } .btn { width: 200px; height: 40px; border-radius: 5px; float: left; margin: 0 10px 0; } .box { width: 660px; height: 300px; } .b1 {background-color: red} .b2 {background-color: orange} .b3 {background-color: cyan} .box_wrap { width: 660px; margin: 10px auto; } </style> <div id="app"> <div class="btn_wrap"> <div class="btn b1" @click='setTag(0)'></div> <div class="btn b2" @click='setTag(1)'></div> <div class="btn b3" @click='setTag(2)'></div> </div> <div class="box_wrap"> <div class="box b1" v-show='isShow(0)'></div> <div class="box b2" v-show='isShow(1)'></div> <div class="box b3" v-show='isShow(2)'></div> </div> </div> <script type="text/javascript"> new Vue({ el: '#app', data: { tag: 0 }, methods: { isShow (index) { return this.tag === index; }, setTag (index) { this.tag = index; } } }) </script>
v-for
<div id="app"> <div> <input type="text" v-model="inValue"> <button @click='pushAction'>提交</button> </div> <ul> <li @click='deleteAction(index)' v-for="(item, index) in list" :key="index">{{ item }}</li> </ul> </div> <script type="text/javascript"> new Vue({ el: '#app', data: { inValue: '', list: [] }, methods: { pushAction: function () { this.list.push(this.inValue); this.inValue = '' }, deleteAction: function (index) { this.list.splice(index, 1); } } }) </script>
一 组件介绍
二 局部组件
三 全局组件
四 父组件传递数据给子组件
五 子组件传递数据给父组件
六 父子组件实现todolist
七 搭建vue开发环境
1 安装nodejs
2 安装脚手架
3 项目创建
4 vue基础模板
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>局部组件</title> <script type="text/javascript" src="js/vue.js"></script> </head> <body> <div id="app"> <!-- 错的 --> <!-- <localTag></localTag> --> <!-- ① --> <!-- <localtag></localtag> --> <!-- ② ③ ④ ⑤ --> <local-tag></local-tag> <local-tag></local-tag> <!-- 总结:组件与html公用的名称(组件名、方法名、变量名),不要出现大写,提倡使用-语法 --> </div> </body> <script type="text/javascript"> // 创建局部组件:就是一个拥有模板(满足vue写法)的对象 var localTag = { // 模板 // 错误: 只能解析第一个标签,以它作为根标签 // template: '<div>局部组件1</div><div>局部组件2</div>' template: ' <div> <div>局部组件1</div> <div>局部组件2</div> </div>' } // 局部组件需要被使用它的父组件注册才能在父组件中使用 // 模板: html代码块 // 根组件,拥有模板,可以显式的方式来书写template,一般不提倡,模板就是挂载点及内部所有内容 // 注:挂载点内部一般不书写任何内容 new Vue({ el: '#app', // old // template: '<div></div>' // new // 用components进行组件的注册 // ① // components: { // 'localtag': localTag // } // ② // components: { // 'local-tag': localTag // } // ③ // components: { // 'localTag': localTag // } // ④ components: { 'LocalTag': localTag } // ⑤ // ES6 key与value一直,可以单独写key // components: { // localTag // } }) </script> </html>
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>全局组件</title> <script type="text/javascript" src="js/vue.js"></script> </head> <body> <div id="app"> <global-tag></global-tag> <global-tag></global-tag> </div> </body> <script type="text/javascript"> // 创建全局组件: 组件名, {template:''} Vue.component('global-tag', { // data: function () { // return { // num: 0 // } // }, data () { return { num: 0 } }, template: '<button @click="btnClick">点击了{{num}}下</button>', methods: { btnClick () { console.log("你丫点我了!!!"); this.num ++ } } }) new Vue({ el: '#app', data: { } }) </script> </html>
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>父传子</title> <script type="text/javascript" src="js/vue.js"></script> </head> <body> <div id="app"> <!-- 通过属性绑定的方式 --> <!-- <global-tag v-bind:abc='sup_d1' :supD2='sup_d2'></global-tag> --> <global-tag v-bind:abc='sup_d1' :sup_d2='sup_d2'></global-tag> <!-- 模板名用-连接命名,属性名用_连接命名 --> </div> </body> <script type="text/javascript"> // 子组件需要接受数据 Vue.component('global-tag', { // 通过props来接收绑定数据的属性 // props: ['abc', 'supd2'], props: ['abc', 'sup_d2'], // template: '<div><p @click="fn">{{ abc }}</p></div>', template: '<div><p @click="fn(abc)">{{ abc }}</p></div>', methods: { // fn () { // alert(this.abc) // } fn (obj) { console.log(obj, this.sup_d2) } } }) // 数据是父组件的 new Vue({ el: '#app', data: { sup_d1: "普通字符串", sup_d2: [1, 2, 3, 4, 5] } }) </script> </html>
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>子传父</title> <script type="text/javascript" src="js/vue.js"></script> </head> <body> <div id="app"> <!-- 通过发送事件请求的方式进行数据传递(数据作为请求事件的参数) --> <global-tag @send_data='receiveData'></global-tag> <p>{{ msg }}</p> </div> </body> <script type="text/javascript"> Vue.component('global-tag', { data () { return { sub_v1: '普通字符串', sub_v2: [1, 2, 3, 4, 5] } }, template: '<button @click="btnClick">发送</button>', methods: { btnClick () { console.log("子>>> ", this.sub_v1, this.sub_v2); // 通过emit方法将数据已指定的事件发生出去 // 事件名, 参数... this.$emit("send_data", this.sub_v1, this.sub_v2) } } }) // 数据是父组件的 new Vue({ el: '#app', data: { msg: '' }, methods: { receiveData(obj1, obj2) { console.log("父>>> ", obj1, obj2) this.msg = obj2; } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>组件todoList</title> <script type="text/javascript" src="js/vue.js"></script> </head> <body> <div id="app"> <div> <input type="text" v-model='in_val'> <button @click='pushAction'>提交</button> </div> <!-- <ul> <li @click='deleteAction(index)' v-for='(item,index) in list' :key="index">{{ item }}</li> </ul> --> <!-- 父 将list传输给 子 --> <todo-list :list_data='list' @delete_action='deleteAction'></todo-list> </div> </body> <script type="text/javascript"> Vue.component('todo-list', { props: ['list_data'], template: '<ul><li v-for="(e, i) in list_data" :key="i" @click="li_action(i)">{{e}}</li></ul>', methods: { li_action (index) { // 子 反馈index给 父 this.$emit('delete_action', index); } } }) new Vue({ el: '#app', data: { in_val: '', list: [] }, methods: { pushAction () { this.list.push(this.in_val); this.in_val = '' }, deleteAction (index) { this.list.splice(index, 1); } } }) </script> </html>
一 组件介绍
-
-
每个组件均具有自身的模板template,根组件的模板就是挂载点
-
每个组件模板只能拥有一个根标签
-
子组件的数据具有作用域,以达到组件的复用
二 局部组件
<div id="app"> <local-tag></local-tag> <local-tag></local-tag> </div> <script> var localTag = { data () { return { count: 0 } }, template: '<button @click="btnAction">局部{{ count }}</button>', methods: { btnAction () { this.count ++ } } } new Vue({ el: "#app", components: { 'local-tag': localTag } }) </script>
三 全局组件
<div id="app"> <global-tag></global-tag> <global-tag></global-tag> </div> <script> Vue.component('global-tag', { data () { return { count: 0 } }, template: '<button @click="btnAction">全局{{ count }}</button>', methods: { btnAction () { this.count ++ } } }) new Vue({ el: "#app" }) </script>
四 父组件传递数据给子组件
通过绑定属性的方式进行数据传递
<div id="app"> <global-tag :sup_data1='sup_data1' :supData2='sup_data2'></global-tag> </div> <script type="text/javascript"> Vue.component('global-tag', { props:['sup_data1', 'supdata2'], template: '<div>{{ sup_data1 }} {{ supdata2 }}</div>' }) new Vue({ el: '#app', data: { sup_data1: '数据1', sup_data2: '数据2' } }) </script>
五 子组件传递数据给父组件
通过发送事件请求的方式进行数据传递
<div id="app"> <global-tag @send_action='receiveAction'></global-tag> </div> <script type="text/javascript"> Vue.component('global-tag', { data () { return { sub_data1: "数据1", sub_data2: '数据2' } }, template: '<div @click="clickAction">发生</div>', methods: { clickAction () { this.$emit('send_action', this.sub_data1, this.sub_data2) } } }) new Vue({ el: '#app', methods: { receiveAction (v1, v2) { console.log(v1, v2) } } }) </script>
六 父子组件实现todolist
<div id="app"> <div> <input type="text" v-model='value'> <button @click='click'>提交</button> </div> <ul> <item v-for='(e, i) in list' :key='i' :ele='e' :index='i' @delete='deleteAction' ></item> </ul> </div> <script type="text/javascript"> Vue.component('item', { props: ['ele', 'index'], template: '<li @click="item_click">{{ ele }}</li>', methods: { item_click: function () { this.$emit('delete', this.index) } } }) new Vue({ el: '#app', data: { value: '', list: [], }, methods: { click: function () { this.list.push(this.value) this.value = '' }, deleteAction: function (index) { this.list.splice(index, 1) } } }) </script>
七 搭建vue开发环境
1 安装nodejs
官网下载安装:https://nodejs.org/zh-cn/
2 安装脚手架
安装全局vue:npm install -g @vue/cli
在指定目录创建vue项目:vue create my-project
进入项目目录启动项目:npm run serve
通过指定服务器路径访问项目页面:http://localhost:8080/
3 项目创建
babel:是一个 JavaScript 编译器。
eslint:是一个语法规则和代码风格的检查工具,可以用来保证写出语法正确、风格统一的代码。
4 vue基础模板
<template> </template> <script> export default { } </script> <style scoped> </style>