vue基础知识

vue基本语法

插值操作

<-- Mustache语法 -->
<p>{{message}}</p>
<p>{{message*2}}</p>
<p>{{firstName}}{{lastName}}</p>

vue指令

v-once

该指令表示元素和组件只渲染一次,不会随着数据的改变而改变

<div id="app">
    <h2 v-once>{{message}}</h2>
</div>
<script>
	let vm= new Vue({
        el:"#app",
        data:{
            message:"鸟飞"
        }
    })
</script>

v-html

将插值的内容(字符串)按照html标签来进行解析

<div id="app">
    <h2>{{link}}</h2> <!-- 没有加v-once直接把link当作普通字符串来渲染 -->
    <h2 v-html>{{link}}</h2>  <!-- 将link渲染成一个a标签 -->
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            link:"<a href='http://www.baidu.com'>百度一下</a>"
        }
    })
</script>

v-text

和Mushtache比较,都用于进行数据显示

<div id="app">
    <h2>{{message}}</h2>
    <h2 v-text="message"></h2>  <!-- 两种方式显示的效果一样 -->
</div>
<script>
	let vm = new Vue({
        el:"app",
        data:{
            message:"鸟飞"
        }
    })
</script>

v-pre

用于跳过这个元素和它子元素的编译过程,用于显示原本的Mushtache语法

<div id="app">
    <h2>{{message}}</h2> <!-- 鸟飞 -->
    <h2 v-pre>{{message}}</h2> <!-- {{message}} -->
</div>
<script>
	let vm = new Vue({
        data:{
            message:"鸟飞"
        }
    })
</script>

v-cloak

应用场景:用于在VUE还没有实例化完成时将为渲染的元素隐藏

<style>
    [v-cloak]{
        diaplay:"none"
    }    
</style>
<div id="app">
    <h1 v-cloak>{{message}}</h1>    
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            message:"鸟飞"
        }
    })
</script>

v-bind

用于动态绑定属性 如:a标签的href和img标签的src

v-bind基础

<div id="app">
    <a v-bind:href="link">百度一下</a>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            link:"http://www.baidu.com"
        }
    })
</script>

v-bind语法糖

<div id="app">
    <a :href="link"></a>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            link:"http://www.baidu.com"
        }
    })
</script>

v-bind绑定class

对象语法

在vue中可以将一个对象绑定在class上,对象中的key的属性是true就将key的字面量当作class的类名绑定在标签的class上,false则不绑定

<div id="app">
    <div v-bind:class="{class1:classq , class2:class2 , class3:class3 , class4:class4}"></div>
    <!-- div最后被渲染成 <div class="class2 class3"></div> -->
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            showClass:{
                class1:false,
                class2:true,
                class3:true,
                class4:false
            }
        }
    })
</script>
数组语法

v-bind绑定style

和绑定class的方式差不多,注意一些属性建议使用驼峰标识

对象语法
数组语法

vue配置选项

计算属性

计算属性的基本使用

主要用于对元数据进行改造输出,包括:格式化数据(价格,日期)、大写转小写、排序、添加符号

<div id="app">
    <span>{{newPrice}}</span>  <!-- 显示 ¥:100元 -->
    <span>{{newCount}}</span>  <!-- 显示 件数:10件 -->
</div>
<script>
	let vm = new Vue({
        el:"app",
        data:{
            price:100,
            count:10,
        },
        computed:{
            newPrice(){
                return "¥:"+this.price+"元";
            },
            newCount:function(){//两种方式写的计算属性都是可以的,一种是对象增强写法
                return "件数:"+this.count+"件";
            }
        }
    })
</script>

计算属性的getter和setter

计算属性都包含get和set一般只用get方法,所以可以省略set属性。因为计算属性是属性,所以调用的时候不用加括号

<div id="app">
    <h2>{{fillName}}</h2>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            firstName:"鸟",
            lastName:"飞",
        },
        computed:{
            fUllName:{
                get(){
                    console.log("我调用了fUllName的get");
                    return this.firstName+this.lastName;
                },
                set(value){
                    console.log("我调用了fullName的set========"+value);
                    this.firstName=value[0];                    
                    value.shift();
                    this.lastName=value;
                }
            }
        }
    })
