Vue2:单文件组件、插槽
单文件组件
引入方式:
@1官方脚手架 @2挂载vm对象 @3组件引入并渲染到vm中
单文件组件有全局组件和局部组件 :
只是把一个组件单独写在一个.vue文件中,供别的组件引入然后注册
局部组件
1、在style标签中添加一个scoped
原理:vue的插件webpack打包时,会把当前组件模板中的每一个元素添加一个相同的哈希值命名的属性名
并且为添加了scoped的style中的样式选择器上添加一个属性选择器
2、vue文件中可以出现多个style标签 凡是添加了scoped属性的,里面的选择器就会被修改 没添加scoped属性的就不会被修改
var vm = new Vue({ el: "#box", data: {}, components: { Bar: { template: `` } } })
全局组件
方式:
1.在.vue文件中的style中写的样式 打包后就是全局样式
2.写一个css文件 在项目中导入就是全局样式
如果全局样式出现了相同的选择器. 就看是哪个最后打包引入项目 哪个的优先级就最高
//在主文件中引入其他组件 import Bar from "./xx.vue" import Bar from "@/xx.vue"
//xx.vue组件文件 <template> </template> <script> export default{ data(){ return{ }
} } </script> <style scoped="scoped"> </style>
单文件组件的技术点
1.在项目下创建vue.config.js 就是vue的打包配置文件:
const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, lintOnSave:false//关闭eslint的严格模式检测 })
2.引入文件时@代表了src目录的意思 这个@是vue的脚手架集成的basepath 其他框架中没有@不要记混乱了
3.注册的组件名不能跟vue中的和原生DOM的重名,注册的名字是驼峰 使用时就用连字符
4.注册的组件 使用时可以用双标签也可以用单标签: 如果有插槽必须用双标签
5.如果.vue的script注释了 在打包的时候 vue的打包环境 会帮我们把这个文件解析为一个对象 然后给这个对象添加一个template属性 值为解析的template页面模板字符串
也就是说 .vue文件中 可以不要<style>和<script> 但是不能不写<template>
6.style可以写多个
7.每一个组件内部只能有一个根元素 不要在根元素上写v-for 循环超过2次就会出现多个根元素
属性可以多传,但是注册了的属性就必须传,不然有可能会在使用时因为取值问题出BUG
属性名不要(不是不能)用vue官方或者原生标签已经签名过的名字:比如id class href
属性的类型验证只是一种验证提示 不会阻止程序运行
props:["prop1","prop2"]
props: { propA: Number, // 基础的类型检查 (`null` 匹配任何类型) propB: [String, Number], // 多个可能的类型 propC: { type: String, required: true // 必填的字符串 }, propD: { type: Number, default: 100 // 带有默认值的数字 }, propE: { type: Object, // 带有默认值的对象或者数组填Array default: function () { // 不建议直接填对象(因为对象直接量会一直占用内存),一般使用工厂函数,调用时才创建对象节省资源(面试) return { message: 'hello' } } }, propF: { validator: function (value) {// 自定义验证函数返回为true就代表数据符合我们规定 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } } }
v-slot:插槽
语法:v-slot:插槽名
语法糖:#插槽名
注意:
1、没有指定插槽名就是默认插入到插槽
2、不给插槽插入数据的话,就会使用组件的slot中的数据
3、插槽名不用使用引号引起来,直接写变量名
//vue主页面 <template> <div> <content2 :contentData="arr[1]"> <template #slot1> <img src="../assets/xx.jpg"> </template> <template #slot2> <p>在外部插入插槽的数据,不是子组件中的数据,也不是属性传进去的数据</p> </template> <template v-slot:slot3> 666 </template> <p>没有指定插入到哪里</p> </content2> </div> </template>
//组件页面
<template> <div class="content1"> <slot></slot> <slot name="slot1"></slot> <h1>{{contentData.title}}</h1> <h2>{{contentData.dt}}</h2> <slot name="slot3">你不给我数据到3号插槽中 我就会默认显示出来</slot> <p>{{contentData.text}}</p> <slot name="slot2"></slot> </div> </template> <script> export default{ props:{ contentData:{ type:Object, default:()=>{return {title:"0",dt:"0",text:"0"}} } } } </script>