二.Vue的使用
1.Vue的导入
CDN导入
对于制作原型或学习,你可以这样使用最新版本:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
对于生产环境,我们推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏:
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
本地导入
<script src="js/vue.js"></script>
2.挂载点el
<script>
new Vue({
//vue实例对象通过挂载点与页面建立关联
el:"h1"
}
)
</script>
注意:
// 挂载点只遍历第一个匹配的结果
// html与body标签不可以作为挂载点
// 挂载点的只一般就采用id选择器(唯一性)
3.插值表达式{{ }}
<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实例直接或间接访问-->
4.过滤器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<!--num作为过滤器的参数,过滤器的返回值就是插值表达式显示在前端页面的内容-->
<h4>{{ num | my_filter }}</h4>
<!--过滤器f1被传递了四个参数a,b,c,d,并将过滤结果做出f2的参数再过滤-->
<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: {
num: 10,
a: 1,
b: 2,
c: 3,
d: 4,
arr: [23, 59, 62, 97]
}
})
</script>
</html>
5.文本指令
<!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>
6.属性指令
<!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>
7.事件指令(重点)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>事件指令</title>
<style>
.div {
width: 200px;
height: 200px;
background-color: red;
}
/*斗篷指令,没有vue,不显示,有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'
// }
// python: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>
8.事件指令传参
<!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>
9.表单指令
<!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>
10.条件指令
<!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>
<!--v-if成立会屏蔽下方分支、v-else-if一样f成立会屏蔽下方分支-->
<!--v-if不成立时才看v-else-if、v-else-if成立会屏蔽下方分支-->
<!--v-if、v-else-if都不成立,v-else才成立-->
<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