vue安装
好细的Vue安装与配置_vue配置_LCLANNADT的博客-CSDN博客
脚手架
src/main.js是应用的入口文件 可以在这里导入和配置Vue相关的插件、库、以及全局组件、指令
src/App.vue 这是应用的主组件,也是根组件,可以在这里定义应用的整体样式、布局 以及全局的数据和方法
src/components 用于存放应用的组件文件,可以在这里创建各种子组件,按需引入到主组件或其他组件中使用
src/views 存放应用的页面级组件文件 每个页面通常都对应一个独立的视图组件
src/router 管理应用的路由配置 可以添加新的路由和对应的组件,以实现页面间的导航和切换
路由
Vue基础知识总结 11:前端路由vue-router_哪 吒的博客-CSDN博客
语法
指令
vue指令是在 HTML 模板中以 v- 开头的特殊属性形式使用,用于将响应式数据绑定到 DOM 元素上或在 DOM 元素上进行一些操作。
v-bind:
动态绑定元素属性
<template>
<input v-bind:disabled="isDisabled" v-bind:value="inputValue">
</template>
<script setup>
import { ref } from 'vue';
const isDisabled = ref(false);
const inputValue = ref('DefaultValue');
</script>
动态绑定样式
<template>
<div v-bind:class="{ isActive: isActive }" v-bind:style="{ color: textColor, fontSize: fontSize }">
Vue,启动!
</div>
</template>
<script setup>
import { ref } from 'vue';
const isActive = ref(true);
const textColor = ref('red');
const fontSize = ref('20px');
</script>
动态绑定class对象
<template>
<div v-bind:class="classObject">
Vue,启动!
</div>
</template>
<script setup>
import { reactive } from 'vue';
const classObject = reactive({
isActive: true,
isBold: false,
});
</script>
动态绑定事件处理函数
<template>
<button v-bind:click="handleClick">{{ buttonText }}</button>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const buttonText = ref('ClickMe');
function handleClick() {
count.value++;
buttonText.value = `Clicked ${count.value} times`;
}
</script>
动态绑定元素属性对象
<template>
<div v-bind="elementProps">
Vue,启动!
</div>
</template>
<script setup>
import { reactive } from 'vue';
const elementProps = reactive({
id: 'myId',
class: 'myClass',
title: 'MyTitle',
});
</script>
可以实现动态更新属性、减少重复代码、简化样式和类绑定以及提供扩展性和灵活性。 v-for
用于根据源数据多次渲染元素或组件。通过遍历数组或对象的属性,可以循环生成多个相同的元素,并为每个元素绑定和更新动态数据。
<template>
<div>
<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const items = ref([
{ id: 1, name: '华蕴' },
{ id: 2, name: '中海' },
{ id: 3, name: '师大附小' }
]);
</script>
缩写
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
插值
{{xxx}}
<template>
<div class="TemplateSyntax">
<p>{{ text }}</p>
<p>{{ {name: 'jack'} }}</p>
<p>{{ 'Hello World!' }}</p>
<p>{{ isTrue == -1 }}</p>
<p>{{ isTrue ? '真' : '假' }}</p>
</div>
</template>
<script>
export default {
name:'TemplateSyntax',
data() {
return {
text: '这里是vue模板语法的内容',
isTrue: true
}
}
}
</script>
<style scoped>
p {
color: rgb(148, 118, 118);
}
.TemplateSyntax{
font-size: 10px;
float: left;
margin-left: 10px;
}
</style>
HTML
使用v-html指令时,Vue会将message中的HTML代码直接插入到对应的DOM节点中,并绕过了Vue的编译过程。这意味着<div v-html="message"></div>中的内容不会被Vue所控制,因此无法应用作用域样式。所以要用行内式来写样式
<template>
<div v-html="message" class="TemplateSyntax" style="font-size: 10px; float: left; margin-left: 10px; display: block; background-color: #5d3c3c;"></div>
</template>
<script>
export default {
name:'TemplateSyntax',
data() {
return {
message:'<h5>v-html指令输出代码</h5>'
}
}
}
</script>
或者用v-bind
<div v-html="message" v-bind:class="{TemplateSyntax:true}"> </div>
条件语句
v-if
用于根据特定条件来决定是否渲染或销毁元素。
根据给定的表达式的真假值来动态地控制元素的显示和隐藏。
<template>
<div>
<button @click="toggleDisplay">
切换
</button>
<div v-if="showMessage">
Vue,启动!
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const showMessage = ref(true);
function toggleDisplay() {
showMessage.value = !showMessage.value;
}
</script>
-
适用于:切换频率较低的场景
-
特点:不展示的DOM元素直接被移除
-
注意:
v-if
可以和v-else-if
、v-else
一起使用,但要求结构不能被打断
<template>
<div>
<p v-if="score >= 90">优秀</p>
<p v-else-if="score >= 60">及格</p>
<p v-else>不及格</p>
</div>
</template>
v-show
用于根据给定条件的真假值来控制元素的显示和隐藏。
通过修改 CSS 的 display
属性来控制元素的可见性,而不是从 DOM 中添加或移除元素,响应更快
<template>
<div>
<button @click="toggleDisplay">
切换
</button>
<div v-show="showMessage">
Vue,启动!
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const showMessage = ref(true);
function toggleDisplay() {
showMessage.value = !showMessage.value;
}
</script>
- 写法:
v-show="表达式"
- 适用于:切换频率较高的场景
- 特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
使用v-if
的时,元素可能无法获取到,而使用v-show
一定可以获取到
循环语句
遍历数组
<template>
<div>
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: '苹果' },
{ id: 2, name: '香蕉' },
{ id: 3, name: '橙子' }
]
};
}
};
</script>
遍历对象
//以第二个参数为键名
<template>
<div>
<ul>
<li v-for="(value, key) in user" :key="key">
{{ key }}: {{ value }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
user: {
name: 'cc',
age: 19,
email: '3296785939@qq.com'
}
};
}
};
</script>
//以第三个参数为索引
<template>
<div>
<ul>
<li v-for="(value, key,index) in user" :key="key">
{{index}}: {{ key }}: {{ value }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
user: {
name: 'cc',
age: 19,
email: '3296785939@qq.com'
}
};
}
};
</script>
显示过滤/排序后的结果
我们可以对数组的元素进行处理后再显示出来,一般可以通过创建一个计算属性,来返回过滤或排序后的数组
computed: {
evenNumbers() {
return this.numbers.filter(number => number % 2 === 0)
}
}
<ul>
<li v-for="n in evenNumbers">{{ n }}</li>
</ul>
v-for/v-if 联合使用
<div id="app">
<select @change="changeVal($event)" v-model="selOption">
<template v-for="(site,index) in sites" :site="site" :index="index" :key="site.id">
<!-- 索引为 1 的设为默认值,索引值从0 开始-->
<option v-if = "index == 1" :value="site.name" selected>{{site.name}}</option>
<option v-else :value="site.name">{{site.name}}</option>
</template>
</select>
<div>您选中了:{{selOption}}</div>
</div>
<script>
const app = {
data() {
return {
selOption: "Runoob",
sites: [
{id:1,name:"Google"},
{id:2,name:"Runoob"},
{id:3,name:"Taobao"},
]
}
},
methods:{
changeVal:function(event){
this.selOption = event.target.value;
alert("你选中了"+this.selOption);
}
}
}
Vue.createApp(app).mount('#app')
</script>
监听
为什么需要监听属性?
在前端开发中,属性的变化经常会触发应用的不同行为,例如更新UI、发送HTTP请求、执行动画等。Vue.js作为一个现代的JavaScript框架,提供了一种响应式的数据绑定机制,使属性的变化能够自动地反映在UI上。然而,有时需要更进一步,需要在属性变化时执行一些自定义的逻辑。
监听属性的方法
Vue 3 中的属性监听可以通过 watch
函数或 watchEffect
函数来实现。
1. watch
const stop = watch(source, callback, options);
source
是要监听的属性,可以是一个 ref、reactive 对象或计算属性。callback
是回调函数,当 source
发生变化时会被触发。options
是一个可选参数对象,用于配置监听行为。
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`count 变为 ${newValue},之前是 ${oldValue}`);
});
事件
v-on
监听事件
点击事件、鼠标事件、键盘事件
绑定方法
可以直接绑定到一个方法 也可以内联JavaScript语句。有多个方法时,用‘,’分隔。
<template>
<div>
<button v-on:click="handleClick">点击我</button>
<div v-on:mouseenter="handleMouseEnter" v-on:mouseleave="handleMouseLeave">鼠标进入/离开区域</div>
<input v-on:input="handleInputChange" placeholder="输入框">
<form v-on:submit="handleSubmit">
<button type="submit">提交</button>
</form>
<select v-on:change="handleSelectChange">
<option value="option1">1</option>
<option value="option2">2</option>
<option value="option3">3</option>
</select>
<button @click="say('hi')">Say hi</button>
</div>
</template>
<script>
export default {
methods: {
handleClick: function() {
console.log('点击事件被触发!');
},
handleMouseEnter: function() {
console.log('鼠标进入事件被触发!');
},
handleMouseLeave: function() {
console.log('鼠标离开事件被触发!');
},
handleInputChange: function(event) {
console.log('输入框内容变化事件被触发!');
console.log('输入框的值:', event.target.value);
},
handleSubmit: function(event) {
event.preventDefault();
console.log('表单提交事件被触发!');
},
handleSelectChange: function(event) {
console.log('下拉框选项变化事件被触发!');
console.log('选择的值:', event.target.value);
},
say(message) {
alert(message)
}
}
}
</script>
方法传参
<template>
<button v-on:click="handleClick('Hello', $event)">点击我</button>
</template>
<script>
export default {
methods: {
handleClick(message, event) {
console.log(message);
console.log(event);
}
}
}
</script>
修饰符
事件修饰符
stop
- 阻止冒泡prevent
- 阻止默认事件capture
- 阻止捕获self
- 只监听触发该元素的事件once
- 只触发一次left
- 左键事件right
- 右键事件middle
- 中间滚轮事件- passive - 事件的默认行为立即执行,无需等待事件回调执行完毕
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>
<!-- click 事件只能点击一次 -->
<a v-on:click.once="doThis"></a>
按键修饰符
Vue为一些常用的按键提供了别名
.enter
.tab
.delete
(捕获 "删除" 和 "退格" 键).esc
.space
.up
.down
.left
.right
系统按键修饰键:
.ctrl
.alt
.shift
.meta
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />
<!-- Ctrl + 点击 -->
<div @click.ctrl="doSomething">Do something</div>
.exact 修饰符
.exact 修饰符允许控制触发一个事件所需的确定组合的系统按键修饰符。
<!-- 当按下 Ctrl 时,即使同时按下 Alt 或 Shift 也会触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 仅当按下 Ctrl 且未按任何其他键时才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 仅当没有按下任何系统按键时触发 -->
<button @click.exact="onClick">A</button>
鼠标按钮修饰符:
.left
.right
.middle
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
样式绑定
class属性绑定
<div :class="{ 'active': isActive }"></div>
:class指令可以与普通的class属性共存
<div class="static" :class="{ 'active' : isActive, 'text-danger' : hasError }">
</div>
class 数组
<div class="static" :class="[activeClass, errorClass]"></div>
用三元表达式来切换
<div class="static" :class="[isActive ? activeClass : '', errorClass]"></div>
style(内联样式)
<div :style="{ color: 'red', fontSize:'15px' }">Vue</div>
style直接绑定样式对象
<div :style="styleObject">Vue</div>
style数组
<div :style="[baseStyles, overridingStyles]">Vue</div>
多重值 只会绑定最后一个浏览器支持的值
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
表单
表单绑定
v-model
用于实现数据的双向绑定。它主要用于表单元素,将表单元素的值与 Vue 实例的数据属性进行绑定,当表单元素的值发生变化时,Vue 实例中的数据也会随之更新,反之亦然。
<template>
<div>
<input v-model="message" placeholder="请输入消息">
<p>输入的消息:{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
};
}
}
</script>
文本
<p>Message is: {{ message }}</p>
<input v-model="message" />
文本域
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
复选框
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
<template>
<div>
<input v-model="message" placeholder="请输入消息">
<p>输入的消息:{{ message }}</p>
</div>
</template>
<script>
export default {
name:'VmodelExample',
data() {
return {
message: ''
};
}
}
</script>
<!-- <<template>
<div>
<input v-model="name" type="text" required>
<p v-if="!name">请输入你的姓名</p>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
name: 'VmodelExample',
setup() {
const name = ref('');
return {
name
};
}
}
</script>
<template>
<div>
<input v-model="email" type="text">
<p v-if="!email || !emailRegex.test(email)">请输入有效邮箱</p>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
name: 'VmodelExample',
setup() {
const email = ref('')
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return {
email,
emailRegex
}
}
}
</script>
<template>
<div>
<form @submit="onSubmit">
<input v-model="name" type="text" placeholder="请输入姓名">
<button type="submit">提交</button>
</form>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
name: 'VmodelExample',
setup() {
const name = ref('')
const onSubmit = (event) => {
event.preventDefault()
console.log(`Name: ${name.value}`)
}
return {
name,
onSubmit
}
}
}
</script>
<template>
<div>
<form @submit="onSubmit">
<input v-model.lazy="name" type="text">
<button type="submit">Submit</button>
<button type="button" @click="onReset">重置</button>
</form>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
name: 'VmodelExample',
setup() {
const name = ref('')
const onSubmit = (event) => {
event.preventDefault()
console.log(`Name: ${name.value}`)
}
const onReset = () => {
name.value = ''
}
return {
name,
onSubmit,
onReset
}
}
}
</script> -->
表单验证
必填字段验证
Vue3中可以通过设置HTML5的required
属性或使用自定义的验证规则来实现必填字段验证。
<template>
<div>
<input v-model="name" type="text" required>
<p v-if="!name">请输入你的姓名</p>
</div>
</template>
<script>
export default {
setup() {
const name = ref('')
return {
name
}
}
}
</script>
格式验证
Vue3中可以使用正则表达式或第三方插件来实现格式验证。
<template>
<div>
<input v-model="email" type="text">
<p v-if="!email || !emailRegex.test(email)">请输入有效邮箱</p>
</div>
</template>
<script>
export default {
setup() {
const email = ref('')
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return {
email,
emailRegex
}
}
}
</script>
表单处理
获取表单数据
我们可以使用ref
或reactive
来定义表单数据,并通过访问对应的引用变量来获取用户输入的数据。eg:通过name.value
获取用户输入的姓名
<template>
<div>
<form @submit="onSubmit">
<input v-model="name" type="text">
<button type="submit">提交</button>
</form>
</div>
</template>
<script>
export default {
setup() {
const name = ref('')
const onSubmit = (event) => {
event.preventDefault()
console.log(`Name: ${name.value}`)
}
return {
name,
onSubmit
}
}
}
</script>
表单重置
Vue3提供了reset
方法和v-model
指令的.lazy
修饰符来实现表单重置。
<template>
<div>
<form @submit="onSubmit">
<input v-model.lazy="name" type="text">
<button type="submit">Submit</button>
<button type="button" @click="onReset">重置</button>
</form>
</div>
</template>
<script>
export default {
setup() {
const name = ref('')
const onSubmit = (event) => {
event.preventDefault()
console.log(`Name: ${name.value}`)
}
const onReset = () => {
name.value = ''
}
return {
name,
onSubmit,
onReset
}
}
}
</script>
使用.lazy
修饰符来延迟表单元素的更新,直到点击提交按钮时才将数据同步到name
变量中。当用户点击重置按钮时,我们可以通过将name
重置为空字符串来实现表单重置。
组件
组件(Component)
是 Vue.js 最强大的功能之一。
组件可以扩展 HTML 元素,封装可重用的代码。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
vue 组件组成结构
每个 .vue 组件都由 3 部分构成,分别是:
template -> 组件的模板结构
script -> 组件的 JavaScript 行为
style -> 组件的样式
组件的 template 节点
<template>
<!-- 当前组件的Dom结构需要定义到 template 标签的内部 -->
</template>
组件的 script 节点
<script>
// 导入组件
import MyHeader from './MyHeader.vue'
export default {
// 导出需要定义的方法
//给当前组件定义一个名称
name: 'MyApp',
components: {
MyHeader,
},
//组件中的 data 必须是函数
data() {
return {
username: 'zs',
count: 0,
}
},
methods: { // 处理函数
addCount() {
this.count++
},
},
}
</script>
组件注册的两种方式
vue 中注册组件的方式分为“全局注册”和“局部注册”两种,其中:
-
被全局注册的组件,可以在全局任何一个组件内使用
-
被局部注册的组件,只能在当前注册的范围内使用
-
如果某些组件在开发期间的使用频率很高,推荐进行全局注册;
如果某些组件只在特定的情况下会被用到,推荐进行局部注册。
//调用 app.component() 方法全局注册组件
app.component(Swiper.name, Swiper)
app.component(Test.name, Test)
export default {
name: 'MyApp',
components: { // 通过 components 节点注册私有组件
// 注册
MyStyle
}
}
组件样式
1.scoped属性
style节点的 scoped 属性,用来自动为每个组件分配唯一的“自定义属性",并自动为当前组件的 DOM 标签和 style 样式应用这个自定义属性,防止组件的样式冲突问题。
2./deep/ 样式穿透
如果给当前组件的 style 节点添加了 scoped 属性,则当前组件的样式对其子组件是不生效的。如果想让某些样
式对子组件生效,可以使用 /deep/ 深度选择器。
组件的props
other:
待完善