</script>

计算属性的缓存

methods和computed虽然都能实现其数据格式的功能,但是在机制上有差异,计算属性只会调用一次,而方法会调用很多次

<div id="app">
    <span>{{fullName}}</span>
    <span>{{fullName}}</span>
    <span>{{fullName}}</span>
    <span>{{getFullName}}</span>
    <span>{{getFullName}}</span>
    <span>{{getFullName}}</span>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            firstName:"鸟",
            lastName:"飞"
        },
        computed:{
            fullName(){
                console.log("计算属性被调用");
                return this.firstName+this.lastName;
            }
        },
        methods:{
            getFullName:function (){
                console.log("方法被调用");
                return this.firstName+this.lastName;
            }
        }
    })
</script>

v-on事件监听

v-on基础

用于绑定时间监听,处理前端的用户交互。比如点击、拖拽、键盘操作

<div id="app">
    <button @click="btnClick">按钮</button>
    <button v-on:click="btnClick()">按钮</button>
    <button v-on:click="counter++"></button>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            counter:0,
        },
        methods:{
            btnClick:function(){
                this.counter++;
            }
        }
    })
</script>

v-on参数问题

  • 如果不需要传入参数,方法后面的()可以不写
  • 如果方法里面有参数,但是调用方法没传参数,默认将event对象传给参数
  • 如果方法需要参数,同时也需要event时,可通过$event传入事件
<div id="app">
    <button v-bind:click="btnClick">按钮</button>
    <button @click="btnClick">按钮</button>
    <button v-bind:click="readCount(count,$event)">按钮</button>
    <button @click="addCount">按钮</button>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            count:0,
        },
        methods:{
            btnClick:function(event){
                console.log(event);
            },
            readCount:function(count,event){
                console.log(event);
                console.log(count)
            },
            addCount(){
                this.count++;
            }
        }
    })
</script>

v-on修饰符

在某些情况下,我们拿到event的目的可能是进行一些事情处理,Vue提供了修饰符来帮助我们方便的处理一些事情

<div id="app">
    <div v-on:click="addCount">
        <!-- 停止事件冒泡 -->
        <button v-on:click.stop="addCount">按钮</button>
    </div>
    <!-- 阻止默认行为 -->
    <button @click.prevent="addCount">按钮</button>
    <!-- 阻止默认行为,没有表达式 -->
    <form @submit.prevent></form>
    <!-- 串联修饰符 -->
    <button v-bind:click.once.stop.prevent="addCount">按钮</button>
    <!-- 键修饰符,键别名 -->
    <input @keyup.enter="addCount">
    <!-- 键修饰符,键代码 -->
    <input @keyup.13="addCount">
    <!-- 点击回调只触发一次 -->
    <button @click.once="addCount">按钮</button>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            message:"石鹏飞",
            count:1,
        },
        methods:{
            addCount(){
                console.log(this.count);
                this.count++;                
            }
        }
    })
</script>

条件判断

v-if v-else-if v-else

v-if后面的条件为false,对应的元素以及子元素不会渲染。也就是根本不会有对应的标签出现在DOM中

<div id="app">
    <div v-if="score>90">成绩优秀</div>
    <div v-else-if="score>80">成绩良好</div>
    <div v-else-if="score>60">成绩及格</div>
    <div v-else>成绩不合格</div>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            score:99,
        }
    })
</script>

v-if的元素复用问题

现象:当下面的代码将input中的key属性去掉的时候,在useuname-input的输入框输入的值点击切换之后会在useremail-input的输入框中出出现。

原因:因为Vue在进行DOM渲染时出于性能的考虑,会尽可能地复用已存在地元素,而不是重新创建新的元素。

解决方案:如果我们不希望Vue出现类似的重复利用的问题,可以给input添加 key 。

<div id="#app">
	<span v-if="username">
    	<lable>用户账号:</lable>
        <input placeholder="用户账号" key="username-input" key="username">
    </span>
    <span v-else>
    	<lable>用户邮箱:</lable>
        <input placeholder="用户邮箱" key="useremail-input" key="useremail">
    </span>
    <button @click="handleToggle">切换类型</button>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            username:true
        },
        methods:{
            handleToggle(){
                this.username=!this.username;
            }
        }
    })
