前端学习之Vue
目录
一、Vue框架
vue框架:渐进式JavaScript框架
vue一个环境:可以只控制页面中一个标签、可以控制一组标签、可以控制整个页面、可以控制整个项目
vue可以根据实际需求,选择控制前端项目的区域范围
为什么学习vue
"""
1、html、css、js直接开发项目,项目杂乱,不方便管理,要才有前端框架进行开发,规范项目
2、Angular、React、Vue三个前端框架,吸取前两个框架的所有优点,摒弃缺点,一手文档是中文
3、Vue框架优点:
轻量级
数据驱动
数据的双向绑定
虚拟DOM(嵌套页面架构的缓存)
组件化开发
由全球社区维护
单页面应用、MVVM设计模式
"""
二、Vue指令
-
导入Vue
<script src="vue/vue.js"></script>
2.1 挂载点
实例化对象传递的参数 el为挂载点,才有css3选择器语法与页面标签进行绑定,决定该vue对象控制的页面范围
- 挂载点只检索页面中第一个匹配到的结果,所以挂载点一般都才有id选择器
- html与body标签不可以作为挂载点(组件中解释)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>vue导入-挂载点</title>
</head>
<body>
<div id="app">
</div>
</body>
<script src="vue/vue.js"></script>
<script>
// el为挂载点,才有css3选择器语法与页面标签进行绑定,决定该vue对象控制的页面范围
//
// 2.html与body标签不可以作为挂载点(组件中解释)
new Vue({
el: '#app',
})
</script>
</html>
2.2 vue变量
- 访问vue实例成员(变量),用 vue实例.\(成员名, eg:`app.\)el`
- 插值表达式
{{ }}
可以完成基础运算 - 插值表达式中的变量有实例成员 data 来提供
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>vue变量</title>
</head>
<body>
<div id="app">
<p>{{ msg }}</p>
<p>{{ info }}</p>
</div>
<div id="main">
<p>{{ msg }}</p>
<p>{{ info }}</p>
</div>
</body>
<script src="vue/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data:{
msg:"app_message",
info:"app_info",
}
});
var main = new Vue({
el:"#main",
data:{
msg:"main_message",
info:"main_info",
}
});
console.log(app.info); // 简写
console.log(main.info);
// 创建vue实例(new Vue)传进去的字典(对象)的key,称之为vue实例成员(变量)
// 访问实例成员,用 vue实例.$成员名, eg:app.$el
console.log(app.$el);
console.log(app.$data);
console.log(app.$data.info); // 等同于上面的简写,这是详细写法
</script>
</html>
2.3 vue事件
- v-on指令可以给标签绑定事件,事件函数由实例成员 methods 来提供
- vue实例对象中的this表示整个vue实例对象
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>vue事件</title>
<style>
body {
/*页面内容不允许被选中*/
user-select: none;
}
.p1:hover {
cursor: pointer;
color: green;
}
</style>
</head>
<body>
<div id="app">
<p class="p1" v-on:click="fn">这是一个段落,被点击了{{ count }}下</p>
<p class="p2" v-on:mouseover="overAction" v-on:mouseout="outAction" >该便签被{{ action }}</p>
<div v-on:mouseover="overAction" v-on:mouseout="outAction">div被{{ action }}</div>
</div>
</body>
<script src="vue/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
count:0,
action:"渲染",
},
methods:{
fn:function () {
console.log(this); // this代表当前该vue实例对象
this.count++
},
overAction:function () {
this.action = "悬浮"
},
outAction:function () {
this.action = "离开"
}
}
})
</script>
</html>
2.4 js的对象
回顾一下js的对象
- js中没有字典,只要对象类型,可以把对象当做字典来使用
- key本质是属性名,所以都是字符串类型(可以出现1,true),其实都是省略引号的字符串
let sex = '男';
let dic = {
'name': 'xc',
1: 100,
true: 12345,
age: 18,
// sex: 'sex',
sex, // 简写形式
};
- 声明类创建对象:类可以实例化n个对象,哪个对象调用,this就代表谁
// 声明类创建对象,类可以实例化n个对象,哪个对象调用,this就代表谁
function People(name, age) {
this.name = name;
this.age = age;
this.eat = function () {
console.log(this.name + '在吃饭');
return 123
}
}
var p1 = new People('xc', 17.5);
console.log(p1.name);
- 直接声明对象,{}内的key都属于当前对象的
- {}中的方法通常会简写
let stu1 = {
name: '张三',
age: 18,
// eat: function () {
// console.log(this.name + '在吃饭');
// }
eat () { // 简写形式
console.log(this.name + '在吃饭');
}
};
stu1.eat()
总结
1.{}中直接写一个变量:key与value是同名,value由该名变量提供值
2.es5下,所有的函数都可以作为类,类可以new声明对象,在函数中用 this.资源 为声明的对象提供资源
3.{}中出现的函数叫方法,方法可以简写 { fn: function(){} } => { fn(){} }
2.5 vue文本指令
vue的模板语法中{{}}也叫做插值表达式
- 插值表达式,能完成变量渲染,变量基础运算,变量方法调用,不能完成复杂运算(一步解决不了的,不能出现;)
- v-text:将所有内容做文本渲染
- v-html:可以解析html语法标签的文本
- ``内的语句可以直接被html识别,但是其中的变量必须用${}
<div id="app">
<!-- 1、插值表达式,能完成变量渲染,变量基础运算,变量方法调用,不能完成复杂运算(一步解决不了的,不能出现;) -->
<p>{{ msg }}</p>
<p>{{ msg + "拼接内容" }}</p>
<p>{{ msg[1] }}</p>
<p>{{ msg.slice(1,3) }}</p>
<hr>
<!--2、v-text:将所有内容做文本渲染 -->
<p v-text="msg+'拼接内容'"></p>
<!--3、v-html:可以解析html语法标签的文本 -->
<p v-html="'<b>' + msg + '</b>'"></p>
<!-- ``内的语句可以直接被html识别,但是其中的变量必须用${} -->
<p v-html="`<b>${msg}</b>`"></p>
</div>
<script src="vue/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
msg:"abcdefg"
},
})
</script>
2.6 vue过滤器
- 插值表达式{{ 变量 | 过滤器 }}的过滤器由实例成员 filters 来提供
- 过滤器可以串联,就是将第一个过滤器执行后的结果给第二个过滤器
- 过滤器可以传值
<body>
<div id="app">
<!-- 默认将msg作为参数传给filterFn -->
<p>{{ msg | filterFn }}</p>
<!--过滤器串联 -->
<p>{{ num | f1 | f2 }}</p>
<!--可以同时对多个变量进行过滤,变量用,分割,过滤器还可以额外传入参数辅助过滤-->
<!--过滤器方法接收所有传入的参数,按传入的位置进行接收-->
<p>{{ msg, num | f3(666, '好的') }}</p>
</div>
</body>
<script src="vue/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
msg:"你好啊",
num :1
},
methods: {
filterFn(v1, v2) {
// console.log(v1);
// console.log(v2);
return `<b>${v1}</b>`;
},
},
filters:{
f1(v1){
return v1*100;
},
f2(v1){
return v1*100;
},
f3(v1,v2,v3,v4){
console.log(v1);
console.log(v2);
console.log(v3);
console.log(v4);
},
}
})
</script>
</html>
2.7 vue事件指令
- 事件指令:v-on:事件名="事件函数"
- 简写:@事件名="事件函数"
- 绑定的事件函数添加(),就代表要传递参数。不添加()代表不传递参数,默认会传递事件对象
- 事件函数一旦添加传参(),系统就不再传递任何参数,需要事件对象时,可以手动传入 $event
<div id="app">
<!--事件指令:v-on:事件名="事件函数" -->
<!--简写:@事件名="事件函数" -->
<p v-on:click="f1">被点击了{{ count }}下</p>
<hr>
<p @click="f2">{{ p2 }}</p>
<!--绑定的事件函数可以添加(),添加括号就代表要传递参数-->
<ul>
<li @click="f3(100)">{{ arr[0] }}</li>
<li @click="f3(200)">{{ arr[1] }}</li>
<li @click="f3(300)">{{ arr[2] }}</li>
</ul>
<!--绑定的事件函数如果没有传递参数,默认传入 事件对象 -->
<div class="box" @click="f4">我是事件对象</div>
<hr>
<!--事件函数一旦添加传参(),系统就不再传递任何参数,需要事件对象时,可以手动传入 $event -->
<div class="box" @click="f5(10, $event)">我是参数加事件对象</div>
</div>
<script src="vue/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
count:0,
p2:"第二个p",
arr:[1,2,3]
},
methods:{
// 简写
f1(){
this.count++
},
f2() {
console.log(this.p2)
},
f3(num) {
console.log(num);
},
f4(ev) {
console.log(ev);
},
f5(num,ev) {
console.log(num,ev);
}
}
})
</script>
2.8 vue属性指令
- 属性指令:v-bind:属性名="变量"
- 简写方式::属性名="变量"
- **属性指令操作 style 属性: {}中可以用多个变量控制多个属性细节 **
- 属性指令操作class属性:
- 可以写两份,一份写死,一份由vue控制
- {} 控制类名,key为类名,key对应的值为bool类型,决定该类名是否起作用
- [] 控制多个类名
<head>
<meta charset="UTF-8">
<title>vue属性指令</title>
<style>
.b1 {
width: 100px;
height: 100px;
background-color: red;
}
.box1 {
width: 150px;
height: 150px;
background-color: darkturquoise;
transition: .3s;
}
.box2 {
width: 300px;
height: 100px;
background-color: darkgoldenrod;
transition: .3s;
}
.circle {
border-radius: 50%;
}
</style>
</head>
<body>
<div id="app">
<!--1.下方的class、id、title、abc等是div标签的属性,属性指令就是控制它们的-->
<!--2.属性指令:v-bind:属性名="变量",简写方式 :属性名="变量" -->
<div class="b1" id="b1" v-bind:title="title" :abc="xyz"></div>
<!--3.属性指令操作 style 属性-->
<!-- 通常:变量值为字典 -->
<div :style="mys1"></div>
<!-- 了解:{中可以用多个变量控制多个属性细节} -->
<div :style="{width: w ,height: '200px',backgroundColor: 'deeppink'}"></div>
<!--重点:一般vue都是结合原生css来完成样式控制 -->
<!--class可以写两份,一份写死,一份有vue控制-->
<div class="box1" :class="c2"></div>
<!--{}控制类名,key为类名,key对应的值为bool类型,决定该类名是否起作用-->
<div :class="{box2:true, circle:cable}" @mouseover="changeCable(1)" @mouseout="changeCable(0)"></div>
<!--[]控制多个类名-->
<div :class="[c3, c4]"></div>
</div>
</body>
<script src="vue/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
title: '12345',
xyz: 'opq',
mys1: {
width: '200px',
height: '200px',
// 'background-color': 'greenyellow'
backgroundColor: 'pink',
},
w: '200px',
c1: 'box1',
c2: 'circle',
cable: false,
c3: 'box1',
c4: 'circle'
},
methods: {
changeCable(n) {
this.cable = n;
}
}
})
</script>
</html>
2.9 vue表单指令
- 表单指令:v-model="变量"
- v-model绑定的变量控制的是表单元素的value值
- 普通表单元素,用v-model直接绑定变量控制value值
- 单个复选按钮:布尔值
- 多个复选按钮:列表中放选中的 value值
- 单选按钮:放选中的 value值
<div id="app">
<form action="">
<!--属性指令:v-model="变量",v-model绑定的变量控制的是表单元素的value值 -->
<!--普通表单元素,用v-model直接绑定变量控制value值-->
<p><input type="text" v-model="v1"></p>
<textarea name="" id="" cols="30" rows="10" v-model="v1"></textarea>
<p>{{ v1 }}</p>
<hr>
<!--单一复选框-->
同意:
<input type="checkbox" name="agree" v-model="v2">
<hr>
<!--多个复选框-->
男:<input type="checkbox" name="hobbies" value="male" v-model="v3">
女:<input type="checkbox" name="hobbies" value="female" v-model="v3">
哇塞:<input type="checkbox" name="hobbies" value="wow" v-model="v3">
<p>{{ v3 }}</p>
<hr>
<!--单选框-->
中午吃啥:<br>
肉肉:<input name="food" type="radio" value="rourou" v-model="v4">
饭饭:<input name="food" type="radio" value="fanfan" v-model="v4">
<p>{{ v4 }}</p>
<hr>
<button type="submit">提交</button>
</form>
</div>
<script src="vue_lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
v1:"",
v2: false, // 布尔值,单个复选按钮
v3: ["male","female"], // 列表中放选中的 value值,多个复选按钮
v4: "", // ""放选中的 value值,单选按钮
},
})
</script>
2.10 vue斗篷指令(了解)
- 了解:斗篷指令解决页面闪烁
- 实际上把加载vue环境的那句代码,放到head中也可以解决
<head>
<meta charset="UTF-8">
<title>vue斗篷指令</title>
<style>
[v-cloak] {
display: none;
}
</style>
<!-- 这样也可以-->
<script src="vue_lib/vue.js"></script>
</head>
<body>
<!-- 斗篷指令就是为了解决页面渲染闪烁的问题
先导入vue环境其实就可以
-->
<div id="app" v-cloak>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
</div>
</body>
<script>
new Vue({
el: '#app',
data:{
msg:12345
},
})
</script>
</html>
2.11 vue条件指令
- 条件指令:v-if="true|false",为假时在页面上不渲染
- 条件指令:v-show="true|false",为假时在页面中用display:none渲染
- v-if是一个家族:v-if、v-else-if、v-else
- 分支条件,只能满足一个分支
<div id="app">
<!--条件指令:
v-if="true|false",为假时,在页面上不渲染
v-show="true|false",为假时,在页面中用display:none渲染,虽然没展示,但是任在页面结构中
-->
<p v-if="false">if指令</p>
<p v-show="false">show指令</p>
<!-- v-if是一个家族
v-if
v-else-if
v-else
1、上分支成立,下分支会被屏蔽
2、else分支只要在所有上分支都为假时显示,且不需要条件
-->
<input type="text" v-model="msg">
<p v-if="msg === 'xc'">你真帅</p>
<p v-else-if="msg === 'baba'">傻逼</p>
<p v-else-if="msg === 'cyx'">好看</p>
<p v-else>傻逼,会不会打字</p>
<hr>
</div>
<script src="vue_lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
msg:""
},
})
</script>
vue条件指令案例(重点)
实现点击按钮在页面渲染点击的颜色,并使按钮高亮。下次打开网页也是高亮
- 需要使用前台数据库,所谓前台数据库,就是不需要后台交互,只需要前台的数据库来存储数据即可。
- 打开浏览器,F12,看application选项卡中有
sessionStorage
localStorage
- html5自带了两个:
- sessionStorage的生命周期与页面标签绑定,当标签页被关闭,数据库被清空
- localStorage是前台永久数据库
<head>
<meta charset="UTF-8">
<title>vue条件指令案例(重点)</title>
<style>
.box {
width: 400px;
height: 200px;
}
.r { background-color: red }
.y { background-color: yellow }
.b { background-color: blue }
.action {
background-color: pink;
}
</style>
</head>
<body>
<div id="app">
<!-- 实现记录上次点击按钮的功能
需要用到前台数据库
-->
<p>
<button @click="change('red')" :class="{r: c === 'red'}">红</button>
<button @click="change('yellow')" :class="{y: c === 'yellow'}">黄</button>
<button @click="change('blue')" :class="{b: c === 'blue'}">蓝</button>
</p>
<div class="wrap">
<div class="box r" v-if="c === 'red'"></div>
<div class="box y" v-else-if="c === 'yellow'"></div>
<div class="box b" v-else></div>
</div>
</div>
</body>
<script src="vue_lib/vue.js"></script>
<script>
// sessionStorage的生命周期与页面标签绑定,当标签页被关闭,数据库被清空
// localStorage是前台永久数据库
// localStorage.clear(); 清空
new Vue({
el: '#app',
data:{
c: localStorage.c ? localStorage.c : "red",
},
methods:{
change(color){
this.c = color;
// 每一次改变c的值,将值同步到前台数据库
localStorage.c = color; // 存
}
}
})
</script>
2.12 vue循环指令
- 循环指令:v-for="成员 in 容器"
- 第一个成员一定是value
<body>
<div id="app">
<!--循环指令:
v-for=""
语法:
v-for="成员 in 容器"
-->
<!--1、字符串循环渲染: 可以只遍历值,也可以遍历值与索引-->
<p>
<span v-for="v in title">{{ v }}</span>
<span v-for="(v,i) in title">索引{{ i }}={{ v }} </span>
</p>
<p>
<span v-for="(v,i) in title">
<span v-if="i !=0"> | </span>
{{ v }}
</span>
</p>
<!--2、数组循环渲染: 可以只遍历值,也可以遍历值与索引-->
<div>
<p v-for="(v, i) in arr">第{{ i }}元素:{{ v }}</p>
</div>
<!--3、对象循环渲染: 可以只遍历值,也可以遍历值与键,还可以遍历值、键与索引-->
<div>
<!--只遍历值-->
<p v-for="v in people">{{ v }}</p>
</div>
<div>
<!--只遍历key和value-->
<p v-for="(v, k) in people">{{ k }}:{{ v }}</p>
</div>
<div>
<!--遍历key和value和索引-->
<p v-for="(v, k, i) in people">第{{ i }}个:{{ k }}:{{ v }}</p>
</div>
<div>
<div v-for="(stu, i) in stus">
<hr v-if="i!=0">
<p v-for="(v,k) in stu">{{ k }}:{{ v }}</p>
</div>
</div>
</div>
</body>
<script src="vue_lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
title:"123123",
arr : [5,56,7,8,1,123,],
people: {
name: '兔子',
color: '粉白',
price: 6.66,
},
stus: [
{
name: "Bob",
age: 18
},
{
name: "Tom",
age: 17
},
{
name: "Jerry",
age: 19
}
]
}
})
</script>
vue循环指令案例
- 通过循环来实现留言
<body>
<div id="app">
<input type="text" v-model="msg">
<button @click="send_comment">留言</button>
<ul>
<li v-for="(v, i) in comments" @click="deleteMsg(i)">{{ v }}</li>
</ul>
</div>
</body>
<script src="vue_lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
msg:"",
comments :[],
},
methods:{
send_comment(){
// 数组的增
// push pop unshift shift splice
if (this.msg){
this.comments.push(this.msg); // 留言
this.msg = ""; // 留言后清空输入框
}
},
deleteMsg(index){
this.comments.splice(index,1);
}
}
})
</script>
<script>
// 数组操作万能方法,可以完成增删改
let arr = [1, 2, 3];
// 参数:开始索引,操作长度,操作的结果们
arr.splice(2, 0, 100); // 从索引为2的地方插入
arr.splice(1, 1); // 删除掉从索引1开始的一个元素
console.log(arr);
</script>
三、实例成员
1、el:实例
new Vue({
el: '#app'
})
// 实例与页面挂载点一一对应
// 一个页面中可以出现多个实例对应多个挂载点
// 实例只操作挂载点内部内容
2、data:数据
<div id='app'>
{{ msg }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
msg: '数据',
}
})
console.log(app.$data.msg);
console.log(app.msg);
</script>
<!-- data为插件表达式中的变量提供数据 -->
<!-- data中的数据可以通过Vue实例直接或间接访问-->
3、methods:方法
<style>
.box { background-color: orange }
</style>
<div id='app'>
<p class="box" v-on:click="pClick">测试</p>
<p class="box" v-on:mouseover="pOver">测试</p>
</div>
<script>
var app = new Vue({
el: '#app',
methods: {
pClick () {
// 点击测试
},
pOver () {
// 悬浮测试
}
}
})
</script>
<!-- 了解v-on:为事件绑定的指令 -->
<!-- methods为事件提供实现体-->
4、computed:计算
- computed中定义的是方法属性,data中定义的也是属性,所以不需要重复定义(省略data中的)
- 方法属性的值来源于绑定的方法的返回值
- 方法属性必须在页面中渲染后,绑定的方法才会被启用(调用)
- 方法中出现的所有变量都会被监听,任何变量发生值更新都会调用一次绑定的方法,重新更新一下方法属性的值
- 方法属性值不能手动设置,必须通过绑定的方法进行设置
<div id="app">
<input type="text" v-model="v1">
+
<input type="text" v-model="v2">
=
<button>{{ res }}</button>
</div>
<script src="vue_lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
v1:"",
v2:"",
// res: '结果',
},
// 1、computed中定义的是方法属性,data中定义的也是属性,所以不需要重复定义(省略data中的)
// 2、方法属性的值来源于绑定的方法的返回值
// 3、方法属性必须在页面中渲染后,绑定的方法才会被启用(调用)
// 4、方法中出现的所有变量都会被监听,任何变量发生值更新都会调用一次绑定的方法,重新更新一下方法属性的值
// 5、方法属性值不能手动设置,必须通过绑定的方法进行设置
computed:{
res(){
console.log("该方法被调用了");
return this.v1 && this.v2 ? +this.v1 + +this.v2:"结果";
}
}
})
</script>
5、watch:监听
- watch中给已有的属性设置监听方法
- 监听的属性值一旦发生更新,就会调用监听方法,在方法中完成相应逻辑
- 监听方法不需要返回值(返回值只有主动结束方法的作用)
<div id="app">
<p>
姓名:<input type="text" v-model="full_name">
</p>
<p>
姓:<span>{{ first_name }}</span>
</p>
<p>
名:<span>{{ last_name }}</span>
</p>
</div>
<script src="vue_lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
full_name:"",
first_name:"",
last_name:"",
},
watch:{
// 1、watch中给已有的属性设置监听方法
// 2、监听的属性值一旦发生更新,就会调用监听方法,在方法中完成相应逻辑
// 3、监听方法不需要返回值(返回值只有主动结束方法的作用)
full_name(){
if(this.full_name.length>=2){
this.first_name = this.full_name[0];
this.last_name = this.full_name.slice(1,);
}
}
}
})
</script>
6、delimiters:分隔符
- 用来修改插值表达式符号
<div id='app'>
${ msg }
</div>
<script>
new Vue({
el: '#app',
data: {
msg: 'message'
},
delimiters: ['${', '}']
})
</script>