然后通过this.$refs.标志名 皆可以获取到 _父页面获取子组件dom class vue">
当前位置:   article > 正文

Vue.js 进阶技巧Day01: 获取DOM节点,获取子组件对象,跨组件通信/依赖注入,表单验证实例_父页面获取子组件dom class vue

父页面获取子组件dom class vue

目录

0x00 $refs、$parent 、$children

0x02 provide 和 inject 跨多组件通信 依赖注入

0x03 表单验证实例


0x00 $refs、$parent 、$children

获取普通元素的dom节点,只需要给要获取的dom节点一个ref属性 作为标志

  1. <!-- 获取普通元素 -->
  2. <input type="text" class='form-control' ref="iamshangrui">

然后通过this.$refs.标志名 皆可以获取到 对应的dom对象,之后的dom操作 和原生的dom操作相同

注意必须在页面渲染完成之后,才能获取到dom节点

  1. export default{
  2. //页面渲染完成的时候
  3. mounted(){
  4. //获取input的dom节点
  5. // console.log(this.$refs.iamshangrui)
  6. //修改样式 : 和以前的dom操作一样
  7. this.$refs.iamshangrui.style.borderColor ='red'
  8. //获取焦点
  9. this.$refs.iamshangrui.focus()
  10. }
  11. }

如果多个元素的ref属性值相同,那么通过this.$refs.标志名 获取到的将是一个数组

  1. <!-- 获取列表 -->
  2. <ul class='list-group'>
  3. <li class='list-group-item' v-for='(item,index) in list' :key='index' ref='list'>item{{item}}</li>
  4. </ul>
  1. console.log(this.$refs.list);
  2. this.$refs.list[3].style.background ='#ccc';

获取子组件 并调用子组件中的方法

  1. <template>
  2. <div>
  3. <h2>This is Input</h2>
  4. <input type="text" v-model='val' class='form-control' ref='input'>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. data(){
  10. return {
  11. val:'输入框'
  12. }
  13. },
  14. methods:{
  15. focus(){
  16. console.log("this is focus")
  17. this.$refs.input.focus()
  18. }
  19. }
  20. }
  21. </script>
  1. <!-- 获取组件 -->
  2. <demo-item ref='demoItem'></demo-item>

同样需要给子组件一个ref标志

  1. //获取子组件
  2. console.log(this.$refs.demoItem)
  3. //调用子组件中的focus方法
  4. this.$refs.demoItem.focus()

通过父组件调用子组件中的方法,可以用来修改子组件中的数据

  1. export default {
  2. data(){
  3. return {
  4. header:"标题",
  5. val:'输入框'
  6. }
  7. },
  8. methods:{
  9. focus(){
  10. console.log("this is focus")
  11. this.$refs.input.focus()
  12. },
  13. renameHeader(data){
  14. this.header = data;
  15. }
  16. }
  17. }
this.$refs.demoItem.renameHeader("Hello world")

也可以直接 修改子组件中的数据

	this.$refs.demoItem.header="123456"

还有更加简便的方式:不需要加ref,直接用$children 来获取

  1. this.$children; //获取该组件/页面的所有 子组件对象 组成的数组
  2. this.$children[0].header ='hello world'

子组件中获取父组件,并修改父组件中的数据

this.$parent 获取到该子组件的父组件

this.$parent.数据名 = 值

this.$parent.title="秋天的奶茶"

this.$parent.方法名 调用父组件的方法

0x02 provide 和 inject 跨多组件通信 依赖注入

父组件可以通过provide 将 数据 和方法 暴露出来,

子组件(或 孙子组件)通过inject 来 接收调用

  1. export default {
  2. provide(){
  3. return {
  4. title:this.title,
  5. rename:this.rename
  6. }
  7. },
  8. data(){
  9. return {
  10. title:"父组件标题"
  11. }
  12. },
  13. components:{
  14. demoItem
  15. },
  16. methods:{
  17. rename(data){
  18. this.title = data
  19. }
  20. }
  21. }

子组件:

  1. <script>
  2. export default{
  3. inject:['title','rename'],
  4. methods:{
  5. clickEvent(){
  6. this.rename("哈哈哈")
  7. }
  8. }
  9. }
  10. </script>

0x03 表单验证实例

