最後的約定Y 2021-08-15 17:02:15 阅读数:341
vue作為現在前端使用的主流框架之一,組件一直是vue的核心部分。起初,我在學習vue的過程中接觸到了組件之間傳值的功能,但是由於在工作中使用較少,對於這一部分沒有深入的認識,導致在開發過程中遇到了一些問題,通過進一步的學習,我了解到了vue組件傳值的方式以及存在兩類不同的組件傳值方式:同級組件之間的傳值、父子組件之間的傳值
組件作用:用來减少Vue實例(對象)中的代碼量,日後在使用Vue開發過程中,可以根據不同的業務功能將頁面中劃分不同的多個組件,然後多個組件去構建整個頁面的布局,便於日後使用Vue進行開發時頁面管理(可以做到複用組件),方便日後的維護。
全局組件注册給Vue實例對象,定義之後可以在Vue實例的作用範圍內使用該組件
<div id="app">
<!-- 必須給需要綁定的元素,設置選擇器(支持CSS的選擇器,但是我推薦使用ID選擇,容器是唯一) -->
<h2>{{title}}</h2>
<!-- 使用全局注册組件,可以做到複用 -->
<login></login> <login></login> </div>
<!-- 1.先引入框架的支持(VUE文件),推薦比特置body結束標簽的前面(使用的是瀏覽器運行環境
,如果使用NodeJS是另一種引入方式) -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 定義全局組件
Vue.component('login',{
template:'<diu><h2>用戶登陸頁面</h2></diu>' });
let vm = new Vue({
el: '#app',
data: {
title: '組件學習 - 全局組件注册'
}
});
</script>
複制代碼
代碼說明:
局部組件注册將組件注册給對應Vue實例中一個 components屬性 來完成組件注册,這種方式不會對Vue實例造成累加。
<div id="app">
<!-- 必須給需要綁定的元素,設置選擇器(支持CSS的選擇器,但是我推薦使用ID選擇,容器是唯一) -->
<h2>{{title}}</h2>
<login></login>
<register></register>
<user-table></user-table>
</div>
<!-- 第三種方式 -->
<template id="userTemplate">
<diu><h2>用戶列錶頁面</h2></diu>
</template>
<!-- 1.先引入框架的支持(VUE文件),推薦比特置body結束標簽的前面(使用的是瀏覽器運行環境,如果使用NodeJS是另一種引入方式) -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 3.創建VUE對象(ViewModel中間件),數據Model -->
<script>
let reg = {
template: "<diu><h2>用戶注册頁面</h2></diu>",
};
const userTemplate = {
template: "#userTemplate",
};
let vm = new Vue({
el: "#app",
data: {
title: "組件學習 - 局部組件注册",
},
components: {
login: {
//第一種方式:直接定義
template: "<diu><h2>用戶登陸頁面</h2></diu>",
},
register: reg, //第二種方式:定義變量
userTable: userTemplate, //第三種方式:注意我使用了駝峰的方式,脚手架推薦方式
},
});
</script>
複制代碼
beforeCreate:組件開始初始化,僅僅注册組件自己事件和生命周期函數
created:組件已經注入data/methods/computed相關數據方法
beforeMount:將template中指向html編譯Vue模版,此時還沒有完成模版中內容渲染
mounted:將template中html編譯模版進行數據渲染並且將渲染完成的數據再內存中形成虛擬dom替換template指向dom
beforeUpdate:當組件中data數據發生變化時,會觸發beforeUpdate,此時頁面中數據還是原始數據
updated:此時頁面中數據和data屬性一致
beforeDestroy:銷毀VUE實例之前觸發方法
destroy:VUE實例已經徹底銷毀、監聽進制全部消失
作用 props用來給組件傳遞相應靜態數據或者動態數據
在子組件裏定義一個props,即props:[msg],msg可以是對象也可以是基本數據類型
<template>
<div class="parent">
//傳遞的數據 message
<Children :msg="message"></Children>
</div>
</template>
<script>
//引入的組件
import Children from "../components/Children";
export default {
name: "Parent",
components: {
Children,
},
data() {
return {
message: "hello world",
};
},
};
</script>
複制代碼
<template>
<section>父組件傳過來的消息是:{{myMsg}}</section>
</template>
<script>
export default {
name: "Children",
components: {},
//通過props接收到的內容
props: ["msg"],
data() {
return {
//可以通過this拿到傳過來的數據
myMsg: this.msg,
};
},
methods: {},
};
</script>
複制代碼
這裏需要使用自定義事件,在子組件中使用this.$emit(‘myEvent’) 觸發,然後在父組件中使用@myEvent監聽
<template>
<section>
<br />
//聲明點擊事件進行傳遞
<div @click="clickme">click me</div>
</section>
</template>
<script>
export default {
name: "Children",
components: {},
data() {
return {
childNum: 0,
};
},
methods: {
clickme() {
// 通過自定義事件addNum把值傳給父組件
this.$emit("addNum", this.childNum++);
},
},
};
</script>
複制代碼
<template>
<div class="parent">
這裏是計數:{{parentNum}}
//這裏的addNum 是子組件傳遞的時候聲明的時間 也就是子組件 this.$emit("addNum", this.childNum++);
<Children-Com @addNum="getNum"></Children-Com>
</div>
</template>
<script>
import ChildrenCom from "../components/Children";
export default {
name: "Parent",
components: {
ChildrenCom,
},
data() {
return {
parentNum: 0,
};
},
methods: {
// childNum是由子組件傳入的
getNum(childNum) {
this.parentNum = childNum;
},
},
};
</script>
複制代碼
運用自定義事件e m i t的觸發和監聽能力,定義一個公共的事件總線evenBus,通過它作為中間橋梁,我們就可以傳值給任意組件了。而且通過eventBus的使用, 可以加深emit的觸發和監聽能力,定義一個公共的事件eventBus,通過它作為中間橋梁,我們就可以傳值給任意組件了。而且通過eventBus的使用,可以加深emit的理解
import Vue from 'vue'
export default new Vue()
複制代碼
<template>
<section>
<div @click="Children1">push message</div>
<br />
</section>
</template>
<script>
//引用bus組件
import eventBus from "./EventBus";
export default {
name: "Children1",
components: {},
data() {
return {
childNum: 0,
};
},
methods: {
Children1() {
// 通過事件總線發送消息
eventBus.$emit("Children1", this.childNum++);
},
},
};
</script>
複制代碼
<template>
<section>children1傳過來的消息:{{msg}}</section>
</template>
<script>
//引用bus組件
import eventBus from "./EventBus";
export default {
name: "Children2",
components: {},
data() {
return {
msg: "",
};
},
mounted() {
// 通過事件總線監聽消息
eventBus.$on("Children1", (children1Msg) => {
this.msg = children1Msg;
});
},
};
</script>
複制代碼
<template>
<div class="parent">
<Children1></Children1>
<Children2></Children2>
</div>
</template>
<script>
//引入的兩個兄弟組件 路徑組件改變
import Children1 from "../components/Children1";
import Children2 from "../components/Children2";
export default {
name: "Parent",
components: {
Children1,
Children2,
},
data() {
return {};
},
methods: {},
};
</script>
複制代碼
使用問號傳值 A頁面跳轉B頁面時使用 this.$router.push(’/B?name=danseek’)
B頁面可以使用 this.$route.query.name 來獲取A頁面傳過來的值
配置的路由如下
//這個就是router裏面index.js的內容
{
path: '/b/:name',
name: 'b',
component: () => import( '../views/B.vue')
}
複制代碼
<template>
<div class="home">
<div>
<Children :data="num" @fatherNums="shouFun"></Children>
</div>
</div>
</template>
<script>
import { ref } from "vue";
import Children from "../components/children";
export default {
name: "Home",
components: {
Children,
},
setup(props) {
// 父傳子組件
const num = ref(18);
return {
num,
};
},
};
</script>
複制代碼
<template>
<div>
{{ num }}
</div>
</template>
<script>
//需要引用的ref綁定
import { ref } from "vue";
export default {
props: {
data: Number,
},
setup(props, { emit }) {
//接收也是props
const num = ref(props.data);
return {
num,
};
},
};
</script>
複制代碼
<template>
<div class="home">
<div>
<p>{{nums}}</p>
<Children :data="num" @fatherNums="shouFun"></Children>
</div>
</div>
</template>
<script>
import { ref } from "vue";
//引入的組件
import Children from "../components/children";
export default {
name: "Home",
//是通過components屬性來引入的組件
components: {
Children,
},
setup(props) {
const nums = ref(null);
// 父接子
const shouFun = (val) => {
console.log(val);
nums.value = val;
};
return {
nums,
};
},
};
</script>
複制代碼
<template>
<div>
<button @click="fatherNum">子傳父</button>
</div>
</template>
<script>
import { ref } from "@vue/reactivity";
export default {
props: {
data: Number,
},
setup(props, { emit }) {
//通過emit和點擊事件傳遞
const fatherNum = () => {
emit("fatherNums", 666);
};
return {
fatherNum,
};
},
};
</script>
複制代碼
props傳遞數據的優點顯而易見、靈活簡單,可以對props數據進行數據計算、數據監聽等處理,十分靈活方便,但這裏單單只是父子一層。
我們子組件中使用父組件props的時候,如果涉及到一些變量賦值,修改等操作,props被莫名其妙的修改了,連同父組件的數據也被篡改了,這讓我們很疑惑,父組件的props不是不能修改嗎?這裏怎麼變了,
其實在vue中的props能不能改變,這個得分情况。
props如果是基礎數據類型,當改變時,就會拋出錯誤:
當props是引用類型的話,我們修改這個數據的某一個屬性的實話,就可以。
由此我們可以得出結論:子組件雖然不能直接對父組件prop進行重新賦值,但父組件是引用類型的時候,子組件可以修改父組件的props下面的屬性。
這就很尷尬了。如果我們設計的初衷就是父組件數據也能同時被修改,這個結果可以接受,如果不希望父組件的數據有變化是,這就是一個嚴重的邏輯bug。這就是props通訊的風險之一。
版权声明:本文为[最後的約定Y]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/08/20210815170211122Q.html