一.Vue简介
前端框架:Angular,React,Vue
Vue是前端框架,它结合了前两个框架的优点:轻量级、中文API、数据驱动、双向绑定、MVVM设计模式、组件化开发、单页面应用
''' 轻量级:压缩之后只有20KB大小 中文API:开发者是中国人,开发文档也是中文,对国人友好,简单易学 数据驱动、双向绑定、MVVM:响应式数据绑定,数据驱动视图,自动的对视图中某些数据的改变做出同步的响应 组件化开发:将一个页面拆分成一个个模块(标签),通过对一个个标签传入指定的参数,从而控制整体的页面 单页面应用:不需要重复渲染页面,跳转同级页面只需要修改其中的数据即可,运行速度更快 '''
Vue开发环境:可以是本地导入,也可以是cdn导入
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue的导入</title> </head> <body> <div class="main"> 123 {{ }} abc </div> </body> <script src="js/vue.js">// 直接导入 </script> <!--<script src="https://cn.vuejs.org/js/vue.js">// cdn导入 </script>--> <script> new Vue({ el: '.main' }) </script> </html>
Vue是js渐进式框架
根据开发需求,可以决定Vue框架控制项目的具体方位:可以为一个标签,也可以为一个页面,甚至可以为整个项目
二.实例成员
1.挂载点
vue如何与html页面结构建立关联:挂载点
... 1.html与body不能作为挂载点 2.一个vue对象挂载点只会匹配一个结果,使用类选择器也只会匹配该类的第一个结果,所以挂载点一般使用id 3.如果想要操作整个页面,不能使用body,但是我们可以将整个页面包在一个div标签内,再使用挂载点匹配该标签 ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>挂载点</title> </head> <body> <div class="d1"> 123 {{ }} 456 </div> <hr> <div class="d1"> 123 {{ }} 456 </div> <script src="js/vue.js"></script> <script> new Vue({ el:'.d1' }) </script> </body> </html>
当使用html或者body作为挂载点时会报错
<script> new Vue({ el:'body' }) </script>
通过body下包裹所有的div标签操作页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>挂载点</title> </head> <body> <div id="d"> <p>{{ }}</p> <hr> <div id="d1"> 123 {{ }} 456 </div> <hr> <div id="d2"> 123 {{ }} 456 </div> </div> <script src="js/vue.js"></script> <script> new Vue({ el:'#d' // 可以通过body下包裹一个大的div标签来操作整个页面 }) </script> </body> </html>
js对象(字典)补充
let b = 123;
let dic = {
a : 10, // 字典中的key都是字符串,可以省略引号
// b : b
b // 当一个变量名作为值,并且这个变量名和字典的key同名时,可以简写
};
console.log(dic)
2.数据
通过data为vue提供数据
... 1.用实例成员data为vue环境提供数据,数据采用字典{}的形式 2.在插值表达式{{ }}中,直接书写数据的key来访问数据 3.在外部通过接受实例的变量app,访问实例成员,间接访问到数据 实例成员都是用$开头,比如:app.$data.info 4.在外部也可以直接通过变量访问到数据 比如:app.info 5.在vue实例内部的方法methods中,可以使用变量this.info ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>数据</title> </head> <body> <div id="app"> <p>{{ info }}</p> <p>{{ num }}</p> <p>{{ res }}</p> <p>{{ arr }}</p> <p>{{ dic }}</p> </div> <script src="js/vue.js"></script> <script> let app = new Vue({ el:'#app', data:{ info:'vue对象中实例成员的数据', num:156, res:true, arr: [1,2,3,4,5], dic: { name: 'sxc', age: 18, } } }) </script> <script> console.log(app); console.log(app.$data.info); console.log(app.info) </script> </body> </html>
3.过滤器
... 1.插值表达式本身可以直接做简单运算 2.过滤器本身就是数据处理函数,可以将插值表达式中的数据作为参数进行处理,得到的函数返回值就是处理后的结果 3.过滤器在插值表达式中的使用语法{{ 变量... | 过滤器名(变量...) }} 4.过滤器在实例中用filters成员提供 ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>过滤器</title> </head> <body> <div id="app"> <p>{{ num + 50 }}</p> <p>{{ num|f1 }}</p> <p>{{ num|f2 }}</p> <p>{{ 10,20,30,40|f3 }}</p> <!--过滤器传多个值的方式有多种--> <p>{{ 10|f3(20,65,79) }}</p> </div> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { num: 100 }, filters: { f1: function () { return '哈哈哈哈' }, f2: function (num) { return num*num }, f3: function (a,b,c,d) { return a+b+c+d } } }) </script> </body> </html>
4.插值表达式符号的更改(了解)
插值表达式的符号是{{ }},而django的模板语言也是{{ }},这样两者就很容易引起混淆,所以引入了插值符号的更改,使用delimiters更改符号
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <p>{{ msg }}</p> <p>{[ msg ]}</p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data:{ msg: 'hahha' }, delimiters:['{[',']}'] // 改变符号 }) </script> </html>
三.指令相关
1.文本指令
... 1.v-text文本指令和插值表达式一样可以渲染普通文本 2.v-html指令可以渲染有html语法的文本,能够解析html语法 3.文本指令中可以渲染变量,也能渲染常量 ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文本指令</title> </head> <body> <div id="app"> <p>{{ msg }}</p> <p v-text="msg"></p> <p v-text="123"></p> <p v-text="true"></p> <p v-text="[1,2,3]"></p> <p v-text="'lalala' + msg"></p> <p v-html="`<b style='color:red'>哈哈哈</b>`"></p> <p v-text="'<b>哈哈哈</b>'"></p> </div> <script src="https://cn.vuejs.org/js/vue.js"></script> <script> new Vue({ el: '#app', data:{ msg: 'hahaha' } }) </script> </body> </html>
反引号补充
... 1.js多行字符串,使用`` 2.反引号字符串中可以直接填充个变量,语法:`${变量名}` ...
<script> let s1 = ` 第一行 第二行 结束行 `; console.log(s1); let name = 'sxc'; let age = 18; let s2 = ` name: ${name} age: ${age} `; console.log(s2); </script>
2.事件指令
... 1.语法:v-on:事件名="函数名(参数...)" 2.可以简写:@事件名="函数名(参数...)" 3.用methods实例成员提供事件函数的实现 4.事件传参: @事件='方法' 默认传入事件对象 $event @事件='方法()' 不传递任何参数 @事件='方法(参数...)' 只传递自定义参数 @事件='方法($event, 参数...)' 自定义传参时传递事件对象 ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> body { user-select: none; } .low_num { cursor: pointer; } .low_num:hover { color: red; } </style> </head> <body> <div id="app"> <p class="low_num" v-on:click="lowNum"> <span>点击减一:{{ num }}</span> </p> <p @dblclick="dblAction">双击</p> <p @mouseover="overAction">悬浮</p> <p @mouseover="overAction()">悬浮1</p> <p @mouseover="overAction(1,2)">悬浮2</p> <p @mouseover="overAction(1,2,$event)">悬浮3</p> </div> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { num: 100 }, methods: { lowNum: function () { this.num-- }, dblAction(ev){ console.log(ev) }, overAction(a, b, c){ console.log(a, b, c) } } }) </script> </body> </html>
3.属性指令
... 1.语法:v-bind:属性名='变量' 2.v-bind:属性名='变量',简写:属性名='变量' 3.单值属性绑定: :title="变量" | :id="变量" | :自定义属性="变量" 4.style属性绑定: :style="字典变量" | :style="{css属性1:变量1, ..., css属性n:变量n}" 5.class属性绑定: :class="变量" | :class="[变量1, ..., 变量n]" | :calss="{类名:布尔变量}" ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> [index] { color: red; } .c1 { color: blue; } .ccc { color: orange; } .ccc1 { color: yellow; } .ccc2 { background-color: hotpink; } .ccc3{ border-radius: 50%; } .xxx{ background-color: rebeccapurple; } </style> </head> <body> <div id="app"> <p id="" class="" title="" index>属性指令1</p> <p v-bind:class="p1">属性指令2</p> <p v-bind:index="p1">自定义属性也可以被vue绑定</p> <!-- v-bind:属性名='变量值'可以简写为:属性名='变量值' --> <p :title="'文本显示'">属性指令可以简写</p> <!-- style样式属性绑定 --> <p :style="myStyle">style样式属性1</p> <p :style="{backgroundColor: 'pink', color: p2 ,borderRadius: p3}">style样式属性2</p> <!-- class类属性绑定 --> <p :class="c1">类属性绑定1</p> <p :class="[c2,c3,c4,'ppp']">类属性绑定2</p> <p :class="{xxx:yyy}" @click="clickAction">点击改变样式</p> </div> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { p1: 'c1', myStyle: { backgroundColor : 'red', color: 'pink', borderRadius: '50%' }, p2: 'green', p3: '50%', c1: 'ccc', c2: 'ccc1', c3: 'ccc2', c4: 'ccc3', yyy: true, }, methods: { clickAction(){ this.yyy = !this.yyy } } }) </script> </body> </html>
动态修改文本样式案例
当鼠标悬浮,按下,抬起,移开都有不同的效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 200px; height: 200px; background-color: hotpink; } .top{ line-height: 21px; } .bottom{ line-height: calc(400px - 21px); } .left { text-align: left; } .right{ text-align: right; } .center1{ text-align: center; } .center2{ line-height: 200px; } </style> </head> <body> <div id="app"> <div class="box" :class="{top:t,bottom:b,left:l,right:r,center1:c1,center2:c2}" @mouseover="m1" @mousedown="m2" @mouseup="m3" @mouseout="m4">{{ msg }}</div> </div> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { msg: '', t: 0, b: 0, l: 0, r: 0, c: 0, }, methods: { // 上中 m1(){ this.msg = '被悬浮'; this.t = 1; this.c1 = 1 }, // 下中 m2(){ this.msg = '被按下'; this.b = 1; this.t = 0; }, // 左中 m3(){ this.msg = '被抬起'; this.l = 1; this.c2 = 1; this.b = 0; this.c1 = 0 }, // 右中 m4(){ this.msg = '被移开'; this.r = 1; this.l = 0 } } }) </script> </body> </html>
4.表单指令
... 1.语法:v-model="控制vaule值的变量" 2.:value="变量" 直接绑定数据不会时时更新(修改表单标签值,值不会时时映射给绑定的变量) 3.v-model="变量" 绑定数据会时时更新(修改表单标签值,值会时时映射给绑定的变量) 4.单独复选框作为确认框时,v-model绑定的变量为布尔类型变量 5.多复选框,v-model绑定的变量值是一个列表(数组),存放复选框选项值(谁被选中就存放了谁) 6.单选框,v-model绑定的变量值是某一个选项的值(值是哪个选项的值,那个选项就被选中) ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .p1{ background-color: orange; } </style> </head> <body> <div id="app"> <form action=""> <!--1) 表单标签的值有 v-model="变量" 来绑定控制,操作的还是value,但是拥有时时变量值的检测 --> <input type="text" v-model="info"> <input type="text" v-model="info"> <p class="p1">{{ info }}</p> <!-- 2) v-model操作单独复选框 - 确认框 --> 是否同意:<input type="checkbox" true-value="yes" false-value="no" v-model="isAgree"> <p class="p1">{{ isAgree }}</p> <!-- 3) 单选框--> 性取向: 男: <input type="radio" name="sex" value="male" v-model="mysex"> 女: <input type="radio" name="sex" value="female" v-model="mysex"> 其他: <input type="radio" name="sex" value="others" v-model="mysex"> <p class="p1">{{ mysex }}</p> <!-- 4) 复选框--> 兴趣爱好: 男: <input type="checkbox" name="hobbies" value="male" v-model="myhobbies"> 女: <input type="checkbox" name="hobbies" value="female" v-model="myhobbies"> 其他: <input type="checkbox" name="hobbies" value="others" v-model="myhobbies"> <p class="p1">{{ myhobbies }}</p> </form> </div> <script src="js/vue.js"></script> <script> new Vue({ el:'#app', data: { info: '123', isAgree: 0, mysex: 'others', myhobbies: ['others'] } }) </script> </body> </html>
5.v-once指令
...
v-once:单独使用,限制的标签内容一旦赋值,就不能更改(如果标签是输入框的话可以主动修改)
...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!-- v-once是单独使用的,限制的内容一旦赋值,就不能更改了 --> <input type="text" v-model="msg"> <input type="text" v-model="msg" v-once> <p>{{ msg }}</p> <p v-once>{{ msg }}</p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { msg: '' } }) </script> </html>
6.v-cloak指令(了解)
...
v-cloak:防止页面{{}}插值表达式闪烁
...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> [v-cloak]{ display: none; } </style> </head> <body> <div id="app" v-cloak> <p>{{ msg }}</p> {{ }} </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { msg: '123' } }) </script> </html>
不处理的情况下,每次新加载该页面,都会渲染{{ }},当vue环境加载成功,会被解析成插值表达式
本质是通过display:none,将标签在加载vue环境前隐藏,当加载完成后删除该标签,就可以防止页面闪烁
7.条件指令家族
v-if指令和v-show指令
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <p v-if="isTrue">if条件指令</p> <p v-show="isTrue">show条件指令</p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data:{ isTrue:false } }) </script> </html>
当v-if和v-show都被隐藏时,v-if在前端浏览器页面代码中是不显示的,而v-show虽然被隐藏了,但是代码还是存在的,并且也能被爬取数据
... v-if = "变量" v-else-if = "变量" v-else 这是一组分支,从上往下依次执行,如果上方的条件不成立才会执行下方的条件,当上方所有的条件都不成立时会执行最后的else,所以else没有条件 ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 400px; height: 400px; } .r { background-color: red; } .y { background-color: yellow; } .b { background-color: blue; } .active { background-color: pink; } </style> </head> <body> <div id="app"> <p> <button @click="clickAction('rBox')" :class="showBox == 'rBox' ? 'active':'' " >红</button> <button @click="clickAction('yBox')" :class="showBox == 'yBox' ? 'active':'' ">黄</button> <button @click="clickAction('bBox')" :class="showBox == 'bBox' ? 'active':'' ">蓝</button> </p> <div class="box r" v-if="showBox == 'rBox'"></div> <div class="box y" v-else-if="showBox == 'yBox'"></div> <div class="box b" v-else></div> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { showBox: 'rBox', isActive: false, }, methods: { clickAction(name){ this.showBox = name; this.isActive = !this.isActive } } }) </script> </html>
8.原义指令
... v-pre指令可以在vue控制的范围内,形成局部vue不控制的区域,也就是局部不解析vue语法 ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <p>{{ msg }}</p> <!-- 指定了v-pre之后,该区域内不受vue环境控制 --> <p v-pre>{{ msg }}</p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data:{ msg: 'hahaha' } }) </script> </html>
9.循环指令
... v-for 1.遍历字符串时,可以只一一遍历字符,也可以遍历索引 <p v-for="ch in str"></p> | <p v-for="(ch, index) in str"></p> 2.遍历数组:可以一一遍历数组中的元素,也可以遍历索引 <p v-for="ele in arr"></p> | <p v-for="(ele, index) in arr"></p> 3.遍历对象:可以一一遍历元素的值,也可以遍历元素的键,也可以遍历元素的索引 <p v-for="v in dic"></p> | <p v-for="(v,k) in arr"></p> | <p v-for="(v,k,i) in arr"></p> ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <p>{{ str }}</p> <span v-for="ele in str">{{ ele }} </span> <!-- 第一个是值,第二个是索引 --> <p v-for="(ele, index) in arr">第{{ index }}个{{ ele }}</p> <!-- 第一个是值,第二个是键,第三个是索引 --> <p v-for="(ele, key, index) in dic">第{{index}}个键:{{key}}值:{{ele}}</p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data:{ str:'dasdte', arr:[1,2,3,4,5], dic:{ name:'sxc', age:18 } } }) </script> </html>
10.todolist留言板案例
... 1.留言就是往事先定义好的留言数组中添加数据,删除留言就是从留言数组中移除数据 2.前台的两个数据库:localStorage和sessionStroage localStorage可以永久的保存数据 sessionStorage临时保存数据(当页面标签关闭时,数据即被清空) 3.前台的数据库存放的都是字符串类型的数据,所以存放数据时需要通过JSON先转换成字符串的数据 ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> li:hover { color: red; cursor: pointer; } </style> </head> <body> <div id="app"> <p> <input type="text" v-model="userMsg"> <button @click="sendMsg">留言</button> </p> <ul> <li v-for="(msg, index) in msgs" @click="deleteMsg(index)"> {{ msg }} </li> </ul> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { // 判断数据库是否有值 msgs:localStorage.msgs ? JSON.parse(localStorage.msgs):[], userMsg:'' }, methods:{ sendMsg(){ if(this.userMsg){ this.msgs.push(this.userMsg); // 尾部添加 // this.msgs.unshift(this.userMsg); // 首部添加 localStorage.msgs = JSON.stringify(this.msgs); // 添加到数据库中 // sessionStorage 是临时数据库,一旦刷新页面数据即消失 this.userMsg = '' } }, deleteMsg(index){ // splice一共三个参数,第一个参数是开始的索引,第二个是操作长度,第三个是想要改变的结果 this.msgs.splice(index, 1,); localStorage.msgs = JSON.stringify(this.msgs) } } }) </script> </html>
64