Vue - 基本指令
目录
Vue
渐进式 JavaScript 框架
js是页面脚本语言,用来控制或是辅助页面搭建,js功能的集合体
vue可以更好更强大的去管理页面
1)vue可以控制一个页面中的一个标签
2)vue可以控制一个页面
3)vue可以控制整个项目
js要控制页面 - 需要在页面中script引入js => vue项目就只有一个页面 => 组件化开发
优点
1、三大前台框架:Angular(脸书) React(Github) Vue(优点:综合前两个框架的优点[轻量级]、一手文档是中文[上手快]、vue完全开源[免费])
2、单页面web应用 - 服务于移动端 - 客户端只需要问后台索要数据
3、MVVM设计模式
4、数据驱动 - 区别于DOM驱动(DOM加载后才能操作)- 在缓存中处理dom,在渲染给真实dom
5、虚拟dom - 页面的缓存机制
6、数据的双向绑定 - 页面中变量相同,数据就相同,实时变检测
Vue导入与挂载点
在官网下载vue.js文件,类似于js的导入。Vue就相当于一个类
<script src="js/vue.js"></script>
<h1>
{{ }}
</h1>
<script>
new Vue({
// 挂载点:vue实例(对象)通过挂载点与页面建立关联
// 挂载点只遍历第一个匹配的结果
// html和body标签不可以作为挂载点
// 挂载点的值一般只选择id选择性,具有唯一性
el:'h1'
})
</script>
Vue插值表达式
<script src="js/vue.js"></script>
<div id='app'>
<!--插值表达式:用来渲染值-->
<h1>{{ msg.split('')[0] }}</h1>
<h2>{{ info+msg }}</h2>
<h3>
{{ num|my_filter }}
</h3>
<h3>
{{ a,b|my_filter(c,d)|f2 }} <!--过滤后再过滤-->
</h3>
</div>
<script>
// 过滤器
Vue.filter('my_filter',function(v){
console.log(v); // 将num传给v
return 999
})
new Vue({
el:'#app',
// data成员用来为vue控制的变量提供值
data:{
msg:'message',
info:'信息'
num:10,
}
})
</script>
Vue文本指令
<div id='app'>
<!--可以出现基本数据类型-->
<h2 v-text='msg'></h2>
<h2 v-text="msg + 'abc'"></h2>
<!--解析标签-->
<h2 v-html='html'></h2>
<input v-model='msg' type='text'>
<!--一次性渲染,插值表达式中的任何一个变量被限制,整个结果就不可变-->
<h3 v-once='html'>{{ htm + msg}}</h3> <!--html为限制的变量-->
</div>
<script>
new Vue({
el:'#app',
data:{
msg:'message'
htm:'<i>标签内容被解析</i>'
}
})
</script>
Vue属性指令 - 控制样式
<style>
.div {
width: 200px;
height: 200px;
background-color: red;
}
.box {
width: 200px;
height: 200px;
}
.blue {
background-color: blue;
}
</style>
<!--属性指令 v-bind:属性名='属性值'-->
d<div id="app">
<div class="div" style="border-radius: 50%"></div>
<!--指令属性 v-bind:属性名='属性值' ==> v-bind:可以简写为:-->
<!--自定义属性:没有太多应用场景-->
<div abc="xyz"></div>
<div v-bind:abc="xyz"></div>
<!--title属性-->
<div :title="xyz"></div>
<!--style属性-->
<!--1)变量:变量的值为字典-->
<div :style="my_style"></div>
<!--2)字典中的多个变量-->
<div :style="{width:w,height:h,background:b}"></div>
<!--class属性-->
<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="{'blue': y}"></div>
</div>
</body>
<script src="Vue/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
xyz: 'ABC',
my_style: {
width: '100px',
height: '100px',
backgroundColor: 'cyan',
borderRadius: '50%'
},
w: '100px',
h: '100px',
b: 'yellow',
c: 'box blue',
c1: 'box',
c2: 'blue',
y: true,
}
})
</script>iv
Vue事件指令
<style>
.div {
width: 200px;
height: 200px;
background-color: red;
}
</style>
<div id="app">
<!--事件指令 v-on:事件名='fn函数变量' => v-on:可以简写为@-->
<!--内容操作每点一次,内容+1-->
<div v-on:click="clickAction" class="div">{{num}}</div>
<!--样式操作:点击切换背景颜色-->
<div @click="changeColor" class="div" :style="{'backgroundColor':bgColor}"></div>
<!--样式操作:点击切换整体样式-->
<div @click="changeStyle" :style="my_style"></div>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
num: 100,
bgColor: 'cyan',
my_style: {
width: '200px',
height: '200px',
backgroundColor: 'orange'
}
},
methods: {
clickAction: function () {
this.num++
},
changeColor() { // 方法的写法
// if (this.bgColor == 'cyan') {
// this.bgColor = 'blue'
// } else {
// this.bgColor = 'cyan'
// }
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); // Vue对象
console.log(app.$el); // 这个标签
console.log(app.$data.num); // num的值
console.log(app.num); // 只有data提供数据,$data可以省略
</script>
Vue事件指令传参
<style>
div {
width: 100px;
height: 100px;
background-color: red;
border-radius: 50%;
line-height: 100px;
text-align: center;
cursor: pointer;
}
</style>
<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>
<script>
new Vue({
el: '#app',
data: {
msg: 'box'
},
methods: {
btnClick1(ev) {
console.log(ev.clientX)
},
btnClick2(a, b, c) {
console.log(a, b, c)
},
btnClick3(a, b, c) {
console.log(a, b, c)
}
}
});
</script>
Vue斗篷指令-初次加载页面不会闪烁
<style>
/*没有vue,不显示;有vue,会移除该属性 => 没有闪烁的显示内容*/
[v-cloak]{
display: none;
}
</style>
<div v-cloak></div>
Vue表单指令
<div id="app">
<form action="">
<!--表单指令:v-model='变量'-->
<!--双向绑定:一个地方修改值,所有地方的数据都会被更新-->
<input type="text" v-model="info" name="user">
<input type="password" v-model="info" name="pwd">
<!--上面没内容,p为初始内容,上面有内容,就显示内容-->
<p>{{ info | infoFilter }}</p>
<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 type="checkbox" name="agree" value="yes" v-model="cb_val">
</div>
<div>
<!--群复选框:v-model='存放选中选框value的数组'-->
男 <input type="checkbox" name="hobby" v-model="cbs_val" value="male">
女 <input type="checkbox" name="hobby" v-model="cbs_val" value="female">
哇塞 <input type="checkbox" name="hobby" v-model="cbs_val" value="others">
<p>{{cbs_val}}</p>
</div>
<div>
<input type="submit" value="提交">
</div>
</form>
</div>
<script>
Vue.filter('infoFilter', (info) => {
return info ? info : '初始内容'
});
new Vue({
el: "#app",
data: {
info: '',
sex_val:'male',
cb_val: true,
cbs_val: []
}
})
</script>
Vue条件指令
<style>
button {width: 400px;}
.box {
width: 200px;
height: 200px;
float: left;
}
.wrap:after {
content: '';
display: block;
clear: both;
}
.red {background-color: red;}
.blue {background-color: blue;}
.page {
width: 300px;
height: 100px;
}
.p1 {background-color: pink;}
.p2 {background-color: yellow;}
.p3 {background-color: green;}
.btn {
width: 100px;
float: left;
}
</style>
<div id="app">
<!--条件指令
v-if='true|false':false时不显示页面就不渲染了,推荐使用
v-show='true|false':false时是用display:none来隐藏
-->
<button @click="btnClick">{{title}}</button>
<div class="wrap">
<!--v-if隐藏时在内存中建立缓存,可以通过key属性设置缓存的键-->
<div class="box red" v-if="is_show"></div>
<div class="box blue" v-show="is_show"></div>
</div>
<div class="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>
<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>
Vue插槽指令
在数据信息交互的时候,父组件将数据传给子组件,子组件又将数据传给父组件,子组件仅仅起数据传递的作用。这种情况,可以通过插槽指令,避免传递数据
<div id="app">
<p>
<input type="text" v-model="info">
<button @click="addMsg">留言</button>
<ul>
<my_dic :msg=msg v-for="(msg,i) in msgs" :key="i">
<!--template通过v-slot绑定子组件内部slot插槽标签的name属性值-->
<!--在父组件模板的自定义子组件标签中,template是属于子组件模板-->
<template v-slot:del_btn>
<span class="del" @click="del_fn">x</span>
</template>
</my_dic>
</ul>
</p>
</div>
<script>
let my_dic = {
props: ['msg'],
// slot标签是用来在子组件中占位,name的值就是占位的对象
template: `
<li>
<slot name="del_btn"></slot>
<span>{{msg}}</span>
</li>`,
}
new Vue({
el: '#app',
components: {
my_dic
},
data: {
info: '',
msgs: JSON.parse(sessionStorage.msgs || '[]'),
},
methods: {
addMsg() {
if (this.info) {
this.msgs.unshift(this.info);
this.info = ''
sessionStorage.msgs = JSON.stringify(this.msgs);
}
},
del_fn(i) {
this.msgs.splice(i, 1)
sessionStorage.msgs = JSON.stringify(this.msgs);
}
}
})
</script>