Vue教程
Vue简介
Vue是一个渐进式的JavaScript框架,易学易用,性能出色,适用场景丰富的web前端框架。
Vue API
选项式API 和 组合式API
选项式API例子:
组合式API例子:
开发前的准备
安装node.js,版本要求15以上。
创建Vue项目:
npm init vue@latest
填写提示的相关信息
项目名称不要包含大写
然后执行:
npm install
npm run dev
开发环境
看的视频里说推荐用VS code,但我还是选择用IDEA。
创建项目之后,选择
npm install
得到的项目结构:
各文件夹用途:
node_modules —Vue项目的运行依赖文件夹
public —资源文件夹
src —源码文件夹
index.html —入口HTML文件
package.json —信息描述文件
vite.config.js —Vue配置文件
模板语法
Vue使用一种基于HTML的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的DOM上。所有的Vue模板都是语法层面合法的HTML,可以被符合规范的浏览器和HTML解析器解析。
文本插值
<template>
<h3>模板语法</h3>
<p>{{ msg }}</p>
</template>
<script>
export default {
data(){
return{
msg:"hello world"
}
}
}
</script>
效果:
JavaScript表达式
有结果的JavaScript表达式可以放在{{}}
中进行展示
<template>
<h3>模板语法</h3>
<p>{{ msg }}</p>
<p>{{ number + 1 }}</p>
<p>{{ ok ? "yes" : "no" }}</p>
<p>{{ message.split("").reverse().join("") }}</p>
</template>
<script>
export default {
data(){
return{
msg:"hello world",
number:10,
ok:true,
message:"大家好"
}
}
}
</script>
无效:赋值语句、条件控制语句(If)
原始HTML
引入HTML页面需要使用v-html
指令
<template>
<h3>模板语法</h3>
<p>{{ msg }}</p>
<p>{{ number + 1 }}</p>
<p>{{ ok ? "yes" : "no" }}</p>
<p>{{ message.split("").reverse().join("") }}</p>
<p v-html="rawHTML"></p>
</template>
<script>
export default {
data(){
return{
msg:"hello world",
number:10,
ok:true,
message:"大家好",
rawHTML:"<a href='https://www.bilibili.com/'>B站</a>"
}
}
}
</script>
属性绑定
{{}}
不能在HTML属性中使用,想要响应式地绑定一个attribute,应该使用v-bind
指令。
<template>
<div v-bind:class="dynamicClass" v-bind:id="dynamicId">测试</div>
</template>
<script>
export default {
data(){
return{
dynamicId:"appid",
dynamicClass:"appclass"
}
}
}
</script>
v-bind
指令只是将元素的id 属性与组件的dynamicId
属性保持一致。如果绑定的值是null
或者undefined
,那么该属性将会从渲染的元素上移除。
简写:省略v-bind
<div :class="dynamicClass" :id="dynamicId">测试</div>
条件渲染
指令:
v-if
,v-else
,v-else-if
,
v-show
<template>
<h3>条件渲染</h3>
<div v-if="flag">你能看见我吗</div>
<div v-else>那你还是看看我吧</div>
<div v-if=" type === 'A' ">A</div>
<div v-else-if=" type === 'B' ">B</div>
<div v-else-if=" type === 'C' ">C</div>
<div v-else-if="type === 'D' ">D</div>
<div v-show="flag">v-show测试</div>
</template>
<script>
export default {
data(){
return {
flag:true,
type:"C"
}
}
}
</script>
v-if
和 v-show
的区别:
列表渲染
指令:v-for
<template>
<h3>列表渲染</h3>
<p v-for="item in names">{{item}}</p>
</template>
<script>
export default {
data() {
return {
names:["A", "B", "C"]
}
}
}
</script>
也可以是item of items
,更接近JavaScript迭代器风格。
通过key管理状态
key的作用在于更新时不进行就地更新(也就是不重新渲染,节省性能),而是更新元素的顺序。
<template>
<h3>key属性添加到v-for中</h3>
<p v-for="(item, index) in names" :key="index">{{item}}</p>
</template>
<script>
export default {
data(){
return{
names:["A", "B", "C"]
}
}
}
</script>
事件处理
使用v-on
来监听DOM事件,并在事件触发时执行对应的JavaScript。
用法:v-on:click="methodName"
或 @click="handler"
事件处理器的值可以是:
内联事件处理器:事件被触发时执行内联的JavaScript语句
方法事件处理器:一个指向组件上定义的方法的属性名或路径
内联事件处理器
<template>
<h3>内联事件处理器</h3>
<button v-on:click="count++">count</button>
<button @click="count++">count</button>
<p>{{count}}</p>
</template>
<script>
export default {
data(){
return{
count:0
}
}
}
</script>
方法事件处理器
<template>
<h3>方法事件处理器</h3>
<button @click="addCount">count</button>
<p>{{count}}</p>
</template>
<script>
export default {
data(){
return{
count:0
}
},
methods:{
addCount(){
this.count++
console.log("点击了")
}
}
}
</script>
事件传参
事件参数可以获取Event对象和通过事件传递数据
代码中的e:
<template>
<h3>方法事件处理器</h3>
<button @click="addCount">count</button>
<p>{{count}}</p>
</template>
<script>
export default {
data(){
return{
count:0
}
},
methods:{
addCount(e){
this.count++
console.log(e)
}
}
}
</script>
获取列表中的内容
<template>
<h3>事件传参</h3>
<p @click="clickEvent(item)" v-for="(item, index) in names" :key="index">{{item}}</p>
</template>
<script>
export default {
data(){
return{
names:["A", "B", "C"]
}
},
methods:{
clickEvent(message){
console.log(message)
}
}
}
</script>
传递参数的过程中获取Event对象
<template>
<h3>事件传参</h3>
<p @click="clickEvent(item, $event)" v-for="(item, index) in names" :key="index">{{item}}</p>
</template>
<script>
export default {
data(){
return{
names:["A", "B", "C"]
}
},
methods:{
clickEvent(message, e){
console.log(message)
console.log(e)
}
}
}
</script>
事件修饰符
例如.prevent
阻止默认事件,.stop
阻止事件冒泡
<template>
<h3>事件修饰符</h3>
<a @click.prevent="clickEvent" href="https://www.bilibili.com/">B站</a>
</template>
<script>
export default {
data(){
return{
}
},
methods:{
clickEvent(){
console.log("点击了")
}
}
}
</script>
数组变化侦测
变更方法
UI会更新
<template>
<button @click="add">添加元素</button>
<p v-for="(item, index) in names">{{item}}</p>
</template>
<script>
export default {
data(){
return{
names:["A", "B", "C"]
}
},
methods:{
add(){
this.names.push("D")
}
}
}
</script>
不可变方法
UI不会更新
计算属性
有一些逻辑判断可以放在计算属性中,计算属性和methods的区别在于,如果数据没有发生更改,多次调用计算属性,返回的是同一个值,不会重新计算,而函数每次都会重新计算。
<template>
<h3>计算属性</h3>
<p>{{isEmpty}}</p>
</template>
<script>
export default {
data(){
return{
peoples:{
names:"zhangshuai",
ages:[1,2,33]
}
}
},
computed:{
isEmpty(){
return this.peoples.ages.length > 0 ? "yes" : "No"
}
}
}
</script>
class绑定
<template>
<!-- 通过对象的方式绑定-->
<p :class="{'active':isActive, 'text-danger':hasError}">class样式绑定1</p>
<p :class="classObject">class样式绑定2</p>
<!-- 通过数组绑定-->
<p :class="[arrActive, arrHasError]">class样式绑定3</p>
<p :class="[isActive ? 'active text-danger' : '']">class样式绑定4</p>
<!-- 数组里嵌套对象,对象不能嵌套数组-->
<p :class="[isActive ? 'active' : '', {'text-danger': hasError}]">class样式绑定5</p>
</template>
<script>
export default {
data(){
return{
isActive:true,
hasError:true,
classObject:{
'active':true,
'text-danger':false
},
arrActive:"active",
arrHasError:"text-danger"
}
}
}
</script>
<style>
.active{
color: aqua;
}
.text-danger{
font-size: 30px;
}
</style>
style绑定
<template>
<p :style="{color:activeColor, fontSize:fontSize + 'px'}">style样式绑定</p>
<p :style="styleObject">style样式绑定2</p>
</template>
<script>
export default {
data(){
return{
activeColor:"green",
fontSize:30,
styleObject:{
color:"green",
fontSize:"30px"
}
}
}
}
</script>
侦听器
响应式数据发生变化时触发一个函数
函数名必须与侦听的数据对象保持一致
<template>
<p>侦听器</p>
<p>{{message}}</p>
<button @click="updateHandle">change message</button>
</template>
<script>
export default {
data(){
return{
message:"hello"
}
},
methods:{
updateHandle(){
this.message = "world"
}
},
// 侦听器
watch:{
message(newValue, oldValue){
console.log(newValue, oldValue)
}
}
}
</script>
表单输入绑定
指令:v-model
输入框绑定
<template>
<form>
<input v-model="message">
</form>
<p>{{message}}</p>
</template>
<script>
export default {
data(){
return{
message:""
}
}
}
</script>
模板引用
通过ref
获取原始DOM元素
<template>
<div ref="container" class="container">{{content}}</div>
<input type="text" ref="username">
<button @click="getElementHandle">获取元素</button>
</template>
<script>
export default {
data(){
return{
content:"内容"
}
},
methods:{
getElementHandle(){
this.$refs.container.innerHTML = "hhh";
console.log(this.$refs.username.value);
}
}
}
</script>
组件组成
组件最大的优势就是可复用性
当使用构建步骤时,我们一般会将Vue组件定义在一个单独的vue文件中,这被叫做单文件组件(简称SFC)
组件嵌套关系
组件注册方式
全局注册
局部注册
组件传递数据
组件和组件之间不是完全独立的,组件和组件之间是可以传递数据的
传递数据的解决方案是props
只能父组件传给子组件
组件传递多种数据类型
组件传递props 效验
Vue组件可以更加细致的声明对传入的props的校验要求