vue基础语法4

组件

  1. 复用
  2. 隔离(拆分)

全局组件

可以在整项目中不注册直接使用
定义 :Vue.component(名称,参数对象)

<script>
    Vue.component("Count",{
        template:`<div><button>按钮</button></div>`
    })
    new Vue({
        el:"#app",
        data:{}
    })
</script>

使用

 <div id="app">
    <Count></Count>
 </div>

在这里插入图片描述

局部组件

谁注册谁使用

  • 定义:var CounterItem={template:"",methods,…}
  • 注册:components:{CounterItem}
  • 使用:<counter-item ></counter-item><Counter-Item></Counter-Item>
 var CounterItem={
        template:`<div><button @dblclick="say()" @click="num++">{{num}}</button></div>`,
        data(){return {num:1}},
        props:["count"],
        methods:{
            say(){alert("666")}
        },
    }
    new Vue({
        el:"#app",
        data:{},
        components:{CounterItem}
    })
</script>
   <div id="app">
        <counter-item ></counter-item>
        <Counter-Item></Counter-Item> 
    </div>

数据传递 父传子
传入数据
<counter-item :count="2" ></counter-item>
接收数据
props:["count"]props:{type:Number,default:1}
props验证默认值:

  • props:{type:Number,default:1}
  • type:Number String Object Array Boolean

组件的单向数据流

  • vue提倡单向数据流 :父传递的组件的数据应该是只读的
  • 想修改父组件传递过来的数据(以父组件的传递过来的数据作为当前组件data初始值)

传参初始化

props:["count"],
created(){this.num=this.count}  //可以修改num值
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="app">
        <counter-item v-for="(item,index) in list" :key="index" :count="item"></counter-item>
            <!-- 01参数  传入属性给组件 -->
            <hr/>
        <Counter-Item></Counter-Item>
    </div>
    
</body>
<script>
    var CounterItem={
        template:`<div><button @dblclick="say()" @click="num++">{{num}}</button></div>`,
        data(){return {num:1}},
        // props:["count"],
        props:{"count":{type:Number,default:20}},
    //    通过props 接收数据
        methods:{
            say(){alert("666")}
        },
        create(){
            this.num=this.count
            //count传过来的数据是num的初始值
        }
    }
    new Vue({
        el:"#app",
        data:{
            list:[1,2,3,4,5]
        },
        components:{CounterItem}
    })
</script>
</html>

子向父传参

this.$emit("事件名",this.num)
//向父组件发送checknum事件,值为this.num
<Step @checknum="nuber($event)"></Step>接收数据
小案例—步进器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
    <style>
        .step{display: inline-block;}
        .step input[type="text"]{width: 30px; text-align: center;}
    </style>
</head>
<body>
    <div id="app">
      <Step></Step>
      <Step :min="30" :max="100" :step="10" :count="40" @checknum="nuber($event)"></Step>
      <h1 v-if="number">{{number}}</h1>
    </div> 
</body>
<script>
   var Step={
       template:`<div class="step">
       <button :disabled="num<=min" @click="cal(-1)">-</button>
       <input type="text" v-model="num" @input="check()" >
       <button :disabled="num>=max" @click="cal(1)">+</button></div>`,
       data(){return{num:1}},
       props:{
           "count":{type:Number,default:1},
           "min":{type:Number,default:1},
           "max":{type:Number,default:999},
           "step":{type:Number,default:1},
       },
       created(){
           this.num=this.count
       },
       methods:{
        check(){
            if(this.num<=this.min){this.num=this.min}
            if(this.num>=this.max){this.num=this.max}
            this.$emit("checknum",this.num)
            //向父组件发送checknum事件,值为this.num
        },
        cal(type){
            this.num+=this.step*type;
            this.check();
        }

       }
   }
    new Vue({
        el:"#app",
        data:{
            number:null
        },
        components:{Step},
        methods:{
            nuber(e){
                this.number=e
            }
        }
    })
</script>
</html>

插槽

