响应式数据的判断
- isRef: 检查一个值是否为一个
ref对象 - isReactive: 检查一个对象是否是由
reactive创建的响应式代理 - isReadonly: 检查一个对象是否是由
readonly创建的只读代理 - isProxy: 检查一个对象是否是由
reactive或者readonly方法创建的代理
1.props传值
// 父组件中和之前vue2一样,子组件中接受
<template>
<div>
<h2>{{ msg }}</h2>
</div>
</template>
// setup 语法糖中
<script setup>
import { defineProps,toRefs } from 'vue'
export interface IProps {
msg: string;
falg: boolean;
}
// 无默认值
const props = defineProps({
msg: String,
falg:boolean,
})
// 有默认值
const props = withDefaults(defineProps<IProps>(), {
msg:'hello world'
falg: false,
});
const {msg,propsData} = props // 这样会失去响应式
const {msg,propsData} = toRefs(props) // 这样才可以,js中使用需要.value
</script>
// setup 中
<script>
import { defineComponent,toRefs } from 'vue'
export default defineComponent({
props: {
msg: {
type: String
}
},
setup(props, context) {
const {msg,propsData} = toRefs(props)
return {}
}
})
</script>
2.$emit 自定义事件
// 父组件中和之前vue2 一样
<template>
<div>
<el-button @click="sonClick">Emit</el-button>
</div>
</template>
// setup 语法糖
<script setup>
import { ref,defineEmits } from 'vue'
const count = ref('传递的数据')
const emits = defineEmits(['queryParent'])
function sonClick() {
emits('queryParent', count)
}
</script>
// setup函数 中
setup(props, context) {
function change() {
context.emit('valueChange', 3)
}
}
3.ref获取子组件实例
<template>
<div id="app" ref="root">
<p class="child"></p>
</div>
</template>
<script>
import {ref, onMounted} from 'vue'
export default {
setup() {
const root = ref(null)
onMounted(() => {
// 注意:在onMounted中才可以获取到
console.log(root.value)
})
}
}
</script>
4.store 获取Vuex
<script>
import {onMounted} from 'vue'
import {useStore} from 'vuex'
export default {
name: 'App',
setup(props, context) {
const store = useStore()
onMounted(() => {
console.log(store.state.info)
store.commit('show')
})
}
}
</script>
5.直接在style中使用变量
<script setup>
import { ref, reactive, getCurrentInstance } from 'vue'
const boxWidth = ref('100px')
interface IProps {
num: number;
height: string;
}
defineProps<IProps>();
</script>
<style scoped>
.testBox{
height: v-bind(height); // 直接使用props中的属性和template中一样
width: v-bind(boxWidth);
border: 1px solid #ccc;
}</style>
6.watch监听
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
const tempObj={
name:'jp',
age:'18',
}
// 单个响应式数据监听
watch(count,(val)=>{console.log(val)},{immediate:true})
// watch监听非响应式数据的时候需要使用回调函数的形式
watch(()=>tempObj,(val)=>{console.log(val)},{immediate:true,deep:true})
// 多个数据同时监听,使用数组
watch([()=>tempObj,count],(val)=>{console.log(val)},{immediate:true,deep:true})
</script>
7.compouted 计算属性
<script setup>
import { reactive, computed } from 'vue'
const user=reactive({
firstName:'J',
lastName:'P'
})
const realName = compoted(()=>user.firstName + user.lastName)
// 计算属性的函数中可以传入一个对象,可以包含`set`和`get`函数,进行读取和修改的操作
const realName = computed({
get() {
return user.firstName + '_' + user.lastName;
},
set(val: string) {
const names = val.split('_');
user.firstName = names[0];
user.lastName = names[1];
},
});
</script>
8.pinia 使用
- 创建pinia,stores中创建index.ts
// https://pinia.vuejs.org/
import { createPinia } from 'pinia';
// 创建
const pinia = createPinia();
// 导出
export default pinia;
- main.ts中引入,挂载到app
import pinia from '@/stores/index';
app.use(pinia)
- 创建模块
import { defineStore } from 'pinia';
interface IPovertyRelief {
secondaryMenu: string; // 二级菜单 一张图 | 五小产业
pageType: string; // 页面类型
pageName: string; // 页面名称
showDetails:boolean; // 住户详情弹框
residentId:string; // 住户id
}
/**
* 后端返回原始路由(未处理时)
* @methods setCacheKeepAlive 设置接口原始路由数据
*/
export const usePovertyRelief = defineStore('povertyRelief', {
state: (): IPovertyRelief => ({
secondaryMenu: 'main',
pageType: 'garden',
pageName:'',
showDetails:false,
residentId:'',
}),
actions: {
},
});
4.页面中引入使用
import { storeToRefs } from 'pinia';
import { usePovertyRelief } from '@/stores/povertyRelief';
const povertyRelief = usePovertyRelief();
const { secondaryMenu, showDetails } = storeToRefs(povertyRelief); // 直接结构会失去响应式
// secondaryMenu, pageType 同proxy代理ref,template中直接使用,script中需要使用`value`属性;
9.v-model多个数据绑定更新
// 父组件
<Editor v-model:get-html="state.editor.htmlVal" v-model:get-text="state.editor.textVal" />
// 子组件
const props = defineProps({
getHtml: String,
getText: String,
});
const emit = defineEmits(['update:getHtml', 'update:getText']);
const handleChange = (editor: IDomEditor) => {
emit('update:getHtml', editor.getHtml());
emit('update:getText', editor.getText());
};
10.vite项目 批量导入图片
<script setup lang="ts">
// 导入图片,这里的路径需要是相对路径
const imgList = import.meta.glob('../../assets/img/*.*',{eager:true})
console.log(imgList)
</script>
11.Teleport传送门使用
// 注意: Teleport,使用传送门组件做全屏页面路由跳转时外层必须包裹一层容器,否则返回其他页面都是空白;
<div>
<Teleport to="#app">
<div class="market_container"></div>
</Teleport>
</div>