</script>

v-if和v-show

v-if和v-show都是决定元素是否进行渲染,但是决定的方式不是很相同。

  • v-if条件为false时,压根不会有元素出现在DOM上
  • v-show条件为false时,仅仅将元素的display属性设置为none

所以当元素切换很频繁的时候使用 v-show 切换的频率很少的时候使用 v-if

<div id="app">
    <h2 v-if="isShow">我是v-if<h2>
    <h2 v-show="idShow">我是v-show</h2>
    <button @clack="change">显示隐藏</button>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            isShow:true,
        },
        methods:{
            change:function(){
                this.isShow=!this.isShow;
            }
        }
    })
</script>

循环遍历

v-for遍历数组

  • v-for="item in movies"
    • 依次从movies中取出item,并且在内容中我们可以使用Mustache语法,来使用item
  • v-for="(item , value) in movies"
    • 其中的index表示取出的item在movies数组上的索引值
<div id="app">
	<ul>
        <li v-for="item in movies">{{item}}</li>
        <li>------分割线------</li>
        <li v-for="(value , index) in movies">{{index}}-{{value}}</li>
    </ul>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            movies:["大江大河","盗梦空间","刀锋1937","谁的青春不迷茫"],
        }
    })
</script>

v-for遍历对象

<div id="app">
	<ul>
        <li v-for="(value , key , index) in personInfo">{{index+1}}-{{key}}-{{value}}</li>
    </ul>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            personInfo:{
                name:"鸟飞",
                height:188,
                weight:130,
                age:18,
            }
        }
    })
</script>
<!-- 显示
1-name-鸟飞
2-height-188
3-weight-130
4-age-18
-->

检测数组更新

在Vue中直接用数组索引对元素进行更改,(如:value[0] = 1 )是不能被Vue框架检测到并及时更新DOM(不能触发视图更新)。

<div id="app">
    <ul>
    	<li v-for="item in nums">{{item}}</li>
    </ul>
    <button @click="btnclick">点击</button>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            nums:["wo","xian","zai","hao","fan"],
        },
        methods:{
            btnclick:function(){
                this.nums[2]="鸟飞";
            }
        }
    })
</script>

能触发视图更新的函数

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sore()
  • reverse()

数据绑定

v-model原理

  • v-bind 绑定一个value值
  • v-on指令给当前元素绑定input事件
<div id="app">
    <input type="text" v-model="message"><br>
    <!-- v-model原理 -->
    <input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
    <h2>{{message}}</h2>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            message:"你好!鸟飞"
        }
    })
</script>

v-model​ : radio

<div id="app">
    <label for="lanqiu">
        <input type="radio" v-model="qiu" name="运动" value="篮球" id="lanqiu">篮球
    </label>
    <label for="zuqiu">
    	<input type="radio" v-model="qiu" name="运动" value="足球" id="zuqiu">足球
    </label>
    <label for="yumaoqiu">
    	<input type="radio" v-model="qiu" name="运动" value="羽毛球" id="yumaoqiu">羽毛球
    </label>
    <h2>你选择的是:{{qiu}}</h2>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            qiu:"篮球"
        }
    })
</script>

v-model:checkbox

单个复选框

<div id="app">
    <label for="show"> <input type="checkbox" v-model="isShow" id="show">是否选择 </label>
    <div>
        <span v-if="isShow">是</span>
        <span v-else>否</span>
    </div>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            isShow:false,
        }
    })
</script>

多个复选框

<div id="app">
    <label for="lanqiu">
    	<input type="checkbox" value="篮球" v-model="selects" id="lanqiu">篮球        
    </label>
    <label for="zuqiu">
    	<input type="checkbox" value="足球" v-model="selects" id="zuqiu">足球
    </label>
    <label for="yumaoqiu">
        <input type="checkbox" value="羽毛球" v-model="selects" id="yumaoqiu">羽毛球
    </label>
    <div>
        <div>
        	你选择的是
        </div>
        <ul>
            <li v-for="item in selects">{{item}}</li>
        </ul>
    </div>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            selects:[],
        }
    })
