Vue3 依赖注入------父级组件与子孙级组件之间的数据传递
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3 依赖注入------父级组件与子孙级组件之间的数据传递相关的知识,希望对你有一定的参考价值。
参考技术A 依赖注入是针对 父级组件与子孙级组件之间的数据传递 数据的传递,或者有很多后代组件的情况,只针对直系后代使用,实现组件之间的数据共享。需要使用到vue提供的 provide以及inject 方法
其中,provide用来提供传递的数据,inject用来接收数据
子组件的如果也想要使用爷爷组件的数据,操作方法是一样的,也是通过inject进行接收并且return,然后直接使用即可。
总结:
1.父传子孙数据:provide
2.子孙得到数据:inject
这里还是使用provide和inject来进行数据的传递,但是这次是通过函数的参数进行传值。
1.导入provide和inject到父组件中
2.通过provide声明函数,并要有形参用来接收孙组件传来的实参
总结:
1.孙子组件传递数据给爷爷组件,需要通过provide一个函数的方式实现
2.爷爷组件传递一个函数,后续通过函数的形参获取数据
孙子组件获取并调用该函数传递数据
1.父子传参:
爹给儿子传递数据,通过 自定义属性 ,给组件props属性,然后绑定在父组件的子组件上
儿子给爹传递数据,通过 自定义事件
2.爷爷孙子传参:
孙子给爷爷传值是 函数 ,通过provide一个函数,在孙子组件inject注入,然后通过参数传递想要传递的值
爷爷给子孙传递 数据 ,通过provide一个变量和值,在孙子组件inject注入,孙子组件通过inject接收数据即可。
3.后代给前辈 传数据都需要 函数传参
4.自定义属性、事件(函数)一般都绑定在父组件中,也就是provide一般出现在父组件,不论是提供给孙组件的数据还是接收孙组件数据的函数
Vue补充
1.vue中inject与provide的用法
provide/inject提供了一种新的组件间通信的方法。它允许父组件向子孙组件间进行跨层级的数据分发,但是provide/inject是非响应式的。一般用于子组件调用父组件的共有方法。它们两个需要一起使用,允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
实例如下:
Test.vue:
<template> <div class="about"> <h1>我是父组件:{{msg}}</h1> <button @click="changeMsg">点位改变</button> <test2></test2> </div> </template> <script> import test2 from "./Test2"; export default { name: "Test", data() { return { msg: "你好啊" }; }, //给子组件传递数据和方法 provide() { return { msg: this.msg, messageBox:this.messageBox }; }, components: { test2 }, methods: { changeMsg() { this.msg = "今天天气转暖"; }, messageBox(msg){ alert(msg) } } }; </script> <style> </style>
Test2.vue:
<template> <div><h3>我是子组件</h3>{{msg}} <button @click="message">我要执行父组件的方法</button> </div> </template> <script> export default { name:‘Test2‘, //接收父组件的数据 inject:[‘msg‘,‘messageBox‘], methods:{ message(){ this.messageBox(‘我是子组件‘) } } } </script> <style> </style>
当点击父组件中的按钮时,父组件中的msg已经改变,但是子组件中接收的数据并未发生变化。这就说明这种方式共享数据不是响应式的,一般不使用这种方式传递数据。
当点击子组件中的按钮时,会执行父组件的messageBox方法,是推荐的用法。
2.vue.nextTick()用法
在下次 DOM 数据更新循环结束之后执行延迟回调。也就是说此回调函数是延迟执行的,是在下一次DOM数据更新后自动执行。
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。主要用在两方面,一种是在vue的created函数中操作DOM数据时使用,另一种是修改DOM数据后获取最新的DOM数据。
2.1在vue的created函数中操作DOM数据时使用
<template> <div> <span ref="span">你好</span> </div> </template> <script> export default { name: "Hello", created() { //在DOM再次更新后执行此回调函数 this.$nextTick(() => { this.$refs.span.innerHTML = "今天加班"; }); }, }; </script> <style> </style>
2.2修改DOM数据后获取最新的DOM数据
<template> <div> <button id="firstBtn" @click="testClick()" ref="aa">{{msg}}</button> </div> </template> <script> export default { name: "Hello", data() { return { msg: "old" }; }, methods: { testClick() { //点击按钮修改数据 this.msg = "new"; console.log(this.$refs.aa.innerText); //输出:old //此时数据并没有更新,原因是DOM没有更新 //此时数据更新了,原因是在输出的时候DOM已经更新了 this.$nextTick(() => { console.log(this.$refs.aa.innerText); //输出:new }); } } }; </script> <style> </style>
3.使用vue的表单方式自定义验证方法进行验证
在验证的时候,除了el-form自带的验证规则外,还可以自己进行验证,然后在规则中指定验证的方法即可。如自定义手机号验证,不管验证是否通过,必须返回一个callback对象。代码如下:
<template> <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm" > <el-form-item label="用户名" prop="name"> <el-input v-model="ruleForm.name"></el-input> </el-form-item> <el-form-item label="角色" prop="role"> <el-select v-model="ruleForm.role" placeholder="请选择角色"> <el-option label="学生" value="0"></el-option> <el-option label="教师" value="1"></el-option> </el-select> </el-form-item> <el-form-item label="爱好" prop="hobby"> <el-checkbox-group v-model="ruleForm.hobby"> <el-checkbox label="0" name="hobby">跑步</el-checkbox> <el-checkbox label="1" name="hobby">打篮球</el-checkbox> <el-checkbox label="2" name="hobby">踢足球</el-checkbox> <el-checkbox label="4" name="hobby">听音乐</el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="性别" prop="sex"> <el-radio-group v-model="ruleForm.sex"> <el-radio label="0">男</el-radio> <el-radio label="1">女</el-radio> </el-radio-group> </el-form-item> <el-form-item label="手机号" prop="phone"> <el-input v-model="ruleForm.phone"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm(‘ruleForm‘)">保存</el-button> <el-button @click="resetForm(‘ruleForm‘)">重置</el-button> </el-form-item> </el-form> </template> <script> export default { name: "FormValidate", data() { //自定义验证规则,在rules中使用 //手机号验证 let phoneValidate = (rule, value, callback) => { let phoneReg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/; if (!value) { //如果为空就回调错误的信息 return callback(new Error("手机号不能为空")); } if (!phoneReg.test(value)) { callback(new Error("手机格式不正确")); } else { //这个必须要调用来放行 callback(); } }; return { ruleForm: { hobby: [] }, rules: { name: [ { required: true, message: "请输入姓名", trigger: "blur" }, { min: 2, max: 5, message: "长度在 2 到 5 个字符", trigger: "blur" } ], role: [{ required: true, message: "请选择角色", trigger: "change" }], hobby: [ { type: "array", required: true, message: "请至少选择一个爱好", trigger: "change" } ], sex: [{ required: true, message: "请选择性别", trigger: "change" }], phone: [{ required: true, validator: phoneValidate, trigger: "blur" }] } }; }, methods: { //提交验证 submitForm(formName) { this.$refs[formName].validate(valid => { if (valid) { alert(JSON.stringify(this.ruleForm)); //清除表单验证规则 this.$refs[formName].clearValidate() } else { console.log("error submit!!"); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } } }; </script> <style> </style>
4.vue filters中使用data中数据
vue 的filters中 this指向的并不是vue实例,但想要获取vue实例中data中的数据,可以在 beforeCreate中将vue实例赋值给定义的全局变量app,然后在filters中通过app代替this来获取data中的数据。
<template> <div> <div v-for="(item,index) in list" :key="index"> <p>姓名{{item.name}}</p> <p>性别{{item.sex | sexFilter}}</p> </div> </div> </template> <script> let vueApp = null export default { name: ‘UserFilters‘, data() { return { sexOption: [{ label: ‘男‘, value: 0 }, { label: ‘女‘, value: 1 }], list: [{ name: ‘张三‘, sex: 0 }, { name: ‘李四‘, sex: 1 }] } }, filters: { //性别过滤显示 sexFilter(data) { let resultData = ‘‘ vueApp.sexOption.forEach(element => { if (element.value == data) { resultData = element.label } }); return resultData } } } </script> <style scoped> </style>
.
以上是关于Vue3 依赖注入------父级组件与子孙级组件之间的数据传递的主要内容,如果未能解决你的问题,请参考以下文章