项目中要求实现在页面A中请求接口,点击确定键把接口中返回的数据保存到vuex中并渲染到组件内,要求可以对组件内渲染的数据要可以进行操作。
如果在页面上直接用:

<mycheckTip @hidden="cancelCheck" @ensure="sureCheck" :isshow="mycheckTipFlag"></mycheckTip>

注:@hidden=”cancelCheck”是控制组件内的取消操作的,@ensure=”sureCheck”是控制组件内的确定键的操作的,:isshow=”mycheckTipFlag”是控制组件的显示与否的。

用以上代码直接控制组件的话,那么写在组件mounted内的读取保存到vuex内的值并赋值给组件内的变量的话则会出现问题,好像是没有赋值成功,但是其实是因为在加载页面时就已经执行组件的mounted内的操作了,所以在点击页面按钮赋值vuex后,实际上并没有在组件内读取,要想读取的话,可以写在组件的updated内,但是读取vuex内的值,赋值给组件内变量的话是需要进行深拷贝的,直接操作vuex内的数据会报Error: [vuex] Do not mutate vuex store state outside mutation handlers.”的错。
用JSON.stringify()和JSON.parse()方法,但是在项目中这样写直接造成了页面挂掉了,查资料说是因为JSON.stringify()和JSON.parse()方法太慢了,所以这个方法不可行。综上所述还是只能在mounted里面执行,那怎么控制呢?
解决方法:给页面用的这个组件标签加一个 v-if,也就是判断数据是否为空,为空就不渲染,这样就可以解决这个问题了。

改为:

<mycheckTip v-if="mycheckTipFlag" @hidden="cancelCheck" @ensure="sureCheck" :isshow="mycheckTipFlag"></mycheckTip>

文件结构如图:
这里写图片描述

页面onePage:
这里写图片描述
代码:

<template>
    <div class="onepage-wrap">
        <div>
            <h3 @click="goQWE">跳到第二个页面</h3>
            <div @click="getData()">请求接口</div>
            <mycheckTip v-if="mycheckTipFlag" @hidden="cancelCheck" @ensure="sureCheck" :isshow="mycheckTipFlag"></mycheckTip>
            <button @click="zujian()">给子组件进行传参</button>
        </div>
    </div>
</template>

<script>
    import { mapGetters } from 'vuex'
    import store from './../vuex/store.js'
    import { GetLocalMethod } from '../common/HttpService'
    import mycheckTip from '../components/trainscheck'
    import { Toast } from 'mint-ui';
    export default {
        name: 'onePage',
        data () {
            return {
                mycheckTipFlag:false,   //政策校验弹窗
            }
        },
        computed:{
            ...mapGetters([
                'saveOneValue',
                'direction',
                'checkPolicy'
            ])
        },
        components: {
            mycheckTip,
        },
        methods: {
            goQWE () {
                this.$router.push(`/twoPage`);
            },
            savaOneValue(){
                store.commit('UPDATE_SAVEONEVALUE','我是改变后的saveOneValue的值');
            },
            //请求本地数据
            getData(){
                GetLocalMethod('./static/data.json', '', true).then(res => {
                    console.log(res.data);
                    res.data.data.forEach(dt => {
                        dt.checked = false;
                    })
                    store.commit('UPDATE_CHECKPOLICY', res.data);
                    this.mycheckTipFlag = true;

                    console.log(this.mycheckTipFlag)
                });
            },
            //给子组件传参
            zujian(){

            },
            //确定校验选择
            sureCheck(){
                this.mycheckTipFlag = false;
            },
            //取消校验弹窗
            cancelCheck(val){
                this.mycheckTipFlag = false;
            },
        },
        mounted() {

        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
    .onepage-wrap{
        h2{
            color: #8fc31f;
        }
    }
    h1, h2 {
        font-weight: normal;
    }

    ul {
        list-style-type: none;
        padding: 0;
    }

    li {
        display: inline-block;
        margin: 0 10px;
    }

    a {
        color: #42b983;
    }

    h5 {
        font-size: 40px;
    }
</style>

组件trainscheck:
这里写图片描述
代码:

<template>
    <div class="transcheck-wrap" v-show="isshow">
        <section class="content">
            <div class="content-Area">
                <div class="securityTips" v-html="checkData.tipMsg"></div><!--checkDataList   checkMsg-->
            </div>
            <ul class="list-Area">
                <li v-for="item,i in checkData.data" @click="selected(item,i)">
                    <div class="li-left">
                        <div class="getway-btn">
                            <i class="iconfont icon-selectmodel"></i>
                            <i class="iconfont icon-selected" v-show="item.checked"></i>
                        </div>
                    </div>
                    <div class="li-right">
                        {{item.msg}}
                    </div>
                </li>
            </ul>
            <div class="btn-Area">
                <div class="cancelBtn" @click="cancel">取&ensp;消</div>
                <div class="sureBtn" @click="sure">确&ensp;定</div>
            </div>
        </section>

    </div>
</template>
<script>
    import { Tool } from '../common/Tool.js'
    import { mapGetters,mapState } from 'vuex'
    import store from '../vuex/store.js'
    export default {
        name: 'mychecktip',
        data() {
            return {
                checkData:{}
            }
        },
        props: ['msg','isshow'],
        computed: {
            ...mapGetters([
                'checkPolicy'
            ])
        },
        watch:{
            msg(val,old){

            }
        },
        methods:{
            sure(){
                let checkNum = this.checkData.data.filter(dt => {
                    return dt.checked == true;
                })
                if(checkNum.length != 0){
                    store.commit('UPDATE_CHECKPOLICY', this.checkData);
                    this.$emit('ensure', false);
                }else{
                    console.log("请选择原因备注");
                }
            },
            cancel(){
                this.$emit('hidden', false);
            },
            selected(item,i){
                //单选
                this.checkData.data.forEach(dt => {
                    dt.checked = false;
                })
                this.checkData.data[i].checked = true;
                //复选
//              item.checked = !item.checked;

            }
        },
        mounted(){
            console.log(this.checkPolicy);
            this.checkData = JSON.parse(JSON.stringify(this.checkPolicy));
        },
        updated(){
            console.log('updated');
        }
    }
</script>
<style lang="scss" scoped>
    @import '../styles/mixin';
    .transcheck-wrap {
        .content{ @include cont(0); z-index: 10;
            background: #fff;
        }
        .content-Area{
            .securityTips{ padding: 1rem;
                font-size: .8rem;
            }
        }
        .list-Area{
            padding: .5rem 2rem;
            li{ @include fj; font-size: .8rem;
                padding: .4rem 0;
                text-align: left;
                .li-left{ width: 15%;
                    .getway-btn{ position: relative;
                        i{ position: absolute;
                            left: 0;
                            margin-top: -.5rem;
                            font-size: .9rem;
                        }
                        .icon-selected{
                            color: $co37c;
                        }
                        span{
                            padding-left: 1.2rem;
                        }
                    }
                }
                .li-right{
                    @include fx; } } } .btn-Area{ @include fj; padding: .5rem 2rem;
            font-size: .8rem;
            div{ @include fx; margin: .5rem;
                text-align: center;
                color: $cofff;
                line-height: 2rem;
                border-radius: 5px;
            }
            .sureBtn{
                background: $co37c;
            }
            .cancelBtn{
                background: $coccc;
            }
        }
    }
</style>
Logo

前往低代码交流专区

更多推荐