</script>

v-model:select

select单选

<div id="app">
    <select v-model="select">
        <option value="篮球">篮球</option>
        <option value="足球">足球</option>
        <option value="羽毛球">羽毛球</option>
        <option value="跑步">跑步</option>
    </select>
    <h3>你的选择是:{{select}}</h3>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            select:"篮球"
        }
    })
</script>

select多选

<div id="app">
    <select multiple v-model="selects">
    	<option value="篮球">篮球</option>
        <option value="足球">足球</option>
        <option value="羽毛球">羽毛球</option>
        <option value="跑步">跑步</option>
    </select>
    <h2>你选择的是:{{selects}}</h2>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            selects:[],
        }
    })
</script>

v-model修饰符

lazy:只在input失去焦点或者按回车键的时候才会更新数据

<div id="app">
	<input type="text" v-model.lazy="message">
    <h2>{{message}}</h2>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            message:"鸟飞"
        }
    })
</script>

number:在默认情况下,输入框默认无论我们输入的是数字还是字母,都会被当作字符串类型来处理,加上number可以让输入框的内容自动转成数字类型

<div id="app">
    <input type="text" v-model="number">
    <h2>number:{{typeof number}}----{{number}}</h2>
    <input type="text" v-model.number="num">
    <h2>num:{{typeof num}}-----{{num}}</h2>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            number:0,
            num:0,
        }
    })
</script>

trim:去除输入内容首尾的空格

<div id="app">
	<input type="text" v-model="text1">
    <h2>{{text1}}</h2>
    <input type="text" v-model.trim="text2">
    <h2>{{text2}}</h2>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            text1:"你好鸟飞",
            text2:"你好鸟飞"
        }
    })
</script>

vue组件化开发

注册组件的基本步骤

组件的基本用法

  1. 创建组件构造器
  2. 调用Vue.component()方法
  3. 在Vue实例的作用范围内使用组件
<div id="app">
    <!-- 3.使用组件 -->
    <my-cpn></my-cpn>
	<my-cpn></my-cpn>
</div>
<script>
	//1.创建组件构造器
    const mycomponent = Vue.extend({
        template:`
		<h2>我是标题</h2>
		<p>我是组件的内容,我叫鸟飞,大家好啊</p>
		`
    })
    //2.注册组件,并定义组件标签的名称
    Vue.component("my-cpn",mycomponent);
    let vm = new Vue{
        el:"#app",
        data:{
            message:"鸟飞"
        }
    }
</script>

全局组件和局部组件

通过上一个案列演示,通过调用Vue.compontnt()注册组件时,注册的是全局组件。可以在任意的Vue实例下使用。如果我们的组件时挂在在一个Vue实例上,那么这个组件就是局部组件。

局部组件的创建方法

<div id="app">
    <!-- 在Vue实例作用范围使用组件 -->
    <my-cpn></my-cpn>
    <my-cpn></my-cpn>
</div>
<script>
    // 1.创建组件构造器
	const mycomponent=Vue.extend({
        template:`
		<div>
			<h2>我是组件的标题</h2>
			<p>我是组件的内容,哈哈哈哈哈哈哈</p>
    	</div>`
    });
    let vm = new Vue({
        el:"#app",
        components:{// 将组件构造器放在实例中
            "my-cpn":mycompontnt,
        }
    })
</script>

父组件和子组件

组件和组件之间存在着层级关系,其中最终要的一种关系就是父子组件之间的关系

<div id="app">
    <cpn></cpn>
</div>
<script>
	// 1.创建一个子组件
    const child = Vue.extend({
        template:`
			<div>我是子组件的内容,我是child<div>`
    });
    // 2.创建父组件
    const parent = Vue.extend({
        template:`
		<div>
			<h2>我是父组件的标题</h2>
			<p>我是父组件的内容,我是parent</p>
			<child-cpn></child-cpn>
    	</div>`,
        components:{
            "child-cpn":child
        }
    });
    let vm = new Vue({
        el:"#app",
        components:{
            "cpn":parent,
        }
    })
</script>

注册组件的语法糖

注册全局组件语法糖

<div id="app">
    <cpn></cpn>
    <cpn></cpn>
