VUE基础知识
代码基本结构
每一个vue文件由三部分组成,template
、script
、style
,分别对应html
、js
、css
,另外需要注意的是:template
中只允许有一个块状元素,通常情况下是div
,其他所有元素的标签都在这个块状元素中
// template即模版的意思,每一个vue文件里必须要有一个,在这里写HTML代码
<template>
<div id="app"></div>
</template>
// 在这里写js逻辑相关的代码
<script>
export default {
name: "app"
};
</script>
// 这里写样式代码
<style></style>
声明式渲染
差值表达式:进行数据的渲染,两个大括号{{}}
,与Js中的模板字符串相当
let str = "hello world";
let template = `<h2>${str}</h2>`;
<template>
<h2>{{title}}</h2>
</template>
<script>
// export default是固定格式,不需要纠结
export default {
// 模块的名字
name: "app",
// 页面中数据存放的地方
data() {
return {
title: "hello world"
};
}
};
</script>
<style scope>
h2 {
color: deeppink;
border: 1px solid #cccccc;
}
</style>
data
方法中用来存放数据或者全局变量;scope
可以理解为锁,将 css 代码锁在文本内,只在文本中生效
事件修饰符
模板中使用表达式
在差值表达式中可以进行简单的计算,或是书写三元表达式
,甚至是书写方法:
<template>
<div id="app">
<li>{{ goods[0].index + 1 }}---{{ goods[0].name }}</li>
<li>{{ goods[1].index + 1 }}---{{ goods[1].name }}</li>
<li>{{ goods[2].index + 1 }}---{{ goods[2].name }}</li>
<p>{{ flag?'你已经通过了考试':'你还没有通过考试' }}</p>
<button @click="exchange">转换</button>
<p>{{ message.split('').reverse().join('') }}</p>
</div>
</template>
v-model(双向绑定)
简单来说就是:改变message
变量的值,input
标签内的值也会发生变化;相反的,改变后者标签内的值,前者的变量值也会发生变化。
此外除了input
,还有text-area
和checkbox
,均可以使用。
<template>
<div class="food">
<p class="page">{{message}}</p>
<input type="text" v-model="message" placeholder="请输入你想输入的内容" />
<div class="check-box">
<input type="checkbox" value="新奥尔良鸡腿堡" v-model="checkedGoods" />
</div>
<div class="food-name">新奥尔良鸡腿堡</div>
<div class="food-price">¥24</div>
</div>
</template>
<script>
export default {
name: "app",
data() {
return {
message: "",
checkedGoods: []
};
}
};
</script>
v-on(触发事件绑定)
以点击事件为例,首先为元素添加点击事件,其语法是:
<button v-on:click="add(可以加上括号用于传递参数)">按钮</button>
//可以将 v-on 简写为 @
<button @click="add">按钮</button>
然后为事件添加方法:
<script>
export default {
name: "app",
data() {
return {
// 初始次数
counter:0
};
},
methods:{
add:function(){
// 这里的this指向当前的vue实例
this.counter++
}
}
};
</script>
v-bind(属性动态绑定)
HTML中的标签都有自己的属性,一般都是被写死的,但是我们现在可以利用v-bind
实现属性的动态绑定,即在属性前加上v-bind:
,也可以简写为:
。
<template>
<div id="app">
<img :src="imgUrl" v-bind:alt="imgText" />
</div>
</template>
<script>
export default {
name: "app",
// 数据
data() {
return {
imgUrl: 'https://#######',
imgText: '周杰伦演唱会图片'
};
}
};
</script>
v-if(条件渲染语句)
条件渲染语句就是根据不同的条件渲染不同的模块,可以与JS中的if
结合起来理解:
<p v-if="questions[0].type==='PICK'">{{ questions[0].content }}</p>
<p v-else-if="questions[1].type==='MULT'">{{ questions[1].content }}</p>
<p v-else>题目还没有加载进来...</p>
v-show(功能与 v-if 类似)
v-show 的用法与 v-if 相同,但是有一个区别:
- v-show 指令只是将标签的 display 属性设为 none;
- v-if 指令,如果不满足条件,则该标签将在 dom 中不存在;
v-for(循环渲染)
循环渲染数字
<ul>
<li v-for="item in 5" :key="item">{{ item }}</li>
</ul>
循环渲染数组
<ul>
<li v-for="(item,index) in nameList" :key="index">{{ index+1 }}---{{ item }}</li>
</ul>
循环渲染对象
<li v-for="(value,key,index)" :key="index"></li>
循环渲染数组中的对象
<ul>
<li v-for="(item,index) in books" :key="index">
{{ index+1 }}----{{ item.title }}----{{ item.author }}----{{ item.publishedTime }}
</li>
</ul>
watch(监听数据变化)
- 书写位置在
export default
对象中,是一个键值对; - 侦听的对象就是
data
中的变量,且侦听器的方法名要与data
中的变量名一致; - 每次当侦听的变量发生变化时,侦听器就会触发其中的方法;
- 如果想要获取上一次该变量的值,可以在侦听器的方法中传入两个参数
(newValue, oldValue)
。
<script>
export default {
name: 'app',
data() {
return {
add_num: 0,
old_data: [],
sort_data: [],
old_str: "",
sort_str: "",
}
},
methods: {
add: function() {
this.old_data.push(this.add_num);
this.old_str = this.old_data.join(",");
},
},
watch: {
old_data: function(newData,oldData) {
this.sort_data = [];
for(let i=0; i<this.old_data.length; i++) {
this.sort_data.push(this.old_data[i]);
}
this.sort_data.sort((a,b) => a-b);
this.sort_str = this.sort_data.join(",");
console.log(newData,oldData);
}
}
};
</script>
另外当侦听的值没有发生变化时,侦听器的方法是不会被触发的,并且页面第一次渲染也不会触发侦听器,如果我们需要在页面渲染第一次时触发侦听器,则需要使用侦听器的一个属性
immediate
,即在侦听器中将该属性设为true
。
<script>
export default {
name: "app",
watch: {
firstName: {
handler: function (newName, oldName) {
this.fullName = newName + " " + this.lastName;
},
immediate: true
}
}
};
</script>
computed(计算属性)
计算属性内部是一系列方法组成的键值对,键是方法名,值是方法体,是data
、methods
、watch
之后的又一个成员,与methods
类似,但是computed
具备两个属性:依赖(就是计算属性所需要的data中的数据)和 缓存(上一次计算得到的值)。
- 当计算属性的依赖发生变化时,计算属性会重新计算,然后返回新的计算结果;
- 计算属性的依赖不发生变化时,计算属性会返回缓存的值,不进行新的计算;
而方法则是在每一次访问时,执行方法体中的逻辑,然后返回新的计算结果。
<script>
export default {
name: "app",
data:function(){
return {
message:"我是天才派大星",
}
}
// 计算属性
computed:{
reverseMessage:function(){
return this.message.split('').reverse().join('')
}
}
};
</script>
:class(动态样式绑定)
- 类名的书写:如果是单个单词的类名
active
,直接由键值对构成;如果是由连字符连接的类名base-active
,则需要双引号或单引号; - 引号的规则:如果大括号是由双引号括起来的,则其中的类名则需要使用单引号括起来,反之则相反;
- 多类名写法:使用逗号隔开,添加即可;
- 类名后的变量是
Boolean
类型的,用于控制类名是否添加。
<div class="base" v-bind:class="{ active: isActive, 'base-active': true }"></div>
.active {
border: 1px solid green;
}
动态绑定的条件类型
可以使用变量、方法、表达式、计算属性等形式:
<span :class="{ 'new-appear': item.type === 'NEW' }">新</span>
computed: {
hoverObj: function () {
return {
//即如果后面的条件为true则为该标签添加类名hover
hover: this.index === 1,
};
},
},
对象语法:
<div v-bind:class="{ active: isActive ,hover:true,'after-hover':false}"></div>
数组语法:由于数组中的都是类名,所以需要带引号
<div v-bind:class="['red-style', 'font-style']"></div>
还可以在数组中使用对象:
<div v-bind:class="['red-style', 'font-style',{'redbg':isChoosed}]"></div>
:style(动态)
对象语法:与:class
语法不同,他的键值对是CSS样式的属性:值组成的键值对,且一般情况下除了数字,其他的值的字符串都需要用引号括起来,若属性中含有中划线则也需要括起来,因此我们可以使用驼峰命名法避免使用引号将属性括起来;除此之外还可以通过在data
中书写全局变量来改变style的书写位置。
需要注意的是:全局变量之间不能互相引用!
<div :style="{background:'red','font-weight':700,'font-size':'20px'}"></div>
<div :style="flexStyle"></div>
data:function(){
return {
flexStyle: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
alignItems: 'center',
flexWrap: 'no-wrap',
},
}
}
数组语法:与:class
类似,不同的是calss数组里面的是类名,需要引号,而style数组中的是变量名,所有不需要引号。
<div :style="[fontStyle,boxStyle]">这里是文字</div>
<div :style="[fontStyle, isActive ? boxStyle : colorBox]">这里是文字</div>