demo.vue

  1. <template>
  2. <div class='container p-5'>
  3. <!-- <form>
  4. <div class="form-group">
  5. <label for="username">用户名</label>
  6. <input type='text' class="form-control is-valid" id="username">
  7. <div class="valid-feedback">
  8. 验证通过
  9. </div>
  10. </div>
  11. <div class="form-group">
  12. <label for="email">邮箱</label>
  13. <input type="email" class="form-control is-invalid" id="email">
  14. <div class="invalid-feedback">
  15. 邮箱不能为空
  16. </div>
  17. </div>
  18. <button type="submit" class="btn btn-primary">提交</button>
  19. </form> -->
  20. <z-form :form='form' :validate='validate'>
  21. <z-form-item label='用户名' name='username'>
  22. <input type='text' class="form-control" id="username" v-model='form.username'>
  23. <!-- 当form.username 变化时,z-form就会监听到form的变化,然后通知给子组件z-form-item,z-form-item 决定是否显示错误框 -->
  24. </z-form-item>
  25. <z-form-item label="邮箱" name="email">
  26. <input type="text" class="form-control" id="email" v-model='form.email'>
  27. </z-form-item>
  28. <z-form-item>
  29. <button type="submit" class="btn btn-primary">提交</button>
  30. </z-form-item>
  31. </z-form>
  32. </div>
  33. </template>
  34. <script>
  35. import zForm from './z-form.vue'
  36. import zFormItem from './z-form-item.vue'
  37. export default {
  38. components:{
  39. zForm,
  40. zFormItem
  41. },
  42. data() {
  43. return {
  44. //表单数据
  45. form: {
  46. username: "",
  47. email: ""
  48. },
  49. //验证规则
  50. validate: [{
  51. name: "username",
  52. validate: {
  53. required: {
  54. data: true, //true表示必填
  55. msg: "用户名不能为空"
  56. },
  57. rule: {
  58. data:"username",
  59. msg:"用户名格式错误"
  60. }
  61. }
  62. },
  63. {
  64. name: "email",
  65. validate: {
  66. required: {
  67. data: true,
  68. msg: "邮箱不能为空"
  69. },
  70. //自定规则
  71. rule: {
  72. data:'email',
  73. msg:"邮箱格式错误"
  74. }
  75. }
  76. }
  77. ]
  78. }
  79. }
  80. }
  81. </script>
  82. <style>
  83. </style>

z-form.vue

  1. <template>
  2. <form>
  3. <slot></slot>
  4. </form>
  5. </template>
  6. <script>
  7. export default{
  8. props:[
  9. 'form',
  10. 'validate'
  11. ],
  12. //注入到子组件
  13. provide(){
  14. return {
  15. form:this.form,
  16. validate:this.validate
  17. }
  18. }
  19. }
  20. </script>
  21. <style>
  22. </style>

z-form-item.vue

  1. <template>
  2. <div class="form-group">
  3. <label :for="name">{{label}}</label>
  4. <slot></slot>
  5. <div :class="status == 1?'valid-feedback':'invalid-feedback'">
  6. {{msg}}
  7. </div>
  8. </div>
  9. </template>
  10. <script>
  11. let rules = {
  12. username: /^[a-zA-Z0-9_-]{4,16}$/,
  13. email: /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/
  14. }
  15. export default{
  16. props:[
  17. 'label',
  18. 'name'
  19. ],
  20. //接收父组件注入的属性
  21. inject:['form','validate'],
  22. data(){
  23. return {
  24. vali:{
  25. },
  26. msg:'验证失败',
  27. status:0, //0 验证未通过 1验证通过
  28. inputDom:''
  29. }
  30. },
  31. methods:{
  32. fail(msg){
  33. this.msg = msg
  34. this.status = 0
  35. //判断当前是否处于失败状态
  36. if(this.inputDom.className.indexOf('is-invalid')>-1){
  37. return;
  38. }
  39. if(this.inputDom.className.indexOf('is-valid')>-1){
  40. return this.inputDom.className = this.inputDom.className.replace(/is-valid/,'is-invalid')
  41. }
  42. this.inputDom.className += ' is-invalid'
  43. },
  44. success(msg){
  45. this.msg = msg
  46. this.status = 1
  47. //判断当前是否处于成功状态
  48. if(this.inputDom.className.indexOf('is-valid')>-1){
  49. return;
  50. }
  51. if(this.inputDom.className.indexOf('is-invalid')>-1){
  52. return this.inputDom.className = this.inputDom.className.replace(/is-invalid/,'is-valid')
  53. }
  54. this.inputDom.className += ' is-valid'
  55. }
  56. },
  57. //页面渲染完成后
  58. mounted(){
  59. //拿到插槽对应的输入框
  60. //如果子组件是slot形式插入的,不能用this.$children拿到子组件,必须用this.$slots
  61. let input = this.$slots.default[0]
  62. if(!input){
  63. return;
  64. }
  65. //真正的dom节点
  66. this.inputDom = input.elm;
  67. console.log(this.inputDom);
  68. //初始化验证规则
  69. this.validate.forEach(item=>{
  70. if(item.name === this.name){
  71. this.vali = item.validate
  72. }
  73. })
  74. //监听字段变化
  75. this.$watch('form.'+this.name,(newValue,oldValue)=>{
  76. //验证数据是否合法
  77. //1.验证是否必填
  78. if(true === this.vali.required.data){
  79. if(newValue.trim() === ''){
  80. console.log('fail')
  81. this.fail(this.vali.required.msg)
  82. return
  83. }
  84. }
  85. //2.验证其他规则
  86. if(this.vali.rule && this.vali.rule.data){
  87. let currentRule = rules[this.vali.rule.data]
  88. if(!currentRule.test(newValue)){
  89. return this.fail(this.vali.rule.msg)
  90. }
  91. }
  92. //3.成功
  93. console.log('success')
  94. this.success("验证通过")
  95. })
  96. }
  97. }
  98. </script>
  99. <style>
  100. </style>

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/133949
推荐阅读
相关标签
  

闽ICP备14008679号