</div>
<script>
	Vue.component("cpn",{
        template:`
	<div>
    	<h2>我是组件的标题</h2>
		<p>我是组件的内容,今天学了注册组件的语法糖学法,好开心</p>
    </div>
`
    })
    let vm = new Vue({
        el:"#app"
    })
</script>

注册局部组件语法糖写法

<div id="app">
    <cpn></cpn>
    <cpn></cpn>
</div>
<script>
	let vm = new Vue({
        el:"#app",
        components:{
            "cpn":{
                template:`
				<div>
					<h2>我是组件标题</h2>
					<p>我是组件的内容,今天学了组建的的语法糖写法,好开心啊</p>
    			</div>
				`
            }
        }
    })
</script>

Vue模板分离写法

<div id="app">
    <cpn></cpn>
    <cpn></cpn>
</div>
<template id="cpn">
    <div>
        <h2>我是组件的标题</h2>
        <p>我是组件的内容,哈哈哈哈</p>
    </div>
</template>
<script>
	let vm = new Vue({
        el:"#app",
        components:{
            "cpn":{
                templete:"#cpn"
            }
        }
    })
</script>

父子组件的通信

首先,每个Vue实例(组件或者是root)都有自己的data用于存放自己的数据,每个实例之间的值是不能直接访问的,需要通过对应的方法才能进行父子组件之间的数据传递。

父组件向子组件传递数据

父组件向子组件传值的数组语法

<div id="app">
    <!-- 3.在组件中通过使用对象的时候将父组件中的data值传给子组件的props -->
	<child-cpn v-bind:message="message"></child-cpn>
    <child-cpn :message="message"></child-cpn>
</div>
<template id="child-cpn">
    <div>
    	<h2>{{message}}</h2>
    </div>
</template>
<script>
	let vm = new Vue({
        el:"#app",
        // 1.Vue实例中的data
        data:{
            message:"大家好,我叫鸟飞",
        },
        components:{
            "child-cpn":{
                template:"#child-cpn",
                // 2.子组件中的props
                props:["message"],
            }
        }
    })
</script>

父组件向子组件传值的对象语法

props属性中的值只能通过父组件来改变

<div id="app">
   <child-cpn v-bind:message="message" :hobbys="hobbys"></child-cpn>
</div>
<template id="child-cpn">
   <div>
       <h2>{{message}}</h2>
       <p>我的情趣爱好是</p>
       <ul>
           <li v-for="item in hobbys">{{item}}</li>
       </ul>
   </div>
</template>
<script>
   let vm = new Vue({
       el:"#app",
       data:{
           message:"大家好,我叫鸟飞",
           hobbys:["篮球","跑步","喝酒","王者荣耀"],
       },
       components:{
   		"child-cpn":{
            	template:"#child-cpn",
                props:{
                	message:String,
                    hobbys:{
                        default:["王者荣耀"]
                    }
                }
            }                 
       }
   })
</script>

子组件向父组件传递数据

子组件向父组件传递数据是通过自定义事件 $emit()来讲数据传递到父组件

<div id="app">
	<child-cpn v-on:add="change" v-on:jian="change"></child-cpn>
</div>
<template id="child-cpn">
	<div>
        <h2>{{count}}</h2>
        <button v-on:click="add()">+</button>
        <button @click="jian()">-</button>
    </div>
</template>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            count:0,
        },
        methods:{
            change:function(value){
                this.count = parseInt(value);
            }
        },
        components:{
            "child-cpn":{
                template:"#child-cpn",
                data:function(){
                    return{
                        count:0
                    }
                },
                methods:{
                    add:function(){
                        this.count++;
                        this.$emit("add",this.count)
                    },
                    jian:function(){
                        this.count--;
                        this.$emit("jian",this.count)
                    }
                }
            }
        }
    })
</script>

父子组件的访问方式

有时候我们需要父组件直接访问子组件,子组件 直接访问父组件,或者子组件直接访问跟组件。就需要用到父子组件的访问方式。

父组件访问子组件:使用$children 或 $refs

<!-- $children的使用 -->
<!-- $children只能遍历子组件,并不能遍历子组件的子组件 -->
<div id="app">
    <child-cpn></child-cpn>
    <button @click="showChild()">显示子组件</button>
