1.Vue模板语法 1.1插值操作 mustache语法 expr可以是变量,常量,表达式,会自动根据Vue中的data进行渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <div id ="app" > <h2 > {{message}}</h2 > <h2 > {{message+message}}</h2 > <h2 > {{v*2}}</h2 > <h2 > {{firstName+" "+lastName}}</h2 > <h2 > {{firstName}}{{lastName}}</h2 > </div > <script src ="../js/vue.js" > </script > <script > const app = new Vue({ el: '#app' , data: { message: "test" , firstName: "hello" , lastName: "world" , v: 100 } }) </script >
v-once 此时,数据只从vue中得到数据初始化渲染一次,之后该组件(标签内)的数据不会随着data中的数据变化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <div id ="app" > <h2 v-once > {{message}}</h2 > </div > <script src ="../js/vue.js" > </script > <script > const vm = new Vue({ el: '#app' , data: { message: "test" , } }) </script >
v-html 类似于innerHtml(),把数据进行解析后显示
v-text 类似于innerText(),把原数据显示出来
v-pre 忽略mustache直接显示出两个大括号
v-cloak 在Vue渲染html标签前,让被渲染的元素隐藏,不显示原生的{ {} }等语法
1.2动态绑定属性 v-bind 为标签的属性绑定Vue的data值,绑定后属性值将根据这个data动态改变
v-bind可用冒号:
代替
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div id ="app" > <img v-bind:src ="imgurl" alt ="" > <a :href ="url" > 百度一下</a > </div > <script src ="../js/vue.js" > </script > <script > const vm = new Vue({ el: '#app' , data: { imgurl: 'https://www.baidu.com/img/flexible/logo/pc/result.png' , url: 'www.baidu.com' } }) </script >
动态参数 https://cn.vuejs.org/v2/guide/syntax.html#%E5%8A%A8%E6%80%81%E5%8F%82%E6%95%B0
v-bind绑定class 通过对象绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 <h2 :class ={ 类名1:boolean ,类名2:boolean }> vue</h2 > <h2 class ="title" :class ="{'active': isActive, 'line': isLine}" > Hello World</h2 > <script src ="../js/vue.js" > </script > <script > const vm = new Vue({ el: '#app' , data: { isActive: true , isLine: false } }) </script >
通过一个对象的形式,若类名对应的值(vue中的data)为true值会为标签绑定class,false则不会,可与原生的class共存。若对象过于复杂,可通过methods或计算属性返回一个对象。
通过数组绑定
1 2 <h2 class ="title" :class ="[类名, 类名,···]" > Hello World</h2 > <h2 class ="title" :class ="[active, line]" > Hello World</h2 >
类名可以是一个变量,常量,表达式,最终代表需要绑定的类名
v-bind绑定style 利用v-bind:style来绑定一些CSS内联样式。
通过对象绑定
1 2 3 <h1 :style ="{属性名:属性值,属性名:属性值,···}" > {{massage}}</h1 > <h1 :style ="{color:colorStyle,'background-color':bkColorStyle,fontSize:fSize+'px'}" > {{massage}}</h1 >
属性名可以是小驼峰式,或者短横线分隔式(需单引号括起)
属性值可以是常量,变量,表达式
通过数组绑定
1 2 3 4 5 6 7 8 9 10 11 <div v-bind:style ="[baseStyles, overridingStyles]" > </div > <script > const vm = new Vue({ el: '#app' , data: { baseStyles: {color :'red' ,'background-color' :'gray' }, overridingStyles: {fontSize :'20px' } } }) </script >
数组中放的是对象,每个对象代表一个css样式,本质上就是通过对象绑定
1.3方法与计算属性 方法(methods): 类似于函数,只不过它属于指定的vue对象
计算属性(computed): 本质上是属性,只是多了getter和setter方法(类似于bean),并且与方法methods相比,具备缓存功能,可以动态监听,当数据改变时才会调用getter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <div id ="app" > <h2 > {{fullName}}</h2 > <h2 > {{fullName2}}</h2 > <h2 > {{fullName3()} }</h2 > <h2 > {{fullName4()} }</h2 > </div > <script type ="text/javascript" src ="../js/vue.js" > </script > <script > const vm = new Vue({ el: '#app' , data: { firstName:'Alan' , lastName:'Turing' }, computed:{ fullName: { get: function ( ) { return this .firstName + ' ' + this .lastName }, set: function (newValue ) { let names = newValue.split(' ' ) this .firstName = names[0 ] this .lastName = names[names.length - 1 ] } }, fullName2:function ( ) { return (this .firstName+' ' +this .lastName).toUpperCase(); } }, methods:{ fullName3:function ( ) { return this .firstName+' ' +this .lastName; }, fullName4(){ return this .firstName+' ' +this .lastName; } } }) </script >
1.4侦听器和滤波器 侦听器:侦听vue实例中的数据变化,一旦数据发生变化就会执行回调函数
1 2 3 4 5 6 7 8 9 10 11 12 13 <script > const vm = new Vue({ el: '#app' , data:{ val=100; } watch:{ val:function (newVal,oldVal ) { console .log(newVal+' ' +oldVal); } }) </script >
滤波器:在输出内容时,给内容添加修饰。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div id ="app" > <span > 总价:{{totalPrice |showPrice } }</span > </div > <script > const vm = new Vue({ el: '#app' , data:{ totalPrice=100; } filters:{ showPrice(totalPrice){ return "¥" +totalPrice.toFixed(2 ); } }) </script >
1.5事件监听 v-on
作用 :绑定事件监听器
缩写 :@
预期 :Function | Inline Statement | Object
参数 :event
v-on:click="func1"
,引号内填写函数名,不带括号时,默认传入一个event,带括号时按正常情况传递参数,当需要传递事件对象时,参数为$event
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <div id ="app" > <button v-on:click ="func1" > 按钮1</button > <button @click ="func2('123','abc')" > 按钮2</button > <button @click ="func2" > 按钮3</button > <button @click ="func2('123',$event)" > 按钮4</button > </div > <script > const vm = new Vue({ el: '#app' , methods:{ func1(param1){ alert("This is btn1:" +param1) ; }, func2(param1,param2){ alert("This is btn2:" +param1+' ' +param2) ; } } }) </script >
v-on修饰符
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
1 2 3 4 5 6 7 8 9 10 11 12 13 <button @click.stop ="doThis" > button</button > <form @submit.prevent ="doThis" action ="url" > <input type ="text" > <input type ="submit" > </form > <button @click.stop.prevent ="doThis" > button</button > <input type ="text" @keyup.enter ="doThis" @keydown.10 ="doThis" > <button @click.once ="doThis" > button</button >
关于修饰符的知识还很欠缺,例如不同修饰符顺序引发不同的结果
一些键修饰别名:
.enter
.tab
.delete
(捕获 “删除” 和 “退格” 键)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
1.6条件渲染 if、else if、else 这三个指令类似于if、else、else if。Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div id ="app" > <h3 v-if ="score>=90" > Excellent</h3 > <h3 v-else-if ="score>=80" > Good</h3 > <h3 v-else-if ="score>=60" > Ok</h3 > <h3 v-else > Fail</h3 > </div > <script type ="text/javascript" src ="../js/vue.js" > </script > <script > const vm = new Vue({ el: '#app' , data:{ score:90, } }) </script >
v-show v-show
和v-if
的用法类似,都是决定一个页面是否被渲染。
区别:
v-if
当条件为false时,压根不会有对应的元素在DOM中。
v-show
当条件为false时,仅仅是将元素的display
属性设置为none
而已。
当需要在显示与隐藏之间切片很频繁时,使用`v-show`。
当只有一次切换时,通过使用`v-if`。
1.7列表渲染 v-for 1 2 3 4 5 6 7 8 <li v-for ="value in arr" > {{value}}</li > <li v-for ="(value,index) in arr" > {{value}}-{{index}}</li > <li v-for ="value in obj" > {{value}}</li > <li v-for ="(value,key) in obj" > {{value}}-{{key}}</li > <li v-for ="(value,key,index) in obj" > {{value}}-{{key}}-{{index}}</li >
数组响应式更新 Vue具有数据绑定的功能,因此当vue实例中的数据发生改变时,视图能做出改变响应。
对数组使用如下方法,都会使得视图发生更新
1 2 3 4 5 6 7 8 9 let arr;arr.push(); arr.pop(); arr.unshift(); arr.shift(); arr.splice(); arr.sort(); arr.reverse();
唯一需要注意的是使用如下方式1 的数组下标赋值的方法,视图并不会发生更新
1 2 3 4 5 6 7 8 9 10 11 let arr=[{key :value}];arr[0 ]={key2 :value2}; let arr2={key :value};arr2[0 ].key=value2; Vue.set(this .arr,index,value);
1.8两个练手小案例: 点击绑定样式和购物车
1.9v-model表单绑定
你可以用 v-model
指令在表单 <input>
、<textarea>
及 <select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。此外input中的value属性也支持v-bind动态绑定。
v-model原理 v-model其实是一个语法糖,它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。它的背后本质上是包含两个操作:
1.v-bind绑定一个value属性
2.v-on指令给当前元素绑定input事件
v-model
会忽略 所有表单元素 的 value
、checked
、selected
attribute 的初始值 而总是将 Vue 实例的数据作为数据来源 。你应该通过 JavaScript 在组件的 data
选项中声明初始值。
v-model
在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
text 和 textarea 元素使用 value
property 和 input
事件;
checkbox 和 radio 使用 checked
property 和 change
事件;
select 字段将 value
作为 prop 并将 change
作为事件。
以下代码等价:
1 <input type ="text" v-model ="message" >
1 <input type ="text" v-bind:value ="message" v-on:input ="message = $event.target.value" >
文本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <div id ="app" > <p > 单行文本:Message is: { { message1 } }</p > <input v-model ="message1" placeholder ="edit me" > <br > <hr > <span > 多行文本: Multiline message is:</span > <p style ="white-space: pre-line;" > {{ message2 } }</p > <br > <textarea v-model ="message2" placeholder ="add multiple lines" > </textarea > </div > <script > const vm = new Vue({ el: '#app' , data:{ message1:'' , message2:'' } }) </script >
单选按钮 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <div id ="app" > <input type ="radio" id ="one" value ="One" v-model ="picked" > <label for ="one" > One</label > <br > <input type ="radio" id ="two" value ="Two" v-model ="picked" > <label for ="two" > Two</label > <br > <span > Picked: { { picked } }</span > </div > <script > const vm = new Vue({ el: '#app' , data:{ picked: '' , } }) </script >
原生的单选按钮中,不同的按钮需要通过一个相同的name来实现互斥,当使用v-model时,可通过绑定同一个value来实现互斥。
复选框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <h3 > 单个复选框</h3 > <input type ="checkbox" id ="checkbox" v-model ="checked" > <label for ="checkbox" > {{ checked } }</label > <h3 > 多个复选框</h3 > <input type ="checkbox" id ="jack" value ="Jack" v-model ="checkedNames" > <label for ="jack" > Jack</label > <input type ="checkbox" id ="john" value ="John" v-model ="checkedNames" > <label for ="john" > John</label > <input type ="checkbox" id ="mike" value ="Mike" v-model ="checkedNames" > <label for ="mike" > Mike</label > <br > <span > Checked names: { { checkedNames } }</span > <script > const vm = new Vue({ el: '#app' , data:{ checked:undefined , checkedNames: [], } }) </script >
选择框 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <h3 > 单个选择框</h3 > <div > <select v-model ="option" > <option disabled value ="" > 请选择</option > <option > A</option > <option > B</option > <option > C</option > </select > <span > Selected: { { option } }</span > </div > <h3 > 多个选择框</h3 > <div > <select v-model ="options" multiple style ="width: 50px;" > <option > A</option > <option > B</option > <option > C</option > </select > <br > <span > Selected: { { options } }</span > </div > <script > const vm = new Vue({ el: '#app' , data:{ option:'' , options: [], } }) </script >
修饰符 lazy修饰符:
默认情况下,v-model默认是在input事件中同步输入框的数据的。
也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。
lazy修饰符可以让数据在失去焦点 或者回车时 才会更新:
number修饰符:
默认情况下,如果希望用户输入数字,原生的input提供了type=”number”的用法,但是在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。
因此可通过<input v-model.number="age" type="number">
给 v-model
添加 number
修饰符可以让在输入框中输入的内容自动转成数字类型:
trim修饰符:
如果要自动过滤用户输入的首尾空白字符,可以给 v-model
添加 trim
修饰符:<input v-model.trim="msg">
2.组件化开发 组件是可复用的 Vue 实例,且带有一个名字,并且组件相对于Vue来说多了一些例如template模板等功能,template使得组件内部可封装某些标签数据。
2.1.组件使用流程 基本使用
创建组件对象(最新vue手册中已不使用Vue.extend()创建组件对象了)
调用Vue.component()方法注册组件
在Vue实例的作用范围内使用组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <div id ="app" > <cpn > </cpn > </div > <cpn > </cpn > <script > // <h3 > 我是标题</h3 > // <div > 我是内容</div > const cpnObj = { template:` <div > <h3 > 我是标题</h3 > <div > 我是内容</div > </div > ` }; Vue.component('cpn' ,cpnObj); const vm = new Vue({ el: '#app' , }); </script >
语法糖 直接在注册时传入对象参数
1 2 3 4 5 6 7 8 9 10 11 <script > Vue.component('cpn' ,{ template:` <div > <h3 > 我是标题</h3 > <div > 我是内容</div > </div > ` }); </script >
2.2全局组件和局部组件 全局组件: 凡是以Vue.component()进行注册的都是全局组件,可以在任何挂载了Vue实例的标签内使用
局部组件: 在Vue实例中注册,或在组件中注册为子组件的组件都是局部组件,他们的作用范围限于各自注册的实例(组件)中。
一个组件对象可在不同的作用域中注册为不同的组件
代码实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <div id ="app" > <cpn2 > </cpn2 > <cpn1 > </cpn1 > </div > <script > const cpnObj1 = { template:` <div > <h3 > 标题1</h3 > </div > ` }; const cpnObj2 = { template:` <div style ="color: #ff0000" > <h3 > 标题2</h3 > <cpn1 > </cpn1 > </div > `, components:{ cpn1:cpnObj1 } }; Vue.component('cpn2' ,cpnObj2); const vm = new Vue({ el: '#app' , components:{ cpn1:cpnObj1 } }) </script >
2.3分离模板 可将组件的template分离出来,单独写在一个标签中
使用script标签
使用script标签包裹template,并给定id,然后在组件对象中引用template的id即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <script type ="text/x-template" id ="myCpn" > <div > <h3 > 这是组件</h3 > </div > </script > <script type ="text/javascript" src ="../js/vue.js" > </script > <script > const cpnObj = Vue.extend() const vm = new Vue({ el: '#app' , components:{ cpn: { template:'#myCpn' } } }) </script >
使用template标签
与script标签相比,不用指定type=”text/x-template”,其余相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <template id ="myCpn" > <div > <h3 > 这是组件</h3 > </div > </template > <script > const cpnObj = Vue.extend() const vm = new Vue({ el: '#app' , components:{ cpn: { template:'#myCpn' } } }) </script >
2.4组件data
问题引入:组件也是一个Vue实例,意味着组件也可以有自己的data,那么当组件标签使用多次时,每个组件标签引用的是同一个data,这样是明显不合理的,即在组件复用的时候,它们应该引用不同的data对象。
解决方法:Vue强制规定在组件中必须把data写成函数的形式,并且该函数返回一个对象来作为该组件的data,利用函数的作用域来让每个组件标签引用不同的数据对象。
每一次使用组件,function中都会有一个对象被创建并赋值给data
code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <div id ="app" > <cpn > </cpn > </div > <template id ="myCpn" > <div > <h3 > 这是组件:{{msg}}</h3 > </div > </template > <script > const vm = new Vue({ el: '#app' , components:{ cpn:{ data(){ return { msg:'message' } }, template: '#myCpn' } } }) </script >
2.5父子组件的数据传递 子组件是无法访问父组件或Vue实例中的数据的,而在实际的开发中,常常需要把父组件的数据传递给子组件使用,因此Vue提供了父子组件间传递数据的方法。
值得注意的是:当一个组件1在某个组件2内部注册为局部组件后不代表该组件1就是组件2的子组件了,只能说明组件1是作用在组件2内部的局部组件。
判断是否为一个组件的子组件看的是在template标签中是否嵌套使用了组件标签,例如在挂载了vue实例的div中使用组件标签cpn,此时cpn就是vue的子组件
父组件=>子组件 props 父组件(Vue实例)把数据传递给子组件中的props属性。
在子组件中的props中声明自己的属性(prop),用于接收父组件传递的数据
在使用该子组件标签时,为该子组件的prop属性赋值或动态绑定变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <div id ="app" > 1:<cpn attr1 ="attribute1" > </cpn > 2:<cpn :attr2 ="val" > </cpn > </div > <template id ="myCpn" > <div > <h3 > 这是属性1:{{attr1}}</h3 > <h3 > 这是属性2:{{attr2}}</h3 > </div > </template > <script > const vm = new Vue({ el: '#app' , data:{ val:'attribute2' }, components:{ cpn:{ template: '#myCpn' , props:['attr1' ,'attr2' ] } } }); </script >
当需要对传入子组件中的prop进行类型验证或默认值等操作时,就需要采用对象语法,实例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <div id ="app" > 1:<cpn :attr1 ="num" > </cpn > 2:<cpn :attr2 ="val" > </cpn > </div > <template id ="myCpn" > <div > <h3 > 这是属性1:{{attr1}}</h3 > <h3 > 这是属性2:{{attr2}}</h3 > </div > </template > <script > const vm = new Vue({ el: '#app' , data:{ val:'DeliveredParameter' , num:10 }, components:{ cpn:{ template: '#myCpn' , props:{ attr1:{ type: Number , }, attr2:{ type: String , default (){ return 'DefaultString' ; } } } } } }); </script >
支持的数据验证类型:验证都支持哪些数据类型呢?String,Number,Boolean,Array,Object,Date,Function,Symbol
子组件=>父组件 $emit 子组件通过触发自定义事件传递数据
父组件(Vue实例)则通过v-on监听子组件触发的事件,并从参数中获得数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <div id ="app" > <cpn @my-event ="handler" > </cpn > </div > <template id ="myCpn" > <div > <button @click ="BtnClick()" > Click me!</button > </div > </template > <script > const vm = new Vue({ el: '#app' , data:{ val:'DeliveredParameter' , }, methods:{ handler(val){ console .log('handler is done:' +val); } }, components:{ cpn:{ template: '#myCpn' , props:{ attr:{ type: String , default (){ return 'DefaultString' ; } } }, methods:{ BtnClick(){ this .$emit('my-event' ,this .attr); } } } } }); </script >
2.6父子组件的相互访问 有时候,在父组件内可能会出现引用子组件中某个函数或变量的情况,vue提供了三个变量来实现父子组件间的相互访问。
父组件访问子组件:$children或$refs
子组件访问父组件:$parent
子组件访问根组件:$root
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 <div id ="app" > <cpn > </cpn > <cpn > </cpn > </div > <template id ="tem1" > <div > <h3 > I am son</h3 > <ccpn > </ccpn > <ccpn > </ccpn > </div > </template > <template id ="tem2" > <div > <h3 > I am grandson</h3 > </div > </template > <script > const vm = new Vue({ el: '#app' , data:{ val:'I am root' , }, methods:{ func1(){ console .log(this .$children[0 ].val); } }, components:{ cpn:{ template: '#tem1' , data(){ return { val: 'I am son' } }, methods:{ func1(){ console .log(this .$parent.val); } }, components: { ccpn:{ template: '#tem2' , data() { return { val: 'I am grandson' } }, methods:{ func1(){ console .log(this .$root.val); } } }, } }, } }); </script >
采用$children形式得到的是包含所有子组件的数组,并且索引与顺序有关
由于组件标签中同一级别的标签数量和标签可能发生变化,因此这种方法显然在修改时不太容易。
$refs就可避免这个问题this.$refs得到的是一个包含所有子组件的对象,$refs使用时只需要为每个子组件指定一个键,ref=”id”,然后父组件再引用时采用this.$refs.id即可访问子组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <div id ="app" > <cpn ref ="first" > </cpn > <cpn ref ="second" > </cpn > </div > <script > const vm = new Vue({ el: '#app' , data: { val: 'I am root' , }, methods: { func1() { console .log(this .$refs.first); } }, } </script >
2.7slot插槽 基本插槽 在编写组件模板的时候,会出现两个模板高度相似的情况,为了更好的复用模板,vue提出了在组件模板中引入插槽slot。slot标签内表示预留一个位置可供其它html代码或组件 插入。提高了组件的复用性和可扩展性。
1 2 3 4 5 6 7 8 9 10 11 12 <div id ="app" > <cpn > </cpn > <cpn > <span > 自定义内容1</span > </cpn > </div > <template id ="tem1" > <div > <h3 > 我是组件</h3 > <slot > <button > 默认内容</button > </slot > </div > </template >
若组件cpn的template
中没有 包含一个 <slot>
元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃(即cpn标签内部内容无效)。
该插槽跟模板的其它地方一样可以访问相同的实例 property (也和vue组件拥有相同的“作用域”)
具名插槽 当一个模板中需要有多个插槽的时候,如果在使用的时候vue默认把cpn标签的内容区替换每个v-slot标签,这个时候就需要为每个插槽指定名称,并在使用时注明。
1 2 3 4 5 6 7 8 9 10 11 12 <div class ="container" > <header > <slot name ="header" > </slot > </header > <main > <slot > </slot > </main > <footer > <slot name ="footer" > </slot > </footer > </div >
在向具名插槽提供内容的时候,我们可以在一个 <template>
元素上使用 v-slot
指令,并以 v-slot
的参数的形式提供其名称:v-slot可缩写为#,使用缩写时必须带上插槽名,例如default
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <base-layout > <template v-slot:header > <h1 > Here might be a page title</h1 > </template > <p > A paragraph for the main content.</p > <p > And another one.</p > <template #:footer > <p > Here's some contact info</p > </template > </base-layout >
作用域插槽 由于组件的编译作用域原因,父组件中无法访问子组件的数据,意味着当父组件向子组件中的slot中插入内容时无法访问到子组件中的数据。
为了解决这一问题,vue提供了作用域插槽,即在为每个实例slot绑定一个function,在把子组件的数据传递到该function的作用域中,实现了每个插槽都有自己单独的作用域。
本质上是:为每个实例的slot标签提供一个作用域,子组件可把数据绑定到slot作用域里,然后父组件在往slot中插入东西时,可以访问slot作用域中的数据。
CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <div id ="app" > <cpn > </cpn > <cpn > <template v-slot:default ="myScope" > <span > 自定义显示年龄:{{myScope.val.age}}</span > </template > </cpn > </div > <template id ="tem1" > <div > <h3 > 我是组件</h3 > <slot v-bind:val ="user" > <span > 默认显示子组件data()中的user.name(姓名):{{user.name}}</span > </slot > </div > </template > <script > const vm = new Vue({ el: '#app' , components:{ cpn:{ template: '#tem1' , data(){ return { user: { name:'Qian' , age:21, } } }, }, } }); </script >
独占插槽 当被提供的内容只有 默认插槽时,组件的标签 才可以被当作插槽的模板来使用,不需要被template标签包裹。这样我们就可以把 v-slot
直接用在组件上:
1 2 3 4 <current-user v-slot:default ="slotProps" > { { slotProps.user.firstName } } </current-user >
当组件内有多个插槽时,为所有 的插槽使用完整 的基于 <template>
的语法:即每个插槽内容均包裹于template,且指定v-slot:default(othername)
附(一):参考: 阿清博客:https://aqingya.cn/articl/92af846d.html
官网文档:https://cn.vuejs.org/v2/guide/
附(二)快捷键: 1 2 3 4 "string".log +tab = console.log("string") div#a + tab = <div id ="a" > </div > div.b + tab = <div class ="b" > </div >