VUE基础(一)
一.VUE简介:
vue是一个渐进式 JavaScript 框架 , js是页面脚本语言,用来控制或是辅助页面搭建,js功能的集合体,
vue可以更好更强大的去管理页面.
渐进式:
1)vue可以控制一个页面中的一个标签 2)vue可以控制一个页面 3)vue可以控制整个项目 js要控制页面 - 需要在页面中script引入js => vue项目就只有一个页面 => 组件化开发
VUE的优点:
1、三大前台框架:Angular React Vue vue:综合前两个框架的优点(轻量级)、一手文档是中文(上手快)、vue完全开源(免费) 2、单页面web应用 - 服务于移动端 - 客户端只需要问后台索要数据 3、MVVM设计模式 4、数据驱动 - 区别于DOM驱动(DOM加载后才能操作) - 在缓存中根据数据处理dom,再渲染给真实dom 5、虚拟dom - 页面的缓存机制 6、数据的双向绑定 - 页面中变量相同,数据就相同,实时被检测
二.VUE模块
挂载点:
(1) vue实例(对象)通过挂载点与页面建立关联
(2) 挂载点只遍历第一个匹配的结果
(3) html与body标签不可以作为挂载点
(4) 挂载点的值一般采用id选择器(唯一性)
vue模块.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app' }) </script> </html>
三.插值表达式
支持js语法(包括字符串切分索引取值,字符串拼接,数值运算,过滤器的使用等), data成员用来为vue控制的变量提供值
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <!--插值表达式--> <h1>{{ msg.split('')[0] }}</h1> <h2>{{ info + msg }}</h2> <h3>{{ num * num }}</h3> <h4>{{ num | my_filter }}</h4> <h4>{{ a, b | f1(c, d) | f2 }}</h4> <h4>{{ arr | f3 }}</h4> </div> </body> <script src="js/vue.js"></script> <script> Vue.filter('my_filter', function (v) { console.log(v); return 999 }); Vue.filter('f1', function (a, b, c, d) { console.log(a, b, c, d); // return '过滤后的逻辑结果' return a + b + c + d }); Vue.filter('f2', function (v) { console.log(v); return v * v }); Vue.filter('f3', function (v) { let new_arr = []; for (n of v) { if (n >= 60) { new_arr.push(n) } } return new_arr }); new Vue({ el: '#app', // data成员用来为vue控制的变量提供值 data: { msg: 'message', info: '信息', num: 10, a: 1, b: 2, c: 3, d: 4, arr: [23, 59, 62, 97] } }) </script> </html>
四.文本指令
v-text, v-html(可解析html标签)都是文本指令,v-once一次性渲染,插值表达式中的任何一个变量被限制,整个结果就不可变
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>文本指令</title> </head> <body> <div id="app"> <!--文本指令: {{ 插值表达式 }} v-text="变量表达式" v-html="html标签可被解析" v-once="限制的变量",内容还是通过上方三者完成渲染 --> <h2 v-text="msg + '!!!'"></h2> <h2 v-text="htm"></h2> <h2 v-html="htm"></h2> <input type="text" v-model="msg"> <h3>{{ msg }}</h3> <!--一次性渲染,插值表达式中的任何一个变量被限制,整个结果就不可变--> <h3 v-once="htm">{{ msg + htm }}</h3> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { msg: 'message', htm: '<i>标签内容是否被解析</i>' } }) </script> </html>
五.属性指令(用于控制样式)
(a)属性指令:v-bind:属性名="属性值" => v-bind: 可以简写为 :
(b)最主要应用于style和class属性:
对于style属性, 可以通过一个变量从data中获取样式字典数据,或者通过样式字典中的多个变量逐一从data中获取变量值;
对于class属性,可直接从stlye标签中获取类标签样式(支持多个),
也可以把类标签名当做data中的变量值,以变量名传给:class(支持多标签),
以[ ] 的形式接受多个data变量名(也直接写类名字符串),
以 {x: y} 形式接受, x为类名,是否生效有变量y(true|false)值决定
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>属性指令 - 控制样式</title> <style> .div { width: 200px; height: 200px; background-color: red; } .box { width: 200px; height: 200px; } .blue { background-color: blue; } .green { background-color: green; } </style> </head> <body> <div id="app"> <div class="div" style="border-radius: 50%"></div> <!--属性指令:v-bind:属性名="属性值" => v-bind: 可以简写为 : eg: v-bind:style="{color: 'red'}" --> <!--自定义属性:没有太多应用场景--> <div abc="xyz"></div> <div v-bind:abc="xyz"></div> <!--title属性--> <div :title="xyz" class="div" style="border-radius: 50%"></div> <!--style属性--> <!--1)变量:变量的值为字典--> <div :style="my_style"></div> <!--2)字典中的多个变量--> <div :style="{width: w, height: h, background: b}"></div> <!--class属性--> <!--<div class="box blue"></div>--> <div :class="c"></div> <div :class="[c1, c2]"></div> <div :class="[c1, 'blue']"></div> <!--x为类名,是否生效有变量y(true|false)值决定--> <div :class="{x: y}"></div> <div :class="[{'box': true}, c2]"></div> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { xyz: 'ABC', my_style: { width: '100px', height: '100px', 'background-color': 'cyan', borderRadius: '50%' }, w: '50px', h: '50px', b: 'red', c: 'box blue', c1: 'box', c2: 'green', y: true, } }) </script> </html>
六.事件指令
(a)事件指令 v-on:事件名="fn变量" => v-on: 可以简写为 @
(b) 内容操作:每点一次,内容+1, 绑定点击事件 v-on:click="clickAction",在app实例中写methods,匿名函数中操作this.num++
(c) 样式操作:点击切换背景颜色, @click="changeColor" , 宽高样式不变,颜色样式 style="{backgroundColor: bgColor}
在data中写默认颜色,methods中写点击事件函数,通过三元表达式改变颜色样式 this.bgColor = this.bgColor != 'cyan' ? 'cyan' : 'blue'
(d) 样式操作:点击切换整体样式, @click="changeStyle" :style="my_style",在data中传默认整体样式,
app.my_style = app.my_style.backgroundColor == 'orange' ? { 新样式}:{原样式} , =>函数内部拿不到this(指向的是window)
(e)斗篷指令: v-cloak中display:none, 没有vue,不显示,有vue,会移除该属性 => 没有闪烁的显示内容
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>事件指令</title> <style> .div { width: 200px; height: 200px; background-color: red; } /*没有vue,不显示,有vue,会移除该属性 => 没有闪烁的显示内容*/ [v-cloak] { display: none; } </style> </head> <body> <div id="app" v-cloak> <!--事件指令 v-on:事件名="fn变量" => v-on: 可以简写为 @ v-on:click="clickAction" @dblclick="dblclickAction" --> <!--内容操作:每点一次,内容+1--> <h2 v-once="num">{{ num }}</h2> <h2>{{ num }}</h2> <div v-on:click="clickAction" class="div">{{ num }}</div> <hr> <!--样式操作:点击切换背景颜色--> <div @click="changeColor" class="div" :style="{backgroundColor: bgColor}"></div> <!--样式操作:点击切换整体样式--> <div @click="changeStyle" :style="my_style"></div> </div> </body> <script src="js/vue.js"></script> <script> let app = new Vue({ el: '#app', data: { num: 100, bgColor: 'cyan', my_style: { width: '100px', height: '100px', backgroundColor: 'orange' } }, methods: { clickAction: function () { // console.log(app.num); // console.log(this.num); this.num ++ }, changeColor () { // 方法的写法 // if (this.bgColor == 'cyan') { // this.bgColor = 'blue' // } else { // this.bgColor = 'cyan' // } // this.bgColor = 'cyan' if this.bgColor != 'cyan' else 'blue' this.bgColor = this.bgColor != 'cyan' ? 'cyan' : 'blue' }, changeStyle: () => { // 这种写法,内部拿不到this(指向的是window) app.my_style = app.my_style.backgroundColor == 'orange' ? { width: '200px', height: '200px', backgroundColor: 'yellow' } : { width: '100px', height: '100px', backgroundColor: 'orange' } } } }); console.log(app); console.log(app.$el); console.log(app.$data.num); console.log(app.num); </script> </html>
(f)事件指令传参
没有传值默认传事件对象
方法()不会直接调用方法,而是在点击触发后进行传参,接收到的参数就是传入的参数,传的参数不足显示undifined,
传多的参数不显示
一旦书写 方法() 就不再传入事件对象,通过 $event 手动传入事件对象
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> div { width: 50px; height: 50px; background-color: red; border-radius: 50%; text-align: center; line-height: 50px; color: white; cursor: pointer; } </style> </head> <body> <div id="app"> <!--没有传值默认传 事件对象 --> <div @click="btnClick1">{{ msg }}</div> <!--方法()不会直接调用方法,而是在点击触发后进行传参,接收到的参数就是传入的参数--> <div @click="btnClick2(1, msg)">{{ msg }}</div> <!--一旦书写 方法() 就不再传入事件对象,通过 $event 手动传入事件对象--> <div @click="btnClick3(msg, $event, $event)">{{ msg }}</div> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { msg: 'box' }, methods: { btnClick1(ev) { console.log(ev); console.log(ev.clientX); }, btnClick2(a, b, c) { console.log(a, b, c) }, btnClick3(a, b, c) { console.log(a, b, c) }, } }) </script> </html>
七.表单指令
(a)表单指令:v-model="变量"
(b)双向绑定(可配合过滤器使用), return info ? info : '初始内容',无值显示初始内容,有值则显示当前内容
(c)单选框 :变量存放的是某个单选框的value值,代表该选框选中
(d)单独复选框: v-model="true|false代表该选框是否选中,选中提交会传agree=yes,不选则提交无此内容
(e)群复选框: 存放选中选框value的数组,多选相当用push新增value值
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>表单指令</title> </head> <body> <div id="app"> <form action=""> <!--表单指令:v-model="变量"--> <!--双向绑定:一个地方修改值,所有地方的数据都会被更新--> <div> <input type="text" v-model="info" name="usr"> <input type="password" v-model="info" name="pwd"> <p>{{ info | infoFilter }}</p> </div> <div> <!--单选框:v-model="变量存放的是某个单选框的value值,代表该选框选中"--> 男<input type="radio" name="sex" value="male" v-model="sex_val"> 女<input type="radio" name="sex" value="female" v-model="sex_val"> </div> <div> <!--单独的复选框:v-model="true|false代表该选框是否选中"--> 是否同意<input v-model="cb_val" value="yes" type="checkbox" name="agree"> </div> <div> <!--群复选框:v-model="存放选中选框value的数组"--> 男<input v-model="cbs_val" value="male" type="checkbox" name="hobby"> 女<input v-model="cbs_val" value="female" type="checkbox" name="hobby"> 哇塞<input v-model="cbs_val" value="others" type="checkbox" name="hobby"> <p>{{ cbs_val }}</p> </div> <div> <input type="submit"> </div> </form> </div> </body> <script src="js/vue.js"></script> <script> Vue.filter('infoFilter', (info) => { return info ? info : '初始内容' }); new Vue({ el: '#app', data: { info: '', sex_val: 'female', cb_val: 0, cbs_val: ["others"] } }) </script> </html>
八.条件指令:
(a)v-if与v-show:
v-if="true|false" v-show="true|false"
v-if隐藏时不渲染,v-show隐藏时用display:none渲染
点击事件函数:
this.title = this.title == '隐藏' ? '显示' : '隐藏';
this.is_show = !this.is_show;
(b)v-if与v-else-if/v-else:
button按钮绑定点击事件传颜色(page)参数,并能保存至缓存,通过条件指令筛选展示页面
(c)缓存问题:
localStorage.page = page; // 永久缓存
sessionStorage.page = page; // 临时缓存
data:
page: localStorage.page || 'pink'
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> .btn1 { width: 400px; } .box { width: 200px; height: 200px; float: left; } .wrap:after { content: ''; display: block; clear: both; } .red { background-color: red } .blue { background-color: blue } </style> <style> .btn-wrap { height: 25px } .btn { width: 100px; height: 25px; float: left; } .page { width: 300px; height: 150px; } .p1 { background-color: pink } .p2 { background-color: yellow } .p3 { background-color: green } </style> </head> <body> <div id="app"> <!--条件指令 v-if="true|false" v-show="true|false" --> <button class="btn1" @click="btnClick">{{ title }}</button> <div class="wrap"> <!--v-if隐藏时不渲染,v-show隐藏时用display:none渲染--> <!--v-if隐藏时在内存中建立缓存,可以通过key属性设置缓存的键--> <div class="box red" v-if="is_show" key="box_red"></div> <div class="box blue" v-show="is_show"></div> </div> <div class="btn-wrap"> <button class="btn" @click="changePage('pink')">粉</button> <button class="btn" @click="changePage('yellow')">黄</button> <button class="btn" @click="changePage('green')">绿</button> </div> <div> <div class="page p1" v-if="page == 'pink'"></div> <div class="page p2" v-else-if="page == 'yellow'"></div> <div class="page p3" v-else></div> </div> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { title: '隐藏', is_show: true, page: localStorage.page || 'pink' }, methods: { btnClick() { this.title = this.title == '隐藏' ? '显示' : '隐藏'; this.is_show = !this.is_show; }, changePage(page) { this.page = page; localStorage.page = page; // 永久缓存 // sessionStorage.page = page; // 临时缓存 } } }) </script> </html>