</div>
<template id="child-cpn">
	<div>
        <h2>{{message}}</h2>
    </div>
</template>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            message:"大家好,我叫鸟飞"
        },
        methods:{
            showChild(){
                console.log(this.$children)
            }
        },
        components:{
            "child-cpn":{
                template:"#child-cpn",
                data:function(){
                    return{
                        message:"我是子组件"
                    }
                }
            }            
        }
    })
</script>

$children的缺陷

  • 通过$children来访问子组件时,是一个数组类型,访问其子组件必须通过索引值
  • 但是当子组件过多,我们需要拿其中一个时,往往不能确定他的索引值,甚至还可能发生变化。
  • 所以可以通过$refs来取特定的组件
<!-- $refs的使用  -->
<div id="app">
    <child-cpn ref="aaa"></child-cpn>
    <button @click="showChild()">显示子组件</button>
</div>
<template id="child-cpn">
	<div>
        <h2>{{message}}</h2>
    </div>
</template>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            message:"大家好,我是鸟飞"
        },
        methods:{
            showChild:function(){
                console.log(this.$refs.aaa);
                console.log(this.$refs);
            }
        },
        components:{
            "child-cpn":{
                template:"#child-cpn",
                data:function(){
                    return{
                        message:"我是子组件"
                    }
                }
            }
        }
    })
</script>

子组件访问父组件

注意事项

  • 尽管在Vue开发中,我们允许通过$parent来访问父组件,但是在真实开发中尽量不要这样做。
  • 子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高。
  • 如果将子组件放在另一个父组件之内,很可能引起父组件没有对应的属性,往往会引起问题。
  • 另外更不能通过$parent来直接修改父组件的状态,那么父组件的状态将变得飘忽不定,不利于调试和维护。
<!-- $parent -->
<div id="app">
    <child-cpn></child-cpn>
</div>
<template id="child-cpn">
	<div>
        <h2>{{message}}<h2>
        <button @click="showparent">显示父子间</button>
    </div>
</template>
<script>
	let vm = new Vue({
        el:"#app",
        data:{
            message:"大家好,我是鸟飞",
        },
        components:{
            "child-cpn":{
                template:"#child-cpn",
                data:function(){
                    return{
                        message:"我是子组件"
                    }
                },
                methods:{
                    showparent:function(){
                        console.log(this.$parent)
                    }
                }
            }
        }
    })
</script>

插槽的使用

插槽的简单使用

<div id="app">
    <child-cpn></child-cpn>
    <child-cpn>
        <template slot="title"><h2>我是标题</h2></template>
        <template slot="msg"><p>大家好,我叫鸟飞,我是组件的内容。</p></template>
    </child-cpn>
</div>
<template id="child-cpn">
	<div>
        <slot name="title"><h2>我是组件的标题插槽</h2></slot>
        <slot name="msg"><p>我是组件的内容插槽</p></slot>
    </div>
</template>
<script>
	let vm = new Vue({
        el:"#app",
        components:{
            "child-cpn":{
                template:"#child-cpn"
            }
        }
    })
</script>

插槽数据处理

适用于Vue2.6以上版本

<div id="app">
    <child-cpn></child-cpn>
    <child-cpn>
    	<template slot="title">
            <h2>兴趣爱好</h2>
        </template>
        <template slot="hobby" v-slot:hobby="slotProps">
        	<span>{{slotProps.hobby.join("-")}}</span>
        </template>
    </child-cpn>
</div>
<template id="child-cpn">
	<div>
        <slot name="title"><h2>我是标题</h2></slot>
        <slot name="hobby" v-bind:hobby="hobby">
        	<ul>
                <li v-for="item in hobby">{{item}}</li>
            </ul>
        </slot>
    </div>
</template>
<script>
    let vm = new Vue({
        el:"#app",
        components:{
            "child-cpn":{
                template:"#child-cpn",
                data(){
                    return{
                        hobby:["篮球","羽毛球","足球","乒乓球","桌球"]
                    }
                }
            }
        }
    })
</script>

原文地址:https://www.cnblogs.com/niaofei123/p/14289133.html