子组件修改父组件传递过来的值
vue 的子组件 不是 不能直接更改父组件的值,需要将props 的值 给到子组件,后再修改,
否则:Unexpected mutation of “props” prop.
vue3提供了一个解决:toRefs:https://v3.cn.vuejs.org/api/refs-api.html#torefs
toRefs 非常有用,这样消费组件就可以在不丢失响应性的情况下对返回的对象进行解构/展开
使用
const { foo, bar } = reactive({
foo: 1,
bar: 2
})
// 核心解决, 使用reactive接收不会响应时更新,需要使用toRefs
const props = defineProps({
drawerStatus: {
type: Boolean
}
})
const {drawerStatus} = toRefs(props)
使用toRefs进行解决
<template>
<el-drawer v-model="drawerStatus" title="设置部门助理" :before-close="handleClose">
<div class="drawer-footer">
<el-button>取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</div>
</el-drawer>
</template>
<script setup>
import {reactive, toRefs} from 'vue'
const props = defineProps({
drawerStatus: {
type: Boolean
}
})
const emits = defineEmits(['upDrawerStatus'])
const {drawerStatus} = toRefs(props)
console.log(33333333, drawerStatus)
// 新增角色数据
const formData = reactive({
})
const onSubmit = () => {
handleClose()
}
const handleClose = () => {
console.log('关闭抽屉')
emits('upDrawerStatus', false)
}
</script>
子组件向父组件传值emit的使用注意事项
子组件的写法
需要从setup函数中引出{emit}
<template>
<div id="center" v-if="isShow">
<h2><slot>my model</slot></h2>
<el-button type="primary" @click="btnclose">传递事件</el-button>
<el-button type="primary" @click="btnparents">子组件触发父组件的方法</el-button>
</div>
</template>
<script lang="ts">
import {
defineComponent,getCurrentInstance
} from "vue";
export default defineComponent({
props: {
isShow:{
type:Boolean,
default:true
}
},
emits: {
"my-close": null,
},
setup(props, {emit}) {
const {proxy}:any=getCurrentInstance()
const btnclose = () => {
emit("my-close",'传递的数据')
}
const btnparents=()=>{
console.log(proxy);
proxy.$parent.addNum()
}
return {
btnclose,
proxy,
btnparents
};
},
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
父组件使用
<template>
<HelloWorld @my-close="myModealHide" :isShow="myModalShow">solt</HelloWorld>
<el-button @click="myModalBlock">my modal2</el-button>
<el-button type="primary" @click="toDelit">用户详情</el-button>
</template>
<script lang="ts">
import { defineComponent, computed, onMounted, watch,ref,getCurrentInstance,reactive,nextTick ,toRefs} from 'vue'
import {
useStore,
mapState,
} from 'vuex'
import {useRoute,useRouter,useLink,UseLinkOptions} from "vue-router"
import { useI18n } from "vue-i18n";
import {data} from "@/utils/TypeState"
import HelloWorld from '@/components/HelloWorld.vue'
export default defineComponent({
components:{
HelloWorld
},
setup(props, context){
console.log('context',context);
const store=useStore()
const {proxy}:any=getCurrentInstance()
const number=ref<string|Number>(store.state.app.age)
const Route=useRoute()
const RouteLink=useLink
const { t } = useI18n();
const languageD=()=>{
proxy.$i18n.locale=data.seleLanguage
}
console.log(store.state.app.allMenuList instanceof Array);
console.log(proxy);
// 监听指定基础类型数据
const addNum=()=>{
// name.value=Number(name.value) +1
name.value++
}
watch(name, (now, prev) => {
console.log(now, prev, 'count')
})
// 监听reactive创建的响应式变量,可以直接监听对象,必须使用内联函数
watch(() => data.tableData, (now, prev) => {
console.log(now, prev, 'tableData')
})
const myModalShow = ref(false)
const myModealHide=(val:any)=>{
myModalShow.value=false
console.log(val);
}
const myModalBlock =()=>{
myModalShow.value=true
}
const toDelit=():void=>{
proxy.$router.push("/userAdminDetils")
}
return {
age,
number,
proxy,
store,
name,
addNum,
...toRefs(data) ,
t,
languageD,
myModealHide,
myModalBlock,
myModalShow,
toDelit
}
},
created () {
console.log(this.$route);
console.log(this.store.state.app.age);
// console.log(this.$store);//报错
}
})
</script>
<style>
</style>
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。