定义:
<slot></slot>
使用:
<组件><p>嵌入内容</p><组件>
例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
    <style>
        .Parent{border: 1px solid #eee;margin: 10px; padding: 10px;}
    </style>
</head>
<body>
    <div id="app">
      <Parent>
            <h1>我是嵌套内容1</h1>
            <Parent>
                <p>我是嵌套内容2</p>
                <Parent>
                    <p>我是嵌套内容3</p>
                </Parent>
            </Parent>  
      </Parent>
    </div>
    
</body>
<script>
   var Parent={
       template:` <div class="Parent"><p>parent组件</p><slot></slot></div>`
   }
    new Vue({
        el:"#app",
        data:{
           
        },
        components:{Parent}
       
    })
</script>
</html>

具名插槽

定义:
<slot name="插槽名"></slot>
使用:
<div slot="插槽名"><p>我是标题</p></div>

小案例–弹出框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
    <style>
      *{ margin: 0;padding: 0;}
			body{ padding: 50px;}
			.modal{
				background-color: rgba(0,0,0,.3);
				position: absolute;
				z-index: 10000;
				height: 100vh;
				width: 100%;
				left:0;
				top: 0;
				display: flex;
				justify-content: center;
				align-items: center;
			}
			.modal-content{
				width: 400px;
				height: 300px;
				background-color: #fff;
				display: flex;
				flex-direction: column;
			}
			.modal-title{
				line-height: 44px;
				background-color: #fafafa;
				display: flex;
				justify-content: space-between;
				padding-left: 15px;
			}
			.close{ width: 44px; text-align: center; color:coral;cursor: pointer;}
			.modal-foot{ height: 44px; padding: 0 15px; text-align: right;}
			.modal-body{flex:1}
    </style>
</head>
<body>
    <div id="app">
        <button @click="flag=true">弹出</button>
       <Model title="你笑起来真好看" :visible="flag" @close="flag=$event">
        <div>
            <p>用户名:<input type="text"></p>
            <p>密码:<input type="text"></p>
        </div>
        <div  slot="foot"><button @click="flag=false">确定</button><button @click="flag=false">取消</button></div>
        <div slot="title"><p>我是标题</p></div>
       </Model>
       
    </div>
   
</body>
<script>
   var Model={
       template:` 
       <div class="modal" v-if="visible">
            <div class="modal-content">
                <div class="modal-title">
                    <div class="title" v-if="$slots.title">
                        <slot name="title"></slot>
                    </div>
                    <div class="title" v-else>{{title}}</div>
                    <div class="close" @click="$emit('close',false)">x</div>
                </div>
                <div class="modal-body">
                    <slot></slot>
                </div>
               
                <div class="modal-foot" v-if="$slots.foot">
                    <slot name="foot"></slot>
                </div>
                <div class="modal-foot" v-else>
                <button @click="$emit('close',false)">确定</button>
                </div>
            </div>
        </div>
       `,
       props:{
           title:{type:String,default:""},
           visible:{type:Boolean,default:false},
       }
   }
    new Vue({
        el:"#app",
        data:{
            flag:false
        },
        components:{Model} 
    })
</script>
</html>

$slots.foot:
所有插槽列表下名字为foot的插槽
$emit 向父组件传递信息
属性.sync修饰符

  1. :visible.sync=“flag”
  2. 组件中:<div v-if="visible"><button @click="$emit('update:visible',false)"></button></div>
  3. props:{visible:{type:Boolean,default:false}}

组价传参-复用-小案例-列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="app">
       <Inp @adds="list.unshift({done:false,title:$event})"></Inp>
       <List :list="list" @del="delHd($event)"></List> 
    </div>
  
</body>
<script>
   var Inp={
       template:` 
       <div>
            <input type="text" v-model="temp"  @keyup.enter="enterHd()">
       </div>`,
       data(){return{
        temp:"",
    }},
    methods:{
        enterHd(){
         
            this.$emit("adds",this.temp);
            this.temp=''
        }
    },
   }
   var Item={
    template:` 
    <div>
        <input type="checkbox" :checked="item.done">
        {{item.title}}
        <button @click="$emit('del',item)">删除</button>
    </div>`,
    props:{item:{type:Object,defaule:{}}}
   }
   var List={
    template:` <div>
                <Item v-for="item in list" 
                :key="item.title" 
                :item="item"
                @del="$emit('del',$event)"
                ></Item>
    
                </div>`,
    props:{list:{type:Array,default:[]}},
    components:{Item}
   }
    new Vue({
        el:"#app",
        data:{
          list:[
              {done:true,title:"吃饭"},
              {done:true,title:"睡觉"},
              {done:true,title:"打豆豆"},
          ]
        },
        methods:{
            delHd(item){
                var ind=this.list.indexOf(item) 
                this.list.splice(ind,1)
            }
        },
        components:{Inp,List}
       
    })
</script>
</html>

猜你喜欢

转载自blog.csdn.net/hhhhhhhhhtr/article/details/106850385