目录
[全局状态管理 vueX](#全局状态管理 vueX)
[全局状态管理 Pinia](#全局状态管理 Pinia)
vue2
基础属性
data:用于定义组件的初始数据,必须是一个函数,返回一个对象,每个组件实例都会有自己的数据对象,避免组件之间数据相互影响。
props:用于接收父组件传递的数据,必须是一个数组或对象,数组中的每个元素是一个字符串,表示接收的属性名,对象中的每个属性表示接收的属性名和属性值的类型。
methods:用于定义组件的方法,每个方法都是一个函数,可以在组件中通过 this 访问。
watch:用于监听数据的变化,当数据发生变化时,执行相应的回调函数,可以监听单个数据或多个数据的变化。
computed:用于计算属性,根据已有的数据计算出新的数据,可以监听多个数据的变化,只有当依赖的数据发生变化时才会重新计算。
created:在实例创建完成后立即执行,可以在这个钩子函数中进行数据初始化、事件监听等操作。
computed计算属性

watch
基本使用
javascript
watch: {
name: { //这里是要监听的变量名
handler(newValue, oldValue) { //这里的第一个参数是改变后的值,第二个参数是原来的值
console.log('改后的值是:' + newValue)
console.log('原来的值是:' + oldValue)
}
}
}
简写
javascript
watch: {
name(newValue, oldValue) { //这里的第一个参数是改变后的值,第二个参数是原来的值
console.log('改后的值是:' + newValue)
console.log('原来的值是:' + oldValue)
}
}
immediate:就是当值第一次绑定时,不会执行监听函数,只有值发生改变时才会执行。如果我们需要在最初绑定值的时候也执行函数,需要用到immediate属性;
deep:当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,此时就需要deep属性对对象进行深度监听,数组字符串一般不需要。
javascript
watch: {
name: {
handler(newValue, oldValue) {//这里的第一个参数是改变后的值,第二个参数是原来的值
console.log('改后的值是:' + newValue)
console.log('原来的值是:' + oldValue)
},
immediate: true,
deep:true
}
}
组件通信
父传子
子传父

非父子通信 eventBus事件总线(兄弟组件)
src/utils/eventBus.js
javascript
import Vue from 'vue';
export const EventBus = new Vue();
javascript
<template>
<button @click="sendData">发送数据到组件 B</button>
</template>
<script>
import { EventBus } from '@/utils/eventBus';
export default {
methods: {
sendData() {
EventBus.$emit('dataEvent', '来自组件 A 的数据');
}
}
};
</script>
javascript
<template>
<p>收到的数据:{{ receivedData }}</p>
</template>
<script>
import { EventBus } from '@/utils/eventBus';
export default {
data() {
return { receivedData: '' };
},
created() {
EventBus.$on('dataEvent', data => {
this.receivedData = data;
});
},
beforeDestroy() {
EventBus.$off('dataEvent');
}
};
</script>
组件通信------非父子通信 Provide Inject(跨层级组件)
javascript
<template>
<ChildComponent />
</template>
<script>
export default {
provide() {
return {
sharedMessage: 'Hello from Provide!'
};
}
};
</script>
javascript
<template>
<p>收到的数据:{{ sharedMessage }}</p>
</template>
<script>
export default {
inject: ['sharedMessage']
};
</script>
组件通信------非父子通信 attrs listeners
官方文档介绍:包含了父作用域不作为prop被识别(且获取)的attribute绑定(class和style除外)。当一个组件没有生命任何prop时,这里会包含所有父作用域的绑定(class和style除外),并且可以通过v-bind="$attrs"传入内部组件--在创建高级别的组件时非常有用。
通俗地来说就是如果从父组件传过来的值,没有在子组件中被接收,那么这些值就会被存在$attrs对象中。
javascript
//Father.vue
<template>
<div class="father">
<span>父亲</span>
<Son :message="message" :age="18"></Son>
</div>
</template>
<script>
import Son from "../components/Son.vue";
export default {
data() {
return {
message: "父组件传过来的值",
age: 18,
};
},
components: {
Son,
},
};
</script>
//Son.vue
<template>
<div class="son">
<span>儿子</span>
<GrandSon v-bind="$attrs"></GrandSon>
</div>
</template>
<script>
import GrandSon from "../components/GrandSon.vue";
export default {
components: {
GrandSon,
},
created() {
console.log("son", this.$attrs);
},
};
//GrandSon.vue
<template>
<div class="grandson">
<span>孙子</span>
<div>{{ $attrs.message }}</div>
</div>
</template>
<script>
export default {
created() {
console.log("grandson", this.$attrs);
},
};
</script>
组件通信------ref $refs
引用信息会注册在父组件的$ref对象上 vue2/vue3 ref组件通信
javascript
//父
<template>
<div id="app">
<TodoItem ref="msg"></TodoItem>
<p ref="dom"></p>
</div>
</template>
<script>
import TodoItem from './components/so.vue'
export default {
name: 'App',
components: {
TodoItem
},
mounted() {
console.log(this.$refs)
// 通过这种方法给子组件传递数据
this.$refs.msg.getmsg("我是tc") // this.$refs.msg指向的是子组件的实例
},
}
</script>
//子
<template>
<div class="so">
<p>{{ msg }}</p>
</div>
</template>
<script>
export default {
name: "todo-item",
data() {
return {
msg: ''
}
},
methods: {
getmsg(s) {
this.msg = s
}
}
}
</script>
全局状态管理 vueX
路由
路由守卫
vue3
基础属性
javascript
import { computed, ref } from 'vue';
export default {
setup() {
const count = ref(0);
// 定义一个计算属性
const doubledCount = computed(() => count.value * 2);
return {
count,
doubledCount
};
}
};
javascript
const fullName = computed({
// getter
get() {
return firstName.value + ' ' + lastName.value
},
// setter
set(newValue) {
// 注意:我们这里使用的是解构赋值语法
[firstName.value, lastName.value] = newValue.split(' ')
}
})
watch
javascript
//ref
<script setup lang="ts">
import { watch, ref } from 'vue'
const sum=ref(1);
// New: 新值 | Old: 老值
watch(sum,(New, Old)=>{
console.log(`新值:${New} --------- 老值:${Old}`)
})
</script>
javascript
//reactive
<script setup lang="ts">
import { watch,reactive} from 'vue'
// 响应式变量
const sum = reactive({
value: 1
})
// watch是一个函数
// 第一个参数: 要监听的响应式变量(数据源)
// 第二个参数:执行的回调函数
// 第三个参数: 配置(例如deep深度监听/immediate是否立即监听等)
// 注意:当监听一个对象时,第一个参数数据源必须是函数且返回一个值即 "() => 对象.要监听的属性"
watch(() => sum.value, (New, Old) => {
console.log(`新值:${New} --------- 老值:${Old}`)
}, { immediate: true, deep:ture })
</script>
watchEffect
- 不需要手动传入依赖(不用指定监听对象)
- 无法获取原始值,只能获取更新后的值
- 立即执行(在
onMounted
前调用)- 一些异步操作放里面更加的合适
javascript
const count = ref(0)
watchEffect(() => {
console.log(count.value)
})
javascript
const stop = watchEffect(() => {
/* ... */
})
// 停止监听
stop()
副作用清除 做一些异步请求连发限制或取消请求的操作,保证请求数据的完整和准确性。
javascript
watchEffect(async (onCleanup) => {
const { response, cancel } = doAsyncWork(id.value)
// `cancel` 会在 `id` 更改时调用
// 以便取消之前
// 未完成的请求
onCleanup(cancel)
data.value = await response
})
组件通信
父传子
javascript
<Child info="我爱祖国" :money="money"></Child>
javascript
子组件获取父组件传递数据:方式1
let props = defineProps({
money:{
type:Number,
default:0
}})
子组件获取父组件传递数据:方式2
let props = defineProps(["info",'money']);
子传父
javascript
<Event2 @xxx="handler3"></Event2>
javascript
<script setup lang="ts">
let $emit = defineEmits(["xxx"]);
const handler = () => {
$emit("xxx", "法拉利", "茅台");
};
</script>
v-model
javascript
<template>
<child v-model:name="name"></child>
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const name = ref('XXX')
</script>
javascript
<template>
<input :value="name" @input="updateName" />
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps(['name'])
const emit = defineEmits(['update:name'])
const updateName = (e) => {
emit('update:name', e.target.value)
}
</script>
依赖注入 (Provide/Inject)
javascript
<script setup>
import { provide, ref } from 'vue'
const themeColor = ref('blue')
provide('theme', themeColor)
</script>
javascript
<script setup>
import { inject } from 'vue'
const theme = inject('theme')
console.log(theme.value) // 'blue'
</script>
ref
javascript
<template>
<TodoItem :ref="(el) => child = el"></TodoItem>
<p ref="dom"></p>
</template>
<script>
import TodoItem from './components/so'
import { ref, onMounted } from 'vue'
export default {
name: 'App',
components: {
TodoItem
}
}
</script>
<script setup>
const child = ref(null)
// const msg = ref()
const dom = ref()
onMounted(() => {
console.log(child.value.getmsg("我是tc"))
// msg.value.getmsg("我是tc")
dom.value.innerHTML = "我是一个普通的DOM元素"
})
</script>
javascript
<template>
<div class="so">
<p>{{ msg }}</p>
</div>
</template>
<script setup>
import { ref, defineExpose } from 'vue'
const msg = ref("")
const getmsg = (s) => {
msg.value = s
}
// 想要父组件可以获取到需要使用defineExpose向父组件暴露
defineExpose({getmsg})
</script>
事件总线
vue3中移除了事件总线,可以借助于第三方工具来完成,Vue官方推荐 mitt 或 tiny-emitter
全局状态管理 Pinia
路由
路由守卫
vue2、vue3生命周期

setup
setup() 钩子是在组件中使用组合式 API 的入口