一、基本语法:
1.文件结构说明:
(1)App.vue(主vue,其他.vue组件文件一样的结构):
<template> //1.vue模版部分,使用html标签实现页面布局
<html标签>...<html标签>
...
</template>
<script> //2.vue代码部分,定义vue属性、计算属性、函数、组件等
export default {
name: 'App', //当前vue名称
..
}
</script>
<style> //3.样式部分,编写CSS样式
...
</style>
(2)main.js(主JS,入口):
import { createApp } from 'vue' //导入vue的createApp系统函数
import App from './App.vue' //导入上面的App.vue
const app = createApp(App) //创建vue应用,
app.mount('#app') //挂载到根节点上
2.属性(类似Java变量):
(1)普通属性:
方式一,选项式定义属性:
<script>
export default {
data() { //定义属性列表,在vue中使用this.属性名,在html标签中使用:{{ 属性名 }}
return {
属性名: '值', //使用:{{ 属性名 }}
列表属性名: ['值1', '值2'], //使用:{{ 列表属性名[下标] }}
对象属性名: {字段1: '值', 字段2: 值}, //使用:{{ 对象属性名.字段1 }}
}
},
}
</script>
方式二,组合式定义属性:
<script setup>
import { ref, reactive } from 'vue' //导入ref与reactive
const 属性名 = ref('值') //ref适用基础类型,使用:{{ 属性名 }}
const 列表属性名 = reactive(['值1', '值2']) //reactive适用列表或对象类型,使用:{{ 列表属性名[下标] }}
const 对象属性名 = reactive({字段1: '值', 字段2: '值'}) //使用:{{ 对象属性名.字段1 }}
</script>
使用属性:
<template>
{{ 属性名 }} {{ 列表属性名[下标] }} {{ 对象属性名.字段1 }}
</template>
(2)计算属性(computed):
方式一,选项式定义计算属性:
<script>
export default {
computed: { //定义计算属性列表
//计算属性名: function(){ //等同下面简写
计算属性名(){ //名称自定义
return 属性名 + 10; //当表达式中属性值变化时才会重新计算
},
},
}
</script>
方式二,组合式定义计算属性:
<script setup>
import { ref, computed } from 'vue' //导入computed
const 属性名 = ref(原数值)
const 计算属性名 = computed(() => { //只含get方法时用此实现方式
return 属性名.value + 10 //当表达式中属性值变化时才会重新计算
})
const 计算属性名2 = computed({ //含get/set方法时用此实现方式
get() {
return 属性名.value + 10 //当表达式中属性值变化时才会重新计算
},
set(newValue) {
属性名.value = newValue
}
})
</script>
(3)监听属性(watch):
方式一,选项式定义监听属性:
<script>
export default {
watch: { //定义需要被监听值改变的属性列表,当属性值改变时触发
//属性名: function(){ //等同下面简写
属性名(newValue, oldValue){ //属性名为data中定义的属性,参数为旧值,改变后的新值
//此处编写属性值改变后的逻辑
},
},
}
</script>
方式二,组合式定义监听属性watch:
说明:不加immediate:true配置时,只有属性值改变时才触发监听
<script setup>
import { ref, reactive, watch } from 'vue' //导入watch
const 属性名 = ref(0)
const 对象属性名 = reactive({ 属性1: 0 })
watch(属性名, (newValue, oldValue) => { //监听基本类型属性,值改变时触发
//...
}, { immediate: false, once: false }) //immediate:true表示监听器创建时立刻触发监听, once:true表示当属性值变化时仅触发一次
watch(() => 对象属性名.属性1, (newValue, oldValue) => { //监听对象类型属性,值改变时触发
//...
})
watch([属性名1, 属性名2 ], ([newValue1, newValue2]) => { //监听属性列表
//...
})
</script>
方式三,组合式定义监听属性watchEffect:
说明:监听器创建时立刻触发监听,且属性值改变时触发监听
<script setup>
import { ref, reactive, watchEffect } from 'vue' //导入watchEffect
const 属性名 = ref(0)
const 对象属性名 = reactive({ 属性1: 0 })
watchEffect(() => { //不需要监听指定属性
console.log(属性名.value + " " + 对象属性名.属性1) //会自动监听使用到的属性值
})
</script>
3.函数:
(1)生命周期函数(vue自带):
方式一,选项式实现生命周期函数:
<script>
export default {
beforeCreate(){ //实例生成之前执行
},
created(){ //实例生成之后执行
},
beforeMount(){ //内容显示到页面之前执行
},
mounted(){ //内容显示到页面之后执行
},
beforeUpdate(){ //data中数据变化,页面更新前执行
},
updated(){ //data中数据变化,页面更新后执行
},
beforeUnmount(){ //页面失效时执行
},
unmounted(){ //页面失效,且dom销毁之后执行
}
}
</script>
方式二,组合式实现生命周期函数:
<script setup>
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue'
onBeforeMount(() => { //内容显示到页面之前执行
})
onMounted(() => { //内容显示到页面之后执行
})
onBeforeUpdate(() => { //data中数据变化,页面更新前执行
})
onUpdated(() => { //data中数据变化,页面更新后执行
})
onBeforeUnmount(() => { //页面失效时执行
})
onUnmounted(() => { //页面失效,且dom销毁之后执行
})
</script>
(2)自定义函数:
方式一,选项式定义函数:
<script>
export default {
methods: { //此处定义函数列表
函数名(){ //此处的this指向app本身,可以"this.属性名"方式使用属性
//...代码
},
函数名: (param1) => { //箭头函数,此处的this指向window
//...代码
}
}
}
</script>
方式二,组合式定义函数:
<script setup>
function 函数名(){ //定义函数
//...
}
</script>
使用函数:
<template>
<div v-on:click="函数名">点击触发函数</div>
</template>
4.指令(v-xxx):
(1)条件语句:
v-if语句:
<div v-if="vue属性名 或 布尔表达式">...</div> //vue属性值为true或false
<div v-else-if="vue属性名 或 布尔表达式">...</div>
<div v-else="vue属性名 或 布尔表达式">...</div>
v-show(显示或隐藏):
<div v-show="vue属性名 或 布尔表达式">...</div> //vue属性值为true或false
(2)v-for(循环语句):
循环列表:
<div v-for="(item, index) in vue列表属性名" v-bind:key="item"> //index为下标, item为列表中每个值
当前第{{index}}条的值为 :{{item}}
<div>
循环对象字段:
<div v-for="(value, key, index) in vue对象属性名"> //key为字段名, value为字段值,index为下标
字段名为{{key}} ,字段值为{{value}}
<div>
(3)v-html(插入html标签):
<div v-html="vue属性名"></div> //vue属性值为html标签,例<html标签>...</html标签>
(4)v-bind绑定html标签属性(给标签属性赋值):
格式:<html标签 v-bind:标签属性名="vue属性名" />
或简写: <html标签 :标签属性名="vue属性名" />
例:
<a v-bind:href="vue属性名">点击跳转</a> //vue属性值为超链接,例http://www.xxx.com
<1>绑定html标签class属性设置样式:
定义样式:
<style>
.样式名1 {
width: 20px; //样式字段列表
Height: 20px;
}
.样式名2 {
background: red; //样式字段列表
}
</style>
定义属性列表:
<script>
export default {
data() {
return {
属性名0: true, //是否使用指定样式, true使用,false不使用
属性名1: '样式名1', //供列表方式使用样式
属性名2: '样式名2', //供列表方式使用样式
对象属性名: {‘样式名1’: true, ‘样式名2’: true}, ///对象方式使用样式
}
},
}
</script>
是否使用指定样式:
<div :class="{'样式名1': vue属性名0, '样式名2': vue属性名0}"></div>
列表方式使用样式:
<div :class="[vue属性名1, vue属性名2]"></div>
对象方式使用样式:
<div :class="vue对象属性名"></div>
<2>绑定html标签style属性设置样式:
定义属性列表:
<script>
export default {
data() {
return {
属性名: '20px', //属性值为样式字段值
对象属性名1: {width: "20px", height: "20px"}, ///对象字段名为样式字段
对象属性名2: {color: "red"}, ///供列表方式
}
},
}
</script>
属性值为样式字段值:
<div :style="{width: vue属性名}"></div> //width为CSS样式字段宽度
对象字段名为样式字段:
<div :style="vue对象属性名1"></div>
列表方式:
<div :style="[vue对象属性名1, vue对象属性名2]"></div>
(5)v-model双向绑定表单(属性与表单绑定):
修饰符:
v-model.lazy -将(默认)输入时触发事件 改为 失去焦点时触发事件
v-model.number -将原值字符串类型转为数值类型
v-model.trim -去掉首尾空格
使用:
<input type="text" v-model="vue属性名"> //1.单行文本框,显示属性值在文本框中
<input v-model.lazy="vue属性名" > //单行文本框修饰符使用,可以为lazy、number、trim
<textarea v-model="vue属性名" /> //2.大文本,显示属性值在大文本框中
<input type="radio" value="值1" v-model="vue属性名"> //3.单选框,value值与vue属性值一致时选中此单选框,例vue数据中:data: {vue属性名: '值1']}
<input type="checkbox" value="值1" v-model="vue数组属性名"> //4.复选框,value值在vue数组中时选中此复选框,例vue数据中:data: {vue数组属性名: ['值1', '值2']}
<select v-model="vue属性名"> //5.下拉选择列表(单选),例vue数据中:data: {vue属性名: '值1'}
<option value="值1">...</option> //value值与vue属性值一致时选中此item项
<option value="值2">...</option>
</select>
<select v-model="vue数组属性名" multiple> //下拉选择列表(多选),例vue数据中:data: {vue数组属性名: ['值1', '值2']}
<option value="值1">...</option> //value值与vue属性值一致时选中此item项
<option value="值2">...</option> //value值与vue属性值一致时同时选中此item项
</select>
(6)v-on(事件处理):
<div v-on:click="函数名">点击调用函数</div> //函数名也可以换成表达式
或简写方式
<div @click="函数名">点击调用函数</div>
或动态方式,绑定的html标签属性名由vue属性值决定,vue属性值必须是html标签存在的属性名
<div @[vue属性]="..."></div>
事件修饰符:
@click.stop - 阻止冒泡
@click.prevent - 阻止默认事件
@click.capture - 阻止捕获
@click.self - 只监听触发该元素的事件
@click.once - 只触发一次
@click.left - 左键事件
@click.right - 右键事件
@click.middle - 中间滚轮事件
事件修饰符例(阻止表单action事件):
<form action="..." @click.prevent="函数名">...</form>
(7)v-once让标签只渲染一次:
<div v-once>{{vue属性名}}</div> //首次加载时使用vue属性值,后面vue属性值改变时,此处显示不会变
(8)ref获取DOM节点与组件引用:
在html标签中使用ref传入引用名:
<template>
<html标签或组件名 ref="引用名">..</html标签或组件名>
</template>
方式一,选项式获取标签的引用:
this.$refs.引用名 //获取html标签或组件标签的引用
方式二,组合式获取标签的引用:
<script setup>
import { ref } from 'vue'
const 标签引用名 = ref(null) //固定写法:ref(null)
</script>
5.<Teleport>将内容移到指定html标签内:
<template>
...
<Teleport to="html标签名或者标签ID">
<div>需要移动的内容</div>
</Teleport>
</template>
二、组件:
1.创建组件文件(放在工程/src/components目录下):
说明:组件是单个文件,例:文件名.vue
实现组件内容:
<template> //1.vue模版部分,使用html标签实现页面布局
<html标签>...<html标签>
...
</template>
<script> //2.vue代码部分,定义vue属性、计算属性、函数、组件等
export default {
name: '单文件组件名',
//props: ['组件属性名'], //接收组件标签属性值
props: { //带有验证的属性
组件属性名1: String, //单个类型,属性值必须为此类型
组件属性名2: [String, Number, Boolean, Array, Object, Date, Function, Symbol], //多个类型,属性值可以为列表中的任意一种类型
组件属性名3: {
type: Object, //对象类型
//required: true, //属性值不能为空
//default: "默认值", //基本类型时,设置默认值
default: function () { //对象或数组类型时,设置默认值必须用此方式
return { 字段名: '值' } //返回一个对象
},
validator: function (value) { // 自定义验证函数
return 验证表达式
}
}
},
inheritAttrs: false, //false时丢弃传入的属性。默认true,父组件使用子组件时,传入子组件props中未定义的属性时,会将该属性添加到子组件的标签上,子组件有多个标签时传入的属性被丢弃,想要不丢弃得在子组件标签上加v-bind="$attrs",例:<div v-bind="$attrs">...</div>
}
</script>
<!-- 3.样式,scoped限制以下样式只对当前组件生效 -->
<style scoped>
...
</style>
2.注册组件:
(1)注册为全局组件:
说明:main.js中注册组件,在其他vue文件中使用(使用时无需import组件文件)
import { createApp } from 'vue' //导入vue的createApp系统函数
import App from './App.vue' //导入App.vue
import 组件名 from './components/组件文件名.vue' //导入组件文件
const app = createApp(App) //创建vue应用,
app.component('组件名', 组件名) //注册为全局组件,任意.vue文件中均可使用此组件
app.mount('#app') //挂载到根上
(2)注册为局部组件:
说明:在使用组件的vue文件中注册组件+使用
<script>
import 组件名 from './components/组件文件名.vue' //导入上面的组件文件
export default {
components: { //定义局部组件列表,仅限当前文件中使用此组件
组件名,
}
}
</script>
3.使用注册的组件:
<template>
<组件名 组件属性名="值"/>
</template>
4.子组件向父组件通信:
(1)父组件监听事件:
<template>
<子组件名 @事件名="父函数名"></子组件> <!-- 监听子组件事件(接收子组件数据),触发时调自已的函数,接收参数值并处理 -->
</template>
<script>
import 子组件名 from '@/components/子组件文件名.vue';
export default {
methods: {
父函数名(参数名){ //此方法接收子组件触发事件时传入的参数
//此处处理从子组件接收过来的数据
}
},
components: {
子组件名
}
}
</script>
(2)子组件中触发父组件中监听的某个事件并传递数据:
export default {
emits: ['事件名'], //定义事件列表
//emits: { //定义事件列表,对触发事件加条件判断
// 事件名: (参数名) => {
// return true //返回false时不触发事件
// }
//},
methods: {
函数名() { //此函数仅仅用于调用,触发以下代码
this.$emit(‘事件名’, 参数值); //子组件触发上面父组件中的事件,传递数据
}
},
}
</script>
5.子组件与父组件数据双向绑定:
(1)父组件实现:
<template>
<子组件名 v-model:子组件的组件属性名="父的属性名"></子组件> <!-- v-model固定,用于双向绑定,当子组件的组件属性名为modelValue时,简写为v-model=”父的属性名” -->
</template>
<script>
import 子组件名 from '@/components/子组件文件名.vue';
export default {
data(){
return {
父的属性名: '值',
}
},
components: {
子组件名
}
}
</script>
(2)子组件实现:
export default {
props: {
'子组件的组件属性名': String, //名称为modelValue时,上面可以简写为v-model
//'modelModifiers': { //modelModifiers为固定名,用于接收父组件v-model的修饰符:this.modelModifiers.修饰符
// default: ()=> ({}) //v.model没有修饰符时返回{}
//}
},
methods: {
函数名() { //此方法仅仅用于调用,触发以下代码
this.$emit(‘update:子组件的组件属性名’, 参数值); //update为固定名,用于双向绑定
}
},
}
</script>
6.插槽<slot>标签使用:
说明:父组件向子组件传递html标签、组件标签、字符串等布局内容,并在子组件中显示。
(1)方式1,父组件向子组件插入一种布局:
父组件实现:
<template>
<子组件名> <!- 此方式用于不需要接收子组件数据时 -->
<!--<子组件名 v-slot="{子组件自定义名}"> --> <!-- 接收子组件数据,方式1 -->
<!--<子组件名 v-slot="父自定义名"> --> <!-- 接收子组件数据,方式2 -->
<div></div> <!-- 将此内容插入到子组件中 -->
<!-- <div>{{ 子组件自定义名}}</div> --> <!-- 方式1,显示子组件的数据 -->
<!-- <div>{{ 父自定义名.子组件自定义名}}</div> --> <!-- 方式2,显示子组件的数据 -->
</子组件名>
</template>
子组件实现:
<template>
<slot></slot> <!-- 使用slot标签显示父组件传入的布局 -->
<!-- <slot v-bind:子组件自定义名="属性名"></slot> --> <!-- 需给父组件传递数据时 -->
</template>
export default {
data() { return {属性名: '值'}}
}
</script>
(2)方式2(具名插槽),父组件向子组件插入多种布局:
父组件实现:
<template>
<子组件名>
<template v-slot:父布局名1> <!-- 每种布局需要定义名称,格式 v-slot:名称 -->
<!--<template #父布局名1>--> <!-- 简写方式,同上 -->
<div>...</div>
</template>
<template v-slot:父布局名2>
<div>...</div>
</template>
</子组件名>
</template>
子组件实现:
<template>
<slot name="父布局名1"></slot> <!-- 使用slot标签显示父组件传入的布局 -->
<div>子组件内容</div>
<slot name="父布局名2"></slot>
</template>
7.动态组件<component>使用:
说明:<component>根据传入的组件名动态显示组件
<template>
<keep-alive> <!--缓存组件的状态数据,避免动态切换组件导致的数据丢失 -->
<component v-bind:is="属性名1"/> <!-- component标签根据值控制显示哪个组件 -->
</keep-alive>
</template>
<script>
export default {
data(){return {
属性名1: '组件名' //属性值必须为某个组件名,否则<component>不会显示组件内容
} },}
</script>
8.异步加载组件:
说明:通过异步方式,需要显示页面时再加载组件
<script>
import { defineAsyncComponent } from 'vue' //导入异步加载库
import加载中组件名 from '../components/加载中组件文件名.vue'
import 错误页组件名 from '../components/错误页组件文件名.vue'
export default {
components: {
// 组件名: defineAsyncComponent( //方式1,无加载中、无错误页
// () => import('../components/组件文件名.vue'), //异步加载方式 显示此组件
// ),
组件名: defineAsyncComponent({ //方式2,显示加载中、加载失败时显示错误页
loader: () => import('../components/组件文件名.vue'), //异步加载方式 显示此组件
loadingComponent: 加载中组件名, //加载中显示的组件
delay: 200, //显示加载组件前的延迟时间,默认为 200ms
errorComponent: 错误页组件名, //加载失败显示的组件
timeout: 3000 //加载超时时间
}),
}
}
</script>
9.provide与inject(孙组件跨层级取爷组件属性值):
(1)爷组件:
方式一,选项式:
export default {
provide: { //此处定义需要暴露给孙组件的属性名
爷暴露名: '值'
},
// provide() { //同上
// return {爷暴露名: this.属性名} //此种方式可以使用data中定义的属性
// },
}
</script>
方式二,组合式:
<script setup>
import { ref, provide } from 'vue'
const 属性名 = ref('值')
provide('爷暴露名', 属性名) //暴露属性
provide('爷暴露函数名', () => { //暴露函数
//...
})
</script>
(2)孙组件:
方式一,选项式:
<script>
export default {
inject: ['爷暴露名'], //取爷属性
}
</script>
<template>
<div>{{ 爷暴露名}}</div> <!-- 显示爷属性值 -->
</template>
方式二,组合式:
<script setup>
import { inject } from 'vue'
const 属性引用名 = inject('爷暴露名', '属性默认值') //取爷组件属性
const 函数引用名 = inject('爷暴露函数名') //取爷组件方法
</script>
<template>
<div v-on:click="函数引用名">{{ 属性引用名 }}</h1>
</template>
10.混入对象(封装通用函数/属性):
(1)编写混入对象内容,在src/plugins/混入对象文件名.js中:
export default {
created() { //vue生命周期函数(实例生成后执行,优先于app的created)
},
data() { //定义属性列表
return {
属性名: '值' //使用:{{ 属性名 }}
}
},
属性名1: '值1', //定义不放入data的自定义属性 //使用:{{ this.$options.属性名1 }}
methods: { //定义函数列表
函数名() {
//...
}
}
}
(2)main.js中注册混入:
...
import MyMixins from './plugins/MyMixins.js' //导入混入对象文件
const app = createApp(App)
app.mixin(MyMixins) //注册混入对象
app.mount('#app')
app.config.optionMergeStrategies.属性名 = (mixinVal, appValue) => { //混入对象与组件中存在同名属性时,优先使用混入对象中的(未加此配置时默认组件同名属性优先)
return mixinVal || appValue;
}
(3)在其他组件中使用混入对象定义的属性或方法:
<template>
<h1 v-on:click="函数名">{{ 属性名 }}</h1>
</template>
11.插件(封装通用函数/属性):
(1)编写插件内容,在src/plugins/插件文件名.js中:
export default {
install: (app, options) => { //定义插件
app.provide('属性名', '属性值'); //定义属性
app.provide('函数名', function(){ //定义函数
//...
});
app.directive('自定义指令', { //定义自定义指令
钩子函数名(el) { //实现vue生命周期函数
//实现自定义指令具体逻辑
}
})
app.mixin({ //定义混入对象
//...
})
app.config.globalProperties.$新字段名 = '新值'; //给vue底层增加新的属性并赋值,使用:this.$新字段名
app.config.globalProperties.$新函数名 = function () { //给vue底层增加新的函数,调用:this.$新函数名()
//...
};
},
}
(2)main.js中注册为插件:
...
import 插件名 from './plugins/插件文件名.js' //导入上面定义的插件文件
const app = createApp(App)
app.use(插件名) //注册为插件
app.mount('#app')
(3)在其他组件中使用插件定义的属性或方法:
<template>
<h1 v-on:click="函数名">{{ 属性名 }}</h1> <!-- 使用插件中定义的属性、函数 -->
</template>
<script>
export default {
inject: ['属性名', '函数名'], //注入插件中定义的属性、函数
}
</script>
12.render函数:
说明:能实现<template>的功能。
app.component('组件名', {
render(){
const { h } = Vue; //引入h函数
return h('html标签名', {}, this.$slots.default()) //利用h函数,调用此标签,第一个参数为标签名, 第2个参数为自定义组件标签传入的属性值参数,第3个参数为自定义组件包含的内容
}
})
三、自定义指令:
钩子函数名:
created : 在绑定元素的属性或事件监听器被应用之前调用。
beforeMount : 指令第一次绑定到元素并且在挂载父组件之前调用。。
mounted : 在绑定元素的父组件被挂载后调用。。
beforeUpdate: 在更新包含组件的 VNode 之前调用。。
updated: 在包含组件的 VNode 及其子组件的 VNode 更新后调用。
beforeUnmount: 当指令与在绑定元素父组件卸载之前时,只调用一次。
unmounted: 当指令与元素解除绑定且父组件已卸载时,只调用一次。
钩子函数参数:
el: 使用此指令的html标签引用,可操作 DOM,例el.innerHTML = “值”
binding: 传给指令的对象,含以下属性:
- instance:使用指令的组件实例
- value:传递给自定义指令的值,取参数值:binding.value
- oldValue:旧值,仅在 beforeUpdate函数、 updated 函数中可用
- arg:传递给自定义指令的参数名。取参数名:binding.arg
- modifiers:包含修饰符的对象
- dir:指令对象本身,例:{钩子函数名(el){...}}
vnode: el参数收到的真实DOM元素的节点
prevNode: 上一个虚拟节点,仅在 beforeUpdate函数、updated函数中可用
1.定义为全局指令:
说明:main.js中定义指令,在其他vue文件中使用
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.directive('自定义指令名', { //全局自定义指令,使用:<div v-自定义指令名 />
钩子函数名(el, binding, vnode){ //钩子函数见上面,取参数名:binding.arg, 取参数值:binding.value
//function(){ //不用钩子函数时可以省略钩子函数名
//执行指令具体逻辑
}
})
2.定义为局部指令:
说明:在使用自定义指令的vue文件中定义+使用
<script>
export default {
directives: { // 局部自定义指令,使用:<div v-自定义指令名 />
自定义指令名: {
钩子函数名(el) {
//执行指令具体逻辑
}
}
}
}
</script>
3.使用自定义指令:
<template>
<html标签名 v-自定义指令名 />
<html标签名 v-自定义指令名:自定义参数名=”参数值” /> //给自定义指令传值
</template>
四、路由跳转:
1.定义路由:
(1)工程/src/router/index.js中配置路由:
import { createRouter, createWebHistory } from 'vue-router' //导入路由依赖库
const 路由列表名 = [ // 1. 路由列表,映射路径到页面
{ path: '/路径名', component: () => import('../views/页面文件名.vue') }, //path配置路由路径,component配置页面vue文件路径,使用:<router-link to="/路径名”>
{ path: '/:pathMatch(.*)*', component: () => import('../views/错误页.vue') }, //捕获所有404 路由
]
const 路由实例名 = createRouter({ //2. 根据路由列表创建路由实例
history: createWebHistory(process.env.BASE_URL),, //或createWebHashHistory
//routes: 路由列表名 //等同下面
routes //路由列表名为routes时,可以用此缩写方式
})
export default 路由实例名 //3.导出路由实例
(2)main.js中使用路由配置:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router' //导入路由目录(工程/src/router)
const app = createApp(App)
app .use(router).mount('#app') //使用路由配置
3.使用路由:
<router-link>标签属性说明:
replace:导航后不会留下记录,例<router-link to="路径" replace />
append:从 /a1 导航到一个相对路径 a2,没有配append时路径为/a2,如果配了,则为/a1/a2,例<router-link to="路径" append />
tag:将<router-link>显示为其他标签(功能不变),例<router-link to="路径" tag="div" />,<router-link>显示为<div>...</div>
active-class:模糊匹配链接激活时显示的CSS样式,例<router-link to="路径" active-class="CSS样式名" />
exact-active-class:精准匹配链接激活时显示的CSS样式,例<router-link to="路径" exact-active-class="CSS样式名" />
event:触发导航的事件,例<router-link to="路径" event="字符串或字符串数组" />
使用路由(<router-link>和<router-view>):
<template>
<router-link to="/路径名”>...</router-link> //此路径与路由中配置的一致,点击时将路由组件显示在<router-view>中
<router-link :to="'/路径名'">...</router-link> //用v-bind,效果同上
<router-link :to="{path: '/路径名'}">...</router-link> //同上,显式写了path
<router-link :to="{name: '/路径名', params: { 参数名: 值 }}">...</router-link> //命名的路由
<router-link :to="{path: '/路径名' query: { 参数名: '值' }}">...</router-link> //带参数的路径,/路径?参数名=值
以下显示路由后的页面内容:
<router-view/> //路由页面内容显示在<router-view>中
</template>
五、Composition API:
1.readonly使用:
作用:包装原对象为只读
<script setup>
import { reactive, readonly} from 'vue' //导入ref
const 原对象名 = reactive({字段名: '值'})
const 包装对象名 = readonly(原对象名) //包装原对象为只读, 使用:{{ 包装对象名.字段名 }}
</script>
2.toRefs使用:
作用:解构对象,取对象字段
<script setup>
import { reactive, toRefs} from 'vue' //导入ref
const 对象名 = reactive({字段名: '值'})
const { 字段名 } = toRefs(对象名) //解构对象,取对象字段,改此值时对象字段的值也跟着变化,使用: {{ 字段名 }}
</script>
<template>
{{ 字段名 }}
</template>
3.toRef使用:
作用:取对象字段,改别名值时对象字段的值也跟着变化
<script setup>
import { reactive, toRef } from 'vue' //导入ref
const 对象名 = reactive({字段名: '值'})
const 字段别名 = toRef(对象名, '字段名') //取对象字段,改别名值时对象字段的值也跟着变化,使用: {{ 字段别名 }}
</script>
<template>
{{ 字段别名 }}
</template>
4.context参数:
<script setup>
import { getCurrentInstance } from 'vue' //导入ref
const context = getCurrentInstance().ctx; //获取context参数
context.props // 访问props, 用于组件标签属性传值
context.attrs // 访问attrs
context.slots // 访问slots,等同插槽<slot>标签
context.emit('事件名') // 访问emit, <子组件名 @事件名="父函数名" />
</script>
六、vuex全局数据管理:
说明:vuex可定义全局属性,供所有组件读/写
1.定义全局属性,在src/store/index.js中:
import { createStore } from 'vuex'
export default createStore({ //全局数据管理
state: { //1.定义属性列表
属性名: '值'
},
getters: {},
mutations: { //4.修改属性值
mutation名1(state, newValue){ //参数由commit传入
state.属性名 = newValue //将外部传入的新值赋给属性
}
},
actions: { //3.接收外部事件,提交到mutations
事件名1(store, newValue){ //参数由外部传入
store.commit('mutation名1', newValue) //提交到mutations
}
},
modules: {}
})
2.读/写全局属性:
方式1,选项式:
<script>
export default {
methods: {
函数名(){
this.$store.dispatch('事件名1', '新值') //触发createStore.actions定义的事件名1
}
}
}
</script>
<template>
<div v-on:click="函数名">点击修改全局属性</div>
{{ this.$store.state.name }} <!-- 读全局属性 -->
</template>
方式2,组合式:
<script setup>
import { useStore } from "vuex"
const store = useStore() //获取store引用
function 函数名(){
store.dispatch('事件名1', '新值') //触发createStore.actions定义的事件名1
}
</script>
<template>
<div v-on:click="函数名">点击修改全局属性</div>
{{ this.$store.state.name }} <!-- 读全局属性 -->
</template>
七、动画:
1.定义过渡动画Class:
过渡名(固定名称):
enter-from:进入过渡动画的开始状态
enter-active:进入过渡动画的持续状态(在此定义持续时间、延迟、速度、曲线类型)
enter-to:进入过渡动画的结束状态
leave-from:离开过渡动画的开始状态
leave-active:离开过渡动画的持续状态(在此定义持续时间、延迟、速度、曲线类型)
leave-to:离开过渡动画的结束状态
Move:移动时的动画效果
(1) .v-过渡名 方式定义Class名:
格式:.v-过渡名
例:
.v-enter-active{ //格式:.v-过渡名
//编写CSS动画
}
(2).动画名-过渡名 方式定义Class名:
动画名(固定名称):
fade:渐隐动画
slide-fade:滑动+渐隐动画
bounce:弹动动画
格式:.动画名-过渡名
例:
.fade-enter-active{ //格式:.动画名-过渡名
//编写CSS动画
}
2.使用<Transition>标签展示动画:
说明:v-show或v-if的值改变时触发动画
(1)name属性+动画名方式:
<template>
<Transition name = "fade"> //fade为动画名(名称固定,不可自定义),与 .动画名-过渡名中的动画名保持一致
<div v-show="true或false">...</div> //要动画的布局,通过改变v-show或v-if的值触发动画
</Transition>
</template>
(2)过渡名-class 作为<Transition>属性方式:
属性名(属性名固定):
enter-from-class
enter-active-class
enter-to-class
leave-from-class
leave-active-class
leave-to-class
例:
<template>
<Transition
enter-active-class="自定义class名1"
leave-active-class="自定义class名2"> //class可自定义或使用三方动画库
<div v-show="true或false">...</div>
</Transition>
</template>
(3)其他<Transition>特性:
<1>过渡动画持续时间:
<Transition :duration="毫秒数">
//<Transition :duration="{ enter: 进场毫秒数, leave: 离场毫秒数 }">
...
</Transition>
<2>给动画过程添加监听函数(在函数中实现动画):
<Transition
:css="false" <!-- 取消CSS动画使用函数中的JS实现动画 -->
@before-enter="自定义函数名" <!-- 在元素被插入到 DOM 之前被调用 -->
@enter="自定义函数名" <!-- 在元素被插入到 DOM 之后的下一帧被调用 -->
@after-enter="自定义函数名" <!-- 当进入过渡完成时调用 -->
@enter-cancelled="自定义函数名" <!-- 当进入过渡在完成之前被取消时调用 -->
@before-leave="自定义函数名" <!-- leave之前调用 -->
@leave="自定义函数名" <!-- 离开过渡开始时调用 -->
@after-leave="自定义函数名" <!-- 离开过渡完成时调用 -->
@leave-cancelled="自定义函数名" > <!-- 仅 v-show 过渡中可用 -->
...
</Transition>
<3>mode属性可实现单个元素切换效果(不加mode默认同步执行动画):
<Transition mode="out-in | in-out" appear> ... </Transition> //appear表示初始化显示时有也动画效果
3.使用<TransitionGroup>标签展示动画:
说明:v-for 列表中的元素插入、移除和顺序改变时触发动画
<template>
<TransitionGroup>
<div v-for="(item, index) in list" v-bind:key="item">{{ item }}</div> <!--列表变化时触发动画-->
</TransitionGroup>
</template>
八、Ajax网络请求(axios框架):
cd到工程目录输入命令安装axios:
C:\Users\Administrator\Desktop\demo2> npm install axios
response响应数据结构说明:
{
data: {}, //response.data,数据
status: 200, //response.status,HTTP 状态码
statusText: "OK", //response.statusText,HTTP 状态信息
headers: {}, //response.headers,响应头
config: {} //response.config,请求提供的配置信息
}
1.GET方式请求:
方式1:
<script>
import axios from 'axios' //导入axios
export default {
methods: {
doGet() { //自定义函数名
// var cancelTask = axios.CancelToken.source(); //用于取消请求
axios.get('url?参数=xxx') //方式1,参数跟在url后面
/*axios.get('url', { //方式2,参数通过第2个参数传入,与上面等同
params: { //参数列表
参数: 值
},
headers: { //头字段列表
‘头字段名’: ‘值’
},
timeout: 300000, //请求超时时长
})*/
.then(function (response) { //处理成功的数据,如json
alert(response)
})
.catch(function (error) { //处理失败的情况
alert(error)
});
//取消请求
//cancelTask.cancel('');
}
}
}
</script>
方式2:
<script>
import axios from 'axios' //导入axios
export default {
methods: {
doPost() {
axios({
method: ‘get’,
url: ‘url?参数=值’,
headers: {'头字段': '值'}
})
.then(function (response) { //处理成功的数据,如json
})
.catch(function (error) { //处理失败的情况
});
}
}
}
</script>
2.POST方式请求:
方式1:
<script>
import axios from 'axios' //导入axios
export default {
methods: {
doPost() { //自定义函数名
axios.post('url',
{ //参数列表
参数1: '值',
参数2: '值'
},
{
headers: {'头字段': '值'} //头字段列表
}
)
.then(function (response) { //处理成功的数据,如json
})
.catch(function (error) { //处理失败的情况
});
}
}
}
</script>
方式2:
<script>
import axios from 'axios' //导入axios
export default {
methods: {
doPost() {
axios({
method: 'post',
url: 'url',
headers: {'头字段': '值'},
data: { 参数1: ‘值' }
})
.then(function (response) { //处理成功的数据,如json
})
.catch(function (error) { //处理失败的情况
});
}
}
}
</script>
3.并发执行多个请求:
axios.all([doGet(), doPost()]) //并发执行上面的get与post请求,或者axios.spread
.then(axios.spread(function (acct, perms) {
// 两个请求执行完毕后回调
}));
4.修改默认值:
axios.defaults.headers.common['Authorization'] = “token值”;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
5.拦截器:
(1)请求拦截器:
axios.interceptors.request.use(function (config) {
//发送请求之前时触发
return config;
}, function (error) {
//请求错误时触发
return Promise.reject(error);
});
(2)响应拦截器:
axios.interceptors.response.use(function (response) {
// 响应数据时触发
return response;
}, function (error) {
// 响应错误时触发
return Promise.reject(error);
});
Web前端:Vue3.js摘要
于 2024-08-05 12:37:33 首次发布