在vue的學習中,一開始我是本身寫組件練手的,在這個過程當中我遇到一個問題:
props:父組件傳遞給子組件參數
(1)props直接在子組件裏直接使用是能夠實時更新的
(2)props若是在created,mounted等聲明或者直接賦值給data的時候,再用data的時候是不能夠實時更新的
(3)內部的data是能夠實時更新的
(4)可是內部不能夠強制去改變父元素傳遞過來的props,這樣是官方不容許的並且是不嚴謹的javascript
那麼,我在寫模態框組件的時候就產生一個很矛盾的問題,若是父級props控制了組件內部的顯示和隱藏,
內部點擊模態框陰影的時候也能夠讓其自動隱藏,我到底去修改什麼值,修改了以後怎麼去改變父組件傳遞過來的props,
給全局一個反饋呢。
在看過文章和本身動手操做後選取了一種方式,將內部的data和props進行關聯,採用vue中v-modal的原理,值發生變化(input事件),
對應的數據也發生相應的改變:
很少說,直接貼代碼:html
子組件:
template:vue
<template > <div :value = "value" v-show = "isShow" > <div :class = "{active: isShow}" class = "modal msg" > <div @click = "onMaskClose" class = "modal-mask" ></div > <div class = "modal-wrapper" > <div :style = "{width: '428px'}" class = "modal-container" > <div class="header">模態框</div> <div class = "body" > <div v-if="!$slots.content" v-html="content"></div> <slot v-else="content" name="content"></slot> </div > <div class = "footer" > <div @click = "onClick" class = "btn" >{{ btnTxt }}</div > </div > </div > </div > </div > </div > </template >
javascript:java
import { mapState, mapActions } from 'vuex' import _ from 'lodash' export default { name: "msg-modal", data () { return { isShow: this.value } }, props: { value: { type: Boolean, default: false }, closeable: { type: Boolean, default: false }, btnTxt: { type: [String, Number], default: '肯定' }, content: { default: '內容' } }, watch: { value (val) { this.isShow = val; }, isShow (val) { this.$emit('input', val); } }, computed: { ...mapState({ allAnchorList: state => state.anchor.list.data }) }, methods: { ...mapActions(['removeAnchor']), onClick () { this.$emit('onClick') }, onMaskClose () { if(!this.closeable) { return } Object.assign(this.$data, this.$options.data()) } } }
less:vuex
.modal { position: fixed; z-index: 800; top: 0; left: 0; width: 100%; height: 100%; display: table; transition: all .3s; background-color: transparent; &.active{ opacity: 1; } .modal-mask { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; background-color: rgba(0, 0, 0, .5); } .modal-wrapper { display: table-cell; vertical-align: middle; .modal-container { width: 300px; margin: 0 auto; border-radius: 2px; //box-shadow: 0 2px 8px rgba(0, 0, 0, .33); transition: all .3s ease; font-family: Helvetica, Arial, sans-serif; .header{ position: relative; backgroud-color: #fff, min-height: 50px; } .modal-body { margin: 20px 0; } .footer { padding-bottom: 26px; overflow: hidden; border-bottom-left-radius: 4px !important; border-bottom-right-radius: 4px !important; background-color: #fff; .btn { height: 36px; line-height: 36px; width: 230px; margin: 0 auto; color: #fff; font-size: 14px; text-align: center; cursor: pointer; user-select: none; background-color: #2859ED; border-radius: 4px; } } } } }
父組件的引用:
template:app
<template > <div> <MsgModal v-model = "show" content = "這是一段內容" @onClick = "handleClick" /> </div> </template > javascript: <script > import MsgModal from './components/Modal/MsgModel' export default { name: 'App', data(){ return { show: false } }, components: { MsgModal }, methods: { handleClick () { console.log('點擊模態框肯定按鈕') } } } </script >
樣式隨便寫的,
主要就是用vue的v-model原理,將值與被傳遞的props實現雙向綁定,
須要注意的是在組件mounted的時候須要對組件初始化中的傳遞的props賦值給綁定的v-model的value
本身也是才摸索vue全家桶階段,纔沒作兩個項目
有不足的地方請你們見諒和指導
歡迎你們討論less