• v-model 用在组件中


    官方文档:

      使用自定义事件的表单输入组件

    官方也说明了,v-model只不过是一个语法糖而已,真正的实现靠的还是

    1.  v-bind :  绑定响应式数据
    2.  触发 input 事件 并传递数据  (核心和重点)

    大体就是:

       监听原生组件的事件, 当获取到原生组件的值后把值通过调用 $emit('input' ,data) 方法去触发 input事件 
     
    demo:
      父组件代码:
    <template>
      <div class="hello">
           <button @click="ifShow=!ifShow">点击显示</button>
           <show-alert v-model="ifShow"></show-alert>
      </div>
    </template>
    
    <script>
    import showAlert from './showAlert.vue'
    export default {
      name: 'HelloWorld',
      components:{
          showAlert,
      },
      data () {
        return {
                ifShow:false,
        }
      }
    }
    </script>

      子组件代码:

    <template>
        <div id="showAlert" :value="value" v-if="ifValue">
            <div>showAlert 内容</div>
            <button class="close" @click="ifValue=false">关闭</button>
        </div>
    </template>
    
    <script>
        export default{
            props:{
                value:{
                    type:Boolean,
                    default:false,
                }
            },
            data:function(){
                return{
                    ifValue:false,
                }
            },
            watch:{
                value(bool){
                    this.ifValue=bool;
                    console.log('bool='+ bool);
                },
                ifValue(val){
                    /*使用了v-model的组件会自动监听 input 事件, 
                     * 并把这个input事件所携带的值 传递给v-model所绑定的属性,
                     * 这样组件内部的值就给到了父组件了
                     */
                    this.$emit('input',val);//传值给父组件, 让父组件监听到这个变化
                }
            },
        }
    </script>
    
    <style scoped>
        .close{
            background:red;
            color:white;
        }
    </style>

        实现效果:

      点击显示按钮以后:

      前提: this.$emit('input',data);

      点击子组件关闭按钮后:

      如果未加this.$emit('input',data);

      点击子组件关闭按钮后:

      如果未通过$emit把值传到父组件, 则父组件监听不到子组件的变化.

    ====================================================================

    封装一个可复用的弹窗组件

    <!-- 
        弹出窗口组件,
        调用方法:
        父组件import 当前vue文件, 在对应的components中注册即可使用,
        注意:
        需要在父组件给一个boolean的属性 通过v-model的形式关联即可
        其他属性看下方注释,
    
        params(父组件调用 标签属性):
        title-info      弹出框显示文字
        left-button     左边按钮文字
        right-button    右边按钮文字
        left-click      左边按钮点击回调函数
        right-click     右边按钮点击回调函数
    
        中间部分可以从父元素自定义设置通过slot放入
        例子:
        <show-model>
            <p slot="reference">111</p>
        </show-model>
    
        例子:
        <show-model 
            v-model="flag" 
            title-info="优惠码输入错误,请重试"
            left-button="取消"
            right-button="确定"
            @left-click="left_button"
            @right-click="right_button"></show-model>
    
        ****
        watch中增加.
        当弹出窗弹出时,阻止后面页面可以滚动的问题
     -->
    <template>
        <div class="model-wrapper" :value="value" v-if="ifValue">
            <div class="mask" @click="close_click"></div>
            <div class="model-content">
                <p v-if="titleInfo">{{titleInfo}}</p>
                <div class="button-group" v-if="leftButton || rightButton">
                    <div v-if="leftButton" @click="left_click">{{leftButton}}</div>
                    <div v-if="rightButton" @click="right_click">{{rightButton}}</div>
                </div>
            </div>
        </div>
    </template>
    
    <script>
        export default{
            props:{
                value:{
                    type:Boolean,
                    default:false
                },
                titleInfo:{
                    type:String,
                    default:''
                },
                leftButton:{
                    type:String
                },
                rightButton:{
                    type:String
                }
            },
            data:function(){
                return {
                    ifValue:false,
                }
            },
            methods:{
                close_click:function(){
                    this.$emit('close-click');
                },
                left_click:function(){
                    this.$emit('left-click');
                },
                right_click:function(){
                    this.$emit('right-click');
                }
            },
            watch:{
                value(bool){
                    this.ifValue=bool;
                },
                ifValue(val){
                    this.$emit('input',val);
                }
            }
        }
    </script>
    
    <style scoped>
        .model-wrapper{
            width:100%;
            height:100%;
            position:fixed;
            top:0;
            left:0;
            z-index:999;
        }
        .mask{
            width:100%;
            height:100%;
            position:absolute;
            left:0;
            top:0;
            z-index:1;
            background-color:rgba(0,0,0,0.5);
        }
        .model-content{
            width:80%;
            background:white;
            position:absolute;
            top:50%;
            left:50%;
            transform:translate(-50%,-50%);
            z-index:10;
        }
        .button-group{
            margin-top:40px;
            display:flex;
            padding:0 10px 10px;
        }
        .button-group div{
            flex:1;
            height:40px;
            line-height:40px;
            box-sizing:border-box;
            cursor:pointer;
        }
        .button-group div:first-child{
            background:#000;
            color:#fff;
        }
        .button-group div:last-child{
            border:1px solid gray;
        }
    </style>

    在首页调用

        <button @click="showModel">点击显示弹窗</button>
        <show-model v-model="ifShowModel" titleInfo="嘿嘿嘿" leftButton="确定" rightButton="取消" @close-click="close_click" @left-click="left_click" @right-click="right_click"     ></show-model>
        showModel:function(){
              this.ifShowModel=true;
              
          },
          close_click:function(){
              this.ifShowModel=false;
          },
          left_click:function(){
              this.ifShowModel=false;
          },
          right_click:function(){
              this.ifShowModel=false;
          }

  • 相关阅读:
    [JavaScript]继续学习DOM事件模型
    [面试]作答整理一些面试题
    [JavaScript]使用jQuery实现无缝轮播
    [JavaScript]使用CSS + jQuery 实现自动轮播图
    [JavaScript]从DOM到jQuery(2)
    [JavaScript]从DOM到jQuery(1)
    [JavaScript]JavaScript中的函数(2)
    [JavaScript]JavaScript中的函数(1)
    [JavaScript]JavaScript中的Array
    React练习 7 :点击div,显示innerHTML
  • 原文地址:https://www.cnblogs.com/rachelch/p/8944367.html
Copyright © 2020-2023  润新知