1.父组件格式
传入:dialog-visible=“xxx”
<updatePassword :dialog-visible="dialogVisible" @confirm="confirm" @cancel="cancel" />
2.子组件格式
重要的是script标签,从props接受:dialogVisible的值
export default {
props: {
dialogVisible: {
type: Boolean,
default: false
}
3.父组件修改props
直接修改 :dialog-visible=“dialogVisible” 的值
4.子组件修改props
子组件不能直接修改props
如果子组件直接修改父组件中的参数,这个参数多个子组件引用,就造成数据不正常
所以,子组件要修改props,子组件就得使用$emit通知父组件进行修改
//子组件这样写,父组件用@confirm
this.$emit('confirm', this.form)
//父组件
confirm(form) {
//xxx逻辑
}
5.完整代码
1.子组件
<template>
<div>
<el-dialog :visible.sync="dialogVisible" title="修改密码" width="30%" :close-on-click-modal="false">
<el-form ref="passwordForm" :model="form" :rules="loginRules" label-width="120px" label-position="left">
<el-form-item label="新密码" prop="password">
<el-input v-model="form.password" placeholder="请输入新密码" />
</el-form-item>
<el-form-item label="确认新密码" prop="password2">
<el-input v-model="form.password2" placeholder="请再次输入新密码" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="danger" @click="cancel">取 消</el-button>
<el-button type="primary" @click="confirm">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'Index',
props: {
dialogVisible: {
type: Boolean,
default: false
}
},
data() {
const validatePassword = (rule, value, callback) => {
if (value.length < 5) {
callback(new Error('密码不能小于5位'))
} else {
callback()
}
}
const validatePassword2 = (rule, value, callback) => {
if (value !== this.form.password) {
callback(new Error('新密码与旧密码不相同'))
} else {
callback()
}
}
return {
loginRules: {
password: [{ required: true, trigger: 'blur', validator: validatePassword }],
password2: [{ required: true, trigger: 'blur', validator: validatePassword2 }]
},
form: {
password2: '',
password: ''
},
routes: [],
rolesList: []
}
},
methods: {
confirm() {
this.$refs['passwordForm'].validate(valid => {
if (valid) {
this.$emit('confirm', this.form)
} else {
return false
}
})
},
cancel(param) {
this.$emit('cancel', param)
}
}
}
</script>
<style scoped>
</style>
2.父组件
<template>
<div class="navbar">
<hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<breadcrumb class="breadcrumb-container" />
<updatePassword :dialog-visible="dialogVisible" @confirm="confirm" @cancel="cancel" />
<div class="right-menu">
<el-dropdown class="avatar-container" trigger="click">
<div class="avatar-wrapper">
<img src="@/assets/admin.jpg" class="user-avatar">
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown" class="user-dropdown">
<router-link to="/welcome">
<el-dropdown-item>
首 页
</el-dropdown-item>
</router-link>
<el-dropdown-item divided @click.native="showUpdatePassword">
<span style="display:block;">修改密码</span>
</el-dropdown-item>
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">退 出</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger'
import updatePassword from '@/components/updatePassword'
import { updatePassApi } from '@/api/login'
export default {
components: {
Breadcrumb,
Hamburger,
updatePassword
},
data() {
return {
dialogVisible: undefined
}
},
computed: {
...mapGetters([
'sidebar',
'avatar'
])
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},
async logout() {
await this.$store.dispatch('user/logout')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
},
showUpdatePassword() {
this.dialogVisible = true
},
cancel() {
this.dialogVisible = false
},
confirm(form) {
updatePassApi(form).then(() => {
this.$message.success('修改密码成功')
this.dialogVisible = false
})
}
}
}
</scipt>