Vue3.X的父子組件、自定義組件,非父子組件獲取與傳值


組件間傳值及傳值校驗

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>study</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return { num: 1111 }
    },
    template: `
      <div><test :content="num" /></div>
    `
  });

  // type:String, Boolean, Array, Object, Function, Symbol
  // validator 校驗
  // required 必填
  // default 默認值
  app.component('test', {
    props: {
      content: {
        type: Number,
        validator: function(value) {
          return value < 500;
        },
        default: function() {
          return 456;
        }
      }
    },
    template: `<div>{{content}}</div>`
  });

  const vm = app.mount('#root');
</script>
</html>

父組件獲取子組件的數據和執行子組件方法

  1. 調用子組件的時候定義一個 ref
<v-header ref="header" />
  1. 父組件獲取子組件數據
this.$refs.header.屬性
  1. 父組件執行子組件的方法
this.$refs.header.方法

子組件獲取父組件的數據和執行父組件方法

  1. 子組件獲取父組件的數據
this.$parent.數據
  1. 子組件獲取父組件的方法
this.$parent.方法

Vue3.x 父組件自定義事件,子組件給父組件傳值

  1. 子組件獲取父組件的方法
    父組件中聲明自定義方法
<template>
    <div>
        <v-header @send="getChild"></v-header>
    </div>
</template>
<script>
import Header from "./Header"

export default {
    data() {
        return {
            title: "首頁組件"
        }
    },
    methods: {
        getChild(data) {
            console.log(data + "home")
        }
    },
    components: {
        "v-header": Header
    }
}
</script>

<style lang="scss">
</style>
子組件通過this.$emit調用該自定義的方法
<template>
    <div>
        <h2>頭部組件
            --- <button @click="sendParent">執行父組件的自定義事件</button>
        </h2>
    </div>
</template>
<script>
export default {
    // 建議定義所有發出的事件,以便更好地記錄組件應該如何工作
    emits: ["send"],
    data() {
        return {
            msg: "頭部組件"
        }
    },
    methods: {
        sendParent() {
            // this.$emit("send")
            this.$emit("send", this.msg)
        }
    }
}
</script>

<style lang="scss">
h2 {
    text-align: center;
    background: #000;
    height: 44px;
    line-height: 44px;
    color: white;
}
</style>

比較高級的使用方式:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>study</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return { count: 1 }
    },
    template: `
      <counter v-model="count" />
    `
  });

  app.component('counter', {
    props: ['modelValue'],
    methods: {
      handleClick() {
        this.$emit('update:modelValue', this.modelValue + 1);
      }
    },
    template: `
      <div @click="handleClick">{{modelValue}}</div>
    `
  });

  const vm = app.mount('#root');
</script>
</html>

雙向綁定高級部分

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>lesson 19</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return {
        count: 'a',
      }
    },
    template: `
      <counter v-model.uppercase="count" />
    `
  });

  app.component('counter', {
    props: {
      'modelValue': String,
      'modelModifiers': {
        default: ()=> ({})
      }
    },
    methods: {
      handleClick() {
        let newValue = this.modelValue + 'b';
        if(this.modelModifiers.uppercase) {
          newValue = newValue.toUpperCase();
        }
        this.$emit('update:modelValue', newValue);
      },
    },
    template: `
      <div @click="handleClick">{{modelValue}}</div>
    `
  });

  const vm = app.mount('#root');
</script>
</html>

非父子組件傳值

  1. 非父子組件傳值,借用 mitt 三方件
  2. 先安裝 mitt 插件:
    npm install mitt --save
  3. 實例化 mitt
    mitt 的使用:<https://www.npmjs.com/package/mitt
import mitt from 'mitt';

const event = mitt();

export default event;
  1. 組件 A
<template>
    <div>
        <h2>頭部組件
            ----- <button @click="sendLogin">觸發登錄組件里面的事件 實現傳值</button>
        </h2>
    </div>
</template>
<script>
import event from "../model/event"

export default {
    data() {
        return {
            msg: "頭部組件"
        }
    },
    methods: {
        sendLogin() {
            //廣播事件
            event.emit("toLogin", {
                username: "張三",
                age: 20
            })
        }
    }
}
</script>

<style lang="scss">
h2 {
    text-align: center;
    background: #000;
    height: 44px;
    line-height: 44px;
    color: white;
}
</style>
  1. 組件 B
<template>
    <div class="login">
        <input type="text" v-model="username" placeholder="用戶名" />
        <br>
        <input type="text" v-model="password" placeholder="密碼" />
        <br>
        <button @click="doLogin">執行登錄</button>
    </div>
</template>
<script>
import event from "../model/event"
export default {
    emits: {
        submit: ({ username, password }) => {
            if (username !== "" && password !== "") {
                return true
            } else {
                console.log("用戶名密碼不能為空")
                return false
            }
        }
    },
    data() {
        return {
            username: "",
            password: ""
        }
    },
    methods: {
        doLogin() {
            this.$emit("submit", {
                username: this.username,
                password: this.password
            })
        }
    },
    mounted() {
        //監聽廣播
        event.on("toLogin", (data) => {
            console.log(data)
        })
    }
}
</script>

<style lang="scss">
.login {
    padding: 20px;
}
</style>

持續更新中......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM