一文带你看懂vue基础语法、生命周期、指令、监听器、依赖注入
ztj100 2024-12-31 15:58 13 浏览 0 评论
vue3移动端项目搭建,vue3+vant+vite+axios+pinia+sass完整版代码下载:
【免费】vue3移动端项目搭建,vue3+vant+vite+axios+pinia+sass_vue3响应式布局资源-CSDN文库
vue3移动端项目构建TS,vue3+vant+vite+axios+pinia+sass+typescript完整版代码下载:
vue3 PC端项目构建,vue3+antd+vite+pinia+axios+sass完整版代码下载:
vue3PC端项目构建,vue3+antd+vite+pinia+axios+sass_zyadmin资源-CSDN文库
vue3 PC端项目构建TS,vue3+antd+vite+axios+pinia+sass+typescript完整版代码下载:
vue3PC端项目构建TS,vue3+antd+vite+axios+pinia+sass+typescript_高级写法vue3+ts开源项目资源-CSDN文库
一、简介
Vue.js 是一个流行的前端 JavaScript 框架,用于构建用户界面和单页面应用程序(SPA)。Vue.js 的设计目标是通过简单、灵活的 API 提供高效的数据驱动视图层渲染。本文主要针对script setup讲解
以下是 Vue.js 的一些特点和优势:
- 简洁易用:Vue.js 的 API 简单易懂,容易上手,使开发者能够快速构建交互性强、动态的用户界面。
- 响应式数据绑定:Vue.js 使用双向数据绑定和虚拟 DOM 技术,能够自动追踪数据变化并更新视图,使开发者能够更容易地管理和维护应用的状态。
- 组件化开发:Vue.js 支持组件化开发,将页面拆分为多个独立的组件,每个组件负责自己的视图和逻辑,有利于代码复用和维护。
- 灵活性:Vue.js 提供了诸多灵活的特性,如指令、计算属性、过滤器等,使开发者能够根据需求选择合适的工具进行开发。
- 生态系统丰富:Vue.js 生态系统庞大丰富,拥有大量的插件、工具和第三方库,能够满足各种不同需求。
- 性能优化:Vue.js 通过虚拟 DOM 和 diff 算法优化了页面渲染性能,同时提供了一些性能优化的工具和指导,帮助开发者提升应用的性能。
二、vue基本语法
- 模板语法与v-html指令
<template>
<div>
<p>{{text}}</p> //普通文本
<span v-html="html"></span> //html
</div>
</template>
<script setup>
const text = 'hello word';
const html = '<span>我是div</span>'
</script>
- 声明响应式状态ref、reactive
<template>
<div>
<p>响应式ref:{{refText}}</p>
<p>响应式reactive:{{reactiveObj.count}}</p>
<button v-on:click="onTextChange">改变文本</button>
</div>
</template>
<script setup>
import {reactive, ref} from "vue";
;
const refText = ref('refText'); //Ref 可以持任何类型的值,包括深层嵌套的对象、数组或者 JavaScript 内置的数据结构,建议使用
const reactiveObj = reactive({count:0}); //只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型)。它不能持有如 string、number 或 boolean 这样的原始类型。
const onTextChange = ()=>{
refText.value =' refText change';
reactiveObj.count++
}
</script>
- 计算属性: computed,不使用计算属性每次重新渲染组件时,都会重新计算这个表达式的值;计算属性具有缓存机制,只有在 author.books 发生变化时,才会渲染组件
- 基本使用
<template>
<div>
<p>不使用计算属性:{{ author.books.length > 0 ? 'Yes' : 'No' }}</p>
<p>使用计算属性:{{ publishedBooksMessage }}</p>
<button @click="onChange">改变值</button>
</div>
</template>
<script setup>
import {computed, ref} from "vue";
const author = ref({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
});
const onChange = ()=>{
author.value.books = []
}
// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
return author.value.books.length > 0 ? 'Yes' : 'No'
})
</script>
- 可写的计算属性,计算属性默认是只读的,如果在某些特殊场景需要修改计算属性,可以使用getter 和 setter
<script setup>
import { ref, computed } from 'vue'
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
// getter
get() {
return firstName.value + ' ' + lastName.value
},
// setter
set(newValue) {
// 注意:我们这里使用的是解构赋值语法
[firstName.value, lastName.value] = newValue.split(' ')
}
})
</script>
- 动态绑定class
<template>
<div>
<div class="no_active" :class="{ active: isActive }">基本使用</div>
<div class="no_active" :class="classObj">绑定对象</div>
<div class="no_active" :class="classComputed">绑定计算属性</div>
<div :class="['no_active',isActive ? 'active' : '']">绑定数组</div>
<button @click="onChange">改变样式</button>
</div>
</template>
<style lang="scss" scoped>
.no_active{
color: #333333;
}
.active{
color: red;
}
</style>
<script setup>
import {computed, ref} from "vue";
const isActive = ref(false);
const classObj = ref({
active: false
});
const classComputed = computed(() => ({
active: isActive.value
}))
const onChange = ()=>{
isActive.value = !isActive.value;
classObj.value.active = !classObj.value.active;
}
</script>
- 动态绑定style
<template>
<div>
<div :style="{ color: activeColor }">基本使用</div>
<div :style="styleObj">绑定对象</div>
<div :style="classComputed">绑定计算属性</div>
<div :style="[styleObj]">绑定数组</div>
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">添加前缀</div>
<button @click="onChange">改变样式</button>
</div>
</template>
<script setup>
import {computed, ref} from "vue";
const activeColor = ref('#333333')
const styleObj = ref({
color: '#333333'
});
const classComputed = computed(() => ({
color: activeColor.value
}))
const onChange = ()=>{
activeColor.value = 'red';
styleObj.value.color = 'red';
}
</script>
三、vue逻辑指令
- 条件渲染,v-if每次切换都换重新渲染,v-show只在初始化渲染。如果需要频繁切换,则使用 v-show 较好,很少切换使用v-if最好
- v-if、v-else、v-else-if根据条件渲染内容,支持在template上使用
<template>
<div>
<div v-if="type == 301">请求重定向</div>
<div v-else-if="type == 404">资源未找到</div>
<div v-else>请求成功</div>
<button @click="onChange">改变请求状态</button>
</div>
</template>
<script setup>
import {computed, ref} from "vue";
const type = ref(200);
const onChange = ()=>{
const array = [200,301,404];
const randomIndex = Math.floor(Math.random() * array.length);
const randomValue = array[randomIndex];
type.value = randomValue
}
</script>
- v-show根据条件渲染内容,不支持在template上使用,v-show会在dom中保留该玄素,只是切换了元素的display
<template>
<div>
<div v-show="type == 301">请求重定向</div>
<div v-show="type == 404">资源未找到</div>
<div v-show="type == 200">请求成功</div>
<button @click="onChange">改变请求状态</button>
</div>
</template>
<script setup>
import {computed, ref} from "vue";
const type = ref(200);
const onChange = ()=>{
const array = [200,301,404];
const randomIndex = Math.floor(Math.random() * array.length);
const randomValue = array[randomIndex];
type.value = randomValue
}
</script>
- 循环渲染v-for,支持在template上使用;v-if 和 v-for不能同时使用,当它们同时存在于一个节点上时,v-if 比 v-for 的优先级更高
- 渲染列表
<template>
<div>
<ol>
<li v-for="item in itemArray">
{{ item.message }}
</li>
</ol>
<ul>
<li v-for="(item,index) in itemArray">
{{ index+1 }}、{{ item.message }}
</li>
</ul>
</div>
</template>
<script setup>
import {ref} from "vue";
const itemArray = ref([{ message: 'Foo' }, { message: 'Bar'}])
</script>
- 渲染对象
<template>
<div>
<ol>
<li v-for="item in info">
{{ item }}
</li>
</ol>
<ul>
<li v-for="(item,key,index) in info">
{{ index+1 }}、{{key}}:{{ item }}
</li>
</ul>
</div>
</template>
<script setup>
import {ref} from "vue";
const info = ref({
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
});
</script>
- 通过 key 管理状态,Vue 默认按照“就地更新”的策略来更新通过 v-for 渲染的元素列表,当数据改变vue不会移动domw,而是在原有的元素上重新渲染;属性key可以跟踪每个节点的标识,从而重用和重新排序现有的元素,提高性能。
<template>
<div>
<ol>
<li v-for="item in info" :key="{item}">
{{ item }}
</li>
</ol>
<ul>
<li v-for="(item,key,index) in info" :key="{key}">
{{ index+1 }}、{{key}}:{{ item }}
</li>
</ul>
</div>
</template>
<script setup>
import {ref} from "vue";
const info = ref({
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
});
</script>
四、vue事件处理
- v-on或@绑定事件
<template>
<div>
<p>count:{{count}}</p>
<button @click="count++">点击改变</button>
<button v-on:click="onChange">点击改变 v-on</button>
<button @click="onChange">点击改变@</button>
<button @click="onAdd(2)">点击改变Add</button>
</div>
</template>
<script setup>
import {ref} from "vue";
const count = ref(0);
const onChange = (event)=>{
console.log(event)
count.value++
}
const onAdd = (nu)=>{
count.value+=nu;
}
</script>
- 事件修饰符
<template>
<div>
<!-- @click.stop阻止事件冒泡-->
<div @click="console.log('阻止事件冒泡')">
<p>count:{count}</p>
<button @click.stop="onStop">.stop阻止事件冒泡</button>
</div>
<!-- .prevent阻止事件默认行为-->
<a href="https://www.baidu.com" @click.prevent="onPrevent">.prevent阻止事件默认行为</a>
<!-- .self用于限制事件只在事件触发的元素自身上触发,而不是在其子元素上触发-->
<div style="border:1px solid red;width: 500px;height:80px" @click.self="onSelf">
<button>.self用于限制事件只在事件触发的元素自身上触发,而不是在其子元素上触发</button>
</div>
<!-- @click.stop阻止事件冒泡-->
<button @click.once="onOnce">.once只触发一次</button>
<!-- .capture事件捕获-->
<div @click.capture="onCapture('外部先处理')">
<button @click="onCapture('内部后处理')">.capture事件捕获</button>
</div>
<!-- @scroll.passive触摸事件的监听器-->
<div @scroll.passive="onScroll" style="border:1px solid red;width: 500px;height:80px;overflow: auto;">
<p style="width: 200px;height:100px">
.passive修饰符一般用于触摸事件的监听器
</p>
</div>
<!-- 链式操作-->
<div @click="console.log('阻止事件冒泡')">
<a href="https://www.baidu.com" @click.stop.prevent="onPrevent">.prevent阻止事件默认行为</a>
</div>
</div>
</template>
<script setup>
import {ref} from "vue";
const count = ref(0);
const onStop = (event) => {
count.value++
}
const onPrevent = () => {
console.log('.prevent阻止事件默认行为')
}
const onSelf = (event) => {
console.log(event.target)
}
const onOnce = () => {
console.log('只触发一次')
}
const onCapture = (text) => {
console.log(text)
}
const onScroll = () => {
console.log('滚动事件的默认行为 (scrolling) 将立即发生而非等待 `onScroll` 完成')
}
</script>
- 键盘按键修饰符
<template>
<div>
<p>
enter:<input @keyup.enter="onkeyup('enter键')" />
</p>
<p>
tab:<button @keyup.tab="onkeyup('tab键')">tab键</button>
</p>
<p>
Delete、Backspace: <input @keyup.delete="onkeyup('Delete和Backspace键')" />
</p>
<p>
esc: <input @keyup.esc="onkeyup('esc键')" />
</p>
<p>
space:<input @keyup.space="onkeyup('space键')" />
</p>
<p>
up: <input @keyup.up="onkeyup('up键')" />
</p>
<p>
down:<input @keyup.down="onkeyup('down键')" />
</p>
<p>
left: <input @keyup.left="onkeyup('left键')" />
</p>
<p>
right:<input @keyup.right="onkeyup('right键')" />
</p>
<p>
ctrl+其他键:<input @keyup.ctrl="onkeyup('ctrl键')" />
</p>
<p>
alt+其他键:<input @keyup.alt="onkeyup('alt键')" />
</p>
<p>
shift+其他键:<input @keyup.shift="onkeyup('shift键')" />
</p>
<p>
window+其他键:<input @keyup.meta="onkeyup('window键')" />
</p>
<p>
链式操作Alt + Enter:<input @keyup.alt.enter="onkeyup('Alt + Enter键')" />
</p>
<p>
.exact:<button @click.ctrl.exact="onkeyup('.exact修饰符')">当用户按下 Ctrl 键并单击按钮时,事件处理程序将被触发</button>
</p>
</div>
</template>
<script setup>
const onkeyup = (name)=>{
console.log(name)
}
</script>
- 鼠标按键修饰符
<template>
<div>
<button @click.middle="onMouse('鼠标中间键')">鼠标中间</button>
<button @click.left="onMouse('鼠标左键')">鼠标左键</button>
<button @click.right="onMouse('鼠标右键')">鼠标右键</button>
</div>
</template>
<script setup>
const onMouse = (name)=>{
console.log(name)
}
</script>
五、vue双向数据绑定v-model
- 基本用法
<template>
<div>
<p>Message is: {{ message }}</p>
<input v-model="message">
</div>
</template>
<script setup>
import {ref} from "vue";
const message = ref('双向数据绑定');
</script>
- 复选框
<template>
<div>
<div>Checked names: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
</div>
</template>
<script setup>
import {ref} from "vue";
const checkedNames = ref(['Jack']);
</script>
- 单选
<template>
<div>
<div>Picked: {{ picked }}</div>
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
</div>
</template>
<script setup>
import {ref} from "vue";
const picked = ref('One');
</script>
- select选择器
<template>
<div>
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
</div>
</template>
<script setup>
import {ref} from "vue";
const selected = ref('A');
</script>
六、vue声明周期
- onMounted(callback):组件被挂载到 DOM 后调用。
- onUpdated(callback):组件更新后调用,DOM 重新渲染之后。
- onUnmounted(callback):组件被卸载或销毁之前调用。
- onBeforeMount(callback):组件挂载之前调用。
- onBeforeUpdate(callback):组件更新之前调用,DOM 重新渲染之前。
- onBeforeUnmount(callback):组件卸载或销毁之前调用。
- onErrorCaptured(callback):捕获子组件生命周期钩子中的错误。
- onRenderTracked(callback):在渲染函数跟踪时调用。
- onRenderTriggered(callback):在渲染函数触发时调用。
- onActivated(callback):keep-alive 组件被激活时调用。
- onDeactivated(callback):keep-alive 组件被停用时调用。
- onServerPrefetch(callback):在服务器端渲染期间调用,用于数据预取。
七、vue监听器
- watch(source,callback,options)
- source: ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组
- callback:回调函数
- options:watch配置
flush:用于指定 watcher 的刷新时机,pre变化前执行回调、post变化后执行回调、sync变化后立即执行回调
immediate:表示是否立即执行 watcher 回调函数。如果设置为 true,则在监听开始时立即执行回调函数。
deep:表示是否深度监听被观察的数据,即是否递归监听对象内部值的变化。
once:表示是否只监听一次变化,即只触发一次回调函数。
- 基本使用
<template>
<div>
<button @click="onXChange">x改变</button>
<button @click="onYChange">y改变</button>
</div>
</template>
<script setup>
import {ref, watch} from "vue";
const x = ref(0);
const y = ref(0);
const onXChange = ()=>{
x.value++
}
const onYChange = ()=>{
y.value+=2
}
// 单个 ref
watch(x, (newValue,oldValue) => {
console.log(`x值已改变,新值:${newValue},旧值:${oldValue}`)
})
// getter 函数
watch(
() => x.value + y.value,
(newValue,oldValue) => {
console.log(`x+y值已改变,新值:${newValue},旧值:${oldValue}`)
}
)
// 多个来源组成的数组
watch([x, () => y.value], (newValues,oldValues) => {
console.log(`x或y值改变,,新值:${newValues},旧值:${oldValues}`)
})
</script>
- 监听对象
<template>
<div>
<button @click="onCountChange">count改变</button>
<button @click="onAgeChange">age改变</button>
</div>
</template>
<script setup>
import {reactive, ref, watch} from "vue";
const obj = reactive({ count: 0, age:0 })
const onCountChange = ()=>{
obj.count++
}
const onAgeChange = ()=>{
obj.age++
}
//监听某一属性值
watch(()=>obj.count,(newValue,oldValue)=>{
console.log(`count已改变,新值:${newValue},旧值:${oldValue}`)
})
//deep强制转成深层侦听器,虽然只监听了count,但是deep为true,当obj其他属性改变也会触发
watch(()=>obj.count,(newValue,oldValue)=>{
console.log(`只监听count,deep:true,新值:${newValue},旧值:${oldValue}`)
},{deep:true})
//监听某一属性值,使用ref时需配置deep参数
watch(obj,(newValue,oldValue)=>{
console.log(`obj已改变,新值:${JSON.stringify(newValue)},旧值:${JSON.stringify(oldValue)}`)
})
</script>
- watchEffect(callback,options))可以自动跟踪回调的响应式依赖,当callback中的某个响应式改变就会触发回调,监听不了对象和计算属性
- options:watch配置
flush:用于指定 watcher 的刷新时机,pre变化前执行回调、post变化后执行回调、sync变化后立即执行回调
- 使用案例
<template>
<div>
<div>count:{{obj.count}}</div>
<div>age:{{obj.age}}</div>
<div>sum:{{sum}}</div>
<button @click="onCountChange">count改变</button>
<button @click="onAgeChange">age改变</button>
<button @click="onSumChange">sum改变</button>
</div>
</template>
<script setup>
import {reactive, watchEffect, ref} from "vue";
const obj = reactive({ count: 0, age: 0 })
let sum = ref(0);
const onCountChange = () => {
obj.count++
}
const onAgeChange = () => {
obj.age++
}
const onSumChange = () => {
sum.value++
}
watchEffect(() => {
console.log('watchEffect监听不了对象:',obj)
})
watchEffect(() => {
console.log('count改变:',obj.count)
})
watchEffect(() => {
console.log('age改变:',obj.age)
})
watchEffect(() => {
console.log('sum改变:',sum.value)
})
</script>
- watchPostEffect(callback):watchEffect() 使用 flush: 'post' 选项时的别名。
- watchSyncEffect(callback):watchEffect() 使用 flush: 'sync' 选项时的别名。
八、vue ref妙用模板引用
<template>
<div>
<input ref="input" />
<ul>
<li v-for="item in list" ref="itemRefs">
{{ item }}
</li>
</ul>
</div>
</template>
<script setup>
import {onMounted, ref} from "vue";
const list = ref([1,2,3,4])
const itemRefs = ref([])
const input = ref();
onMounted(()=>{
input.value.focus();
console.log(itemRefs.value)
})
</script>
九、vue指令
- v-html:将元素的 innerHTML 设置为指定的 HTML。
- v-show:根据表达式的真假值切换元素的显示与隐藏。
- v-if:根据表达式的真假值条件性地渲染元素。
- v-else:用于 v-if 的后续兄弟元素,表示前一个 v-if 条件不成立时渲染。
- v-else-if:用于 v-if 的后续兄弟元素,表示前一个 v-if 条件不成立时进一步判断是否渲染。
- v-for:基于源数据多次渲染元素或模板块。
- v-on:绑定事件监听器,用于监听 DOM 事件,或者使用@。
- v-bind:动态地绑定一个或多个特性,或一个组件 prop,或者使用:。
- v-model:在表单控件或组件上创建双向数据绑定。
- v-text:将元素的文本内容设置为指定的值,或者使用{{}}。
- v-pre:跳过这个元素和它的子元素的编译过程。
<template>
<div>
<span v-pre>{{ this will not be compiled }}</span> //直接渲染文本,不进行编译{{ this will not be compiled }}
</div>
</template>
- v-once:只渲染元素和组件一次,count改变不会重新渲染,一直是初始值
<template>
<div>
<span v-once>count: {{count}}</span>
<div v-once>
<h1>comment</h1>
<p>count: {{count}}</p>
</div>
<button @click="onChange">点击改变</button>
</div>
</template>
<script setup>
import {ref} from "vue";
const count = ref(0);
const onChange = ()=>{
count.value++;
}
</script>
- v-memo:类似于 computed,但是只有在相关依赖项发生变化时才重新计算,只有count、age变化才会重新渲染。只有sum改变不会重新渲染
<template>
<div>
<div v-memo="[count, age]">
<p>count:{{count}}</p>
<p>sum:{{sum}}</p>
<p>age:{{age}}</p>
</div>
<button @click="onCountChange">点击改变count</button>
<button @click="onAgeChange">点击改变age</button>
<button @click="onSumChange">点击改变sum</button>
</div>
</template>
<script setup>
import {ref} from "vue";
const count = ref(0);
const sum = ref(0);
const age = ref(0);
const onCountChange= ()=>{
count.value++;
}
const onAgeChange = ()=>{
age.value++;
}
const onSumChange = ()=>{
sum.value++;
}
</script>
- v-cloak:在 Vue 实例编译结束前隐藏插值标签,防止出现闪烁的情况,直到编译完成前,div将不可见。
<template>
<div>
<div v-cloak>
{{ message }}
</div>
</div>
</template>
<style lang="scss" scoped>
[v-cloak] {
display: none;
}
</style>
<script setup>
import {ref} from "vue";
const message = ref('hello word');
</script>
- v-slot:用于具名插槽分发内容,需和组件使用
十、vue自定义指令
- 基本使用
<template>
<div>
<input v-focus />
</div>
</template>
<script setup>
const vFocus = {
mounted: (el) => el.focus()
}
</script>
- 指令钩子
- el:指令绑定到的元素。可以用于直接操作 DOM。
- binding:包含以下属性
value:传递给指令的值。例如在 v-my-directive="1 + 1" 中,值是 2。
oldValue:之前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否更改,它都可用。
arg:传递给指令的参数 (如果有的话)。例如在 v-my-directive:foo 中,参数是 "foo"。
modifiers:一个包含修饰符的对象 (如果有的话)。例如在 v-my-directive.foo.bar 中,修饰符对象是 { foo: true, bar: true }。
instance:使用该指令的组件实例。
dir:指令的定义对象。
- vnode:代表绑定元素的底层 VNode。
- prevNode:代表之前的渲染中指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。
const myDirective = {
// 在绑定元素的 attribute 前或事件监听器应用前调用
created(el, binding, vnode, prevVnode) {},
// 在元素被插入到 DOM 前调用
beforeMount(el, binding, vnode, prevVnode) {},
// 在绑定元素的父组件,及他自己的所有子节点都挂载完成后调用
mounted(el, binding, vnode, prevVnode) {},
// 绑定元素的父组件更新前调用
beforeUpdate(el, binding, vnode, prevVnode) {},
// 在绑定元素的父组件,及他自己的所有子节点都更新后调用
updated(el, binding, vnode, prevVnode) {},
// 绑定元素的父组件卸载前调用
beforeUnmount(el, binding, vnode, prevVnode) {},
// 绑定元素的父组件卸载后调用
unmounted(el, binding, vnode, prevVnode) {}
}
- 全局自定义指令
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
app.directive('focus',{
mounted: (el) => el.focus()
})
app.mount("#app");
<template>
<div>
<input v-focus />
</div>
</template>
十一、vue依赖注入,一般用于多层级组件嵌套,props传参
一般用于多层级组件嵌套,props传参情况。组件嵌套时,可能某些组件使用不到某些props,但是其他嵌套组件会用到,所以没用到props的组件仍然需要定义并向下传递。如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”,使用provide 和 inject可以解决该问题
- 父组件注册依赖
<template>
<div>
<Demo/>
</div>
</template>
<script setup>
import Demo from "@components/Demo.vue";
import {provide} from "vue";
provide('message', {text: '请求错误'})
</script>
- 子数组件使用依赖
<template>
{{message.text}}
</template>
<script setup>
import {inject} from "vue";
const message = inject('message')
</script>
- 注册全局依赖
import {createApp} from "vue";
import App from "./App.vue";
const app = createApp(App);
app.provide('message', {text: '请求错误'})
app.mount("#app");
十二、vue内置的特殊属性
- key:在比较新旧节点列表时用于识别 vnode。
- ref:用于注册模板引用。
- is:用于绑定动态组件
<table>
<tr is="vue:my-row-component"></tr>
</table>
十三、vue工具函数
- isRef(): 判断一个值是否为 ref 创建的响应式对象。
- unref(): 如果参数是 ref 创建的响应式对象,则返回其内部值;否则返回参数本身。
- toValue(): 如果参数是 ref 创建的响应式对象,则返回其内部值;否则返回参数本身。
- toRef(): 将一个响应式对象的属性转换为 ref 创建的响应式对象。
- toRefs(): 接收一个响应式对象,返回一个包含该对象所有属性的 ref 对象的普通对象。
- isProxy(): 判断一个对象是否是由 Vue 的响应式系统创建的代理对象。
- isReactive(): 判断一个对象是否是由 Vue 的响应式系统创建的响应式对象。
- isReadonly(): 判断一个对象是否是由 Vue 的响应式系统创建的只读代理对象。
- readonly:(): 创建一个只读的响应式代理对象,该对象是一个只读的、不可修改的响应式对象,要避免深层级的转换行为,使用 shallowReadonly() 替代
<template>
<div>
<div>
<p>count:{{obj.count}}</p>
</div>
<button @click="onCountChange">点击改变count</button>
</div>
</template>
<script setup>
import {reactive, readonly, watchEffect} from "vue";
const obj = reactive({ count: 0 });
const copyObj = readonly(obj)
const onCountChange= ()=>{
obj.count++;
}
watchEffect(()=>{
console.log(copyObj.count)
})
</script>
- nextTick(): 用于更新dom
<template>
<div>
<div id="nextTick"></div>
<button @click="onChange">点击改变</button>
</div>
</template>
<script setup>
import {nextTick} from "vue";
const onChange= ()=>{
document.getElementById('nextTick').innerText = 'nextTick';
nextTick(()=>{
console.log('dom更新完毕')
})
}
</script>
十四、vue应用实例
- createApp(): 创建一个 Vue 应用实例,用于初始化一个新的 Vue 应用。
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
- createSSRApp(): 创建一个用于服务端渲染 (SSR) 的 Vue 应用实例。
- app.mount(): 将 Vue 应用实例挂载到指定的 DOM 元素上,启动应用。
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
app.mount("#app");
- app.unmount(): 卸载已经挂载的 Vue 应用实例,用于手动卸载应用。
- app.component(): 定义或注册全局组件。
import { createApp } from "vue";
import App from "./App.vue";
import Page from "@components/layout/Page.vue";
const app = createApp(App);
//注册全局组件
app.component('Page',Page);
app.mount("#app");
- app.use(plugin,options): 安装 Vue.js 插件,options需要查看插件有哪些配置
import { createApp } from "vue";
import "./style.scss";
import App from "./App.vue";
import router from "@/router.js";
import pinia from "@store/pinia.js";
import lang from "@lang/lang.js";
import Page from "@components/layout/Page.vue";
const app = createApp(App);
app.use(router);
app.use(pinia);
app.use(lang);
//注册全局组件
app.component('Page',Page);
app.mount("#app");
- app.directive(): 注册全局自定义指令。
- app.provide(): 在应用的上下文中提供一个全局可访问的数据或方法。
- app.runWithContext(): 在指定上下文中运行一个函数。
- app.mixin(): 应用一个全局 mixin,不推荐。
- app.version: Vue 的版本号。
- app.config: 全局配置对象,包含了一些全局配置选项。
- app.config.errorHandler: 全局错误处理函数,用于处理应用中的错误。
- app.config.warnHandler: 全局警告处理函数,用于处理应用中的警告。
- app.config.performance: 用于配置性能相关的选项。
- app.config.compilerOptions: 编译器选项,用于配置模板编译器的行为。
- app.config.globalProperties: 全局属性对象,用于添加全局属性或方法。
- app.config.optionMergeStrategies: 选项合并策略对象,用于自定义选项的合并行为。
十五、vue自定义插件
- 编写插件
import {createApp} from "vue";
import App from "./App.vue";
const app = createApp(App);
app.use({
install: (app, options) => {
console.log(app, options)
}
}, {
test: '测试插件配置'
})
app.mount("#app");
- 插件中的 Provide / Inject
import {createApp} from "vue";
import App from "./App.vue";
const app = createApp(App);
app.use({
install: (app, options) => {
app.provide('message', {text: '请求错误'})
}
}, {
test: '测试插件配置'
})
app.mount("#app");
- 插件使用场景
- 通过 app.component() 和 app.directive() 注册一到多个全局组件或自定义指令。
- 通过 app.provide() 使一个资源可被注入进整个应用。
- 向 app.config.globalProperties 中添加一些全局实例属性或方法
相关推荐
- 从IDEA开始,迈进GO语言之门(idea got)
-
前言笔者在学习GO语言编程的时候,GO语言在国内还没有像JAVA/Php/Python那样普及,绕了不少的弯路,要开始入门学习一门编程语言,最好就先从选择一个好的编程语言的开发环境开始,有了这个开发环...
- 基于SpringBoot+MyBatis的私人影院java网上购票jsp源代码Mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于SpringBoot...
- 基于springboot的个人服装管理系统java网上商城jsp源代码mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于springboot...
- 基于springboot的美食网站Java食品销售jsp源代码Mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于springboot...
- 贸易管理进销存springboot云管货管账分析java jsp源代码mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目描述贸易管理进销存spring...
- SpringBoot+VUE员工信息管理系统Java人员管理jsp源代码Mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍SpringBoot+V...
- 目前见过最牛的一个SpringBoot商城项目(附源码)还有人没用过吗
-
帮粉丝找了一个基于SpringBoot的天猫商城项目,快速部署运行,所用技术:MySQL,Druid,Log4j2,Maven,Echarts,Bootstrap...免费给大家分享出来前台演示...
- SpringBoot+Mysql实现的手机商城附带源码演示导入视频
-
今天为大家带来的是基于SpringBoot+JPA+Thymeleaf框架的手机商城管理系统,商城系统分为前台和后台、前台用的是Bootstrap框架后台用的是SpringBoot+JPA都是现在主...
- 全网首发!马士兵内部共享—1658页《Java面试突击核心讲》
-
又是一年一度的“金九银十”秋招大热门,为助力广大程序员朋友“面试造火箭”,小编今天给大家分享的便是这份马士兵内部的面试神技——1658页《Java面试突击核心讲》!...
- SpringBoot数据库操作的应用(springboot与数据库交互)
-
1.JDBC+HikariDataSource...
- SpringBoot 整合 Flink 实时同步 MySQL
-
1、需求在Flink发布SpringBoot打包的jar包能够实时同步MySQL表,做到原表进行新增、修改、删除的时候目标表都能对应同步。...
- SpringBoot + Mybatis + Shiro + mysql + redis智能平台源码分享
-
后端技术栈基于SpringBoot+Mybatis+Shiro+mysql+redis构建的智慧云智能教育平台基于数据驱动视图的理念封装element-ui,即使没有vue的使...
- Springboot+Mysql舞蹈课程在线预约系统源码附带视频运行教程
-
今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的Springboot+Mysql舞蹈课程在线预约系统,系统项目源代码在【猿来入此】获取!https://www.yuan...
- SpringBoot+Mysql在线众筹系统源码+讲解视频+开发文档(参考论文
-
今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的在线众筹管理系统,主要实现了普通用户在线参与众筹基本操作流程的全部功能,系统分普通用户、超级管理员等角色,除基础脚手架外...
- Docker一键部署 SpringBoot 应用的方法,贼快贼好用
-
这两天发现个Gradle插件,支持一键打包、推送Docker镜像。今天我们来讲讲这个插件,希望对大家有所帮助!GradleDockerPlugin简介...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 从IDEA开始,迈进GO语言之门(idea got)
- 基于SpringBoot+MyBatis的私人影院java网上购票jsp源代码Mysql
- 基于springboot的个人服装管理系统java网上商城jsp源代码mysql
- 基于springboot的美食网站Java食品销售jsp源代码Mysql
- 贸易管理进销存springboot云管货管账分析java jsp源代码mysql
- SpringBoot+VUE员工信息管理系统Java人员管理jsp源代码Mysql
- 目前见过最牛的一个SpringBoot商城项目(附源码)还有人没用过吗
- SpringBoot+Mysql实现的手机商城附带源码演示导入视频
- 全网首发!马士兵内部共享—1658页《Java面试突击核心讲》
- SpringBoot数据库操作的应用(springboot与数据库交互)
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)