您现在的位置是:网站首页> 小程序设计
uniapp重头到尾
- 小程序设计
- 2024-08-21
- 1120人已阅读
全局变量机制。这套机制在uni-app里也可以使用,并且全端通用
页面传值
//在起始页面跳转到test.vue页面并传递参数
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});
// 在test.vue页面接受参数
export default {
onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
console.log(option.id); //打印出上个页面传递的参数。
console.log(option.name); //打印出上个页面传递的参数。
}
}
每个页面保存页面对象便于其他地方使用
<script>
var _self=this;
export default{
data(){
return{
m_Data:{}
}
},
onLoad(){
_self=this;
_self.m_Data.A="xuneng";
},
...
methods:
{
NFCInit() {
console.log(_self.m_Data.A);
},
...
}
}
</script>
条件编译uniapp直接调用微信小程序api
helloWX(){
//#ifdef MP-WEIXIN
const systemSetting = wx.getSystemSetting();
console.log(systemSetting.wifiEnabled);
//#endif
}
uniapp原生tabbar设置并添加数字角标或小红点提示
uni.setTabBarBadge({ //显示数字
index: 2,//tabbar下标
text: '1'//数字
})
uni.removeTabBarBadge({ //隐藏数字标
index:2
})
uni.showTabBarRedDot({ //显示红点
index: 2
})
uni.hideTabBarRedDot({ //隐藏红点
index:2
})
添加至任何页面的js事件里即可,事件执行,则显示或移除
页面跳转注意,页面跳转
注意跳转到tabbar页面一定要用switchTab
uni.navigateTo(OBJECT)
保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面
uni.redirectTo(OBJECT)
关闭当前页面,跳转到应用内的某个页面
uni.reLaunch(OBJECT)
关闭所有页面,打开到应用内的某个页面。
uni.switchTab(OBJECT)
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
uni.navigateBack(OBJECT)
关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。
uni.preloadPage(OBJECT)
预加载页面,是一种性能优化技术。被预载的页面,在打开时速度更快
窗口动画
uni.navigateTo({
url: '../test/test',
animationType: 'pop-in',
animationDuration: 200
});
uni.navigateBack({
delta: 1,
animationType: 'pop-out',
animationDuration: 200
});
┌─uniCloud 云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud)
│─components 符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─uni_modules 存放[uni_module](/uni_modules)规范的插件。
├─wxcomponents 存放小程序组件的目录,详见
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
├─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
└─uni.scss 这里是uni-app内置的常用样式变量
└─package.json nmp的包管理可有可无 可以在项目目录下通过哟npm init 初始化生成,通过nmp instal --save 包名 安装包 安装后的包再node_modules下
可直接使用import 包名 from '包名'
─components
├─hybrid
│ └─html
│ ├─css
│ │ └─test.css
│ ├─img
│ │ └─icon.png
│ ├─js
│ │ └─test.js
│ └─local.html
├─pages
│ └─index
│ └─index.vue
├─static
├─main.js
├─App.vue
├─manifest.json
└─pages.json
使用
<template>
<view>
<web-view src="/hybrid/html/local.html"></web-view>
</view>
</template>
<web-view> 加载的网页中支持调用部分 uni 接口:
方法名说明平台差异说明
uni.navigateTonavigateTo
uni.redirectToredirectTo
uni.reLaunchreLaunch
uni.switchTabswitchTab
uni.navigateBacknavigateBack
uni.postMessage向应用发送消息字节跳动小程序不支持、H5 暂不支持(可以直接使用 window.postMessage (opens new window))
uni.getEnv获取当前环境字节跳动小程序与飞书小程序不支持
uni.postMessage(OBJECT)
网页向应用发送消息,在 <web-view> 的 message 事件回调 event.detail.data 中接收消息
传递的消息信息,必须写在 data 对象中。
event.detail.data 中的数据,以数组的形式接收每次 post 的消息
在 <web-view> 加载的 HTML 中,添加以下代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>网络网页</title>
<style type="text/css">
.btn {
display: block;
margin: 20px auto;
padding: 5px;
background-color: #007aff;
border: 0;
color: #ffffff;
height: 40px;
width: 200px;
}
.btn-red {
background-color: #dd524d;
}
.btn-yellow {
background-color: #f0ad4e;
}
.desc {
padding: 10px;
color: #999999;
}
.post-message-section {
visibility: hidden;
}
</style>
</head>
<body>
<p class="desc">web-view 组件加载网络 html 示例。点击下列按钮,跳转至其它页面。</p>
<div class="btn-list">
<button class="btn" type="button" data-action="navigateTo">navigateTo</button>
<button class="btn" type="button" data-action="redirectTo">redirectTo</button>
<button class="btn" type="button" data-action="navigateBack">navigateBack</button>
<button class="btn" type="button" data-action="reLaunch">reLaunch</button>
<button class="btn" type="button" data-action="switchTab">switchTab</button>
</div>
<div class="post-message-section">
<p class="desc">网页向应用发送消息,注意:小程序端应用会在此页面后退时接收到消息。</p>
<div class="btn-list">
<button class="btn btn-red" type="button" id="postMessage">postMessage</button>
</div>
</div>
<script type="text/javascript">
var userAgent = navigator.userAgent;
if (userAgent.indexOf('AlipayClient') > -1) {
// 支付宝小程序的 JS-SDK 防止 404 需要动态加载,如果不需要兼容支付宝小程序,则无需引用此 JS 文件。
document.writeln('<script src="https://appx/web-view.min.js"' + '>' + '<' + '/' + 'script>');
} else if (/QQ/i.test(userAgent) && /miniProgram/i.test(userAgent)) {
// QQ 小程序
document.write(
'<script type="text/javascript" src="https://qqq.gtimg.cn/miniprogram/webview_jssdk/qqjssdk-1.0.0.js"><\/script>'
);
} else if (/miniProgram/i.test(userAgent) && /micromessenger/i.test(userAgent)) {
// 微信小程序 JS-SDK 如果不需要兼容微信小程序,则无需引用此 JS 文件。
document.write('<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"><\/script>');
} else if (/toutiaomicroapp/i.test(userAgent)) {
// 头条小程序 JS-SDK 如果不需要兼容头条小程序,则无需引用此 JS 文件。
document.write(
'<script type="text/javascript" src="https://s3.pstatp.com/toutiao/tmajssdk/jssdk-1.0.1.js"><\/script>');
} else if (/swan/i.test(userAgent)) {
// 百度小程序 JS-SDK 如果不需要兼容百度小程序,则无需引用此 JS 文件。
document.write(
'<script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.18.js"><\/script>'
);
} else if (/quickapp/i.test(userAgent)) {
// quickapp
document.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"><\/script>');
}
if (!/toutiaomicroapp/i.test(userAgent)) {
document.querySelector('.post-message-section').style.visibility = 'visible';
}
</script>
<!-- uni 的 SDK -->
<!-- 需要把 uni.webview.1.5.2.js 下载到自己的服务器 -->
<script type="text/javascript" src="https://gitee.com/dcloud/uni-app/raw/master/dist/uni.webview.1.5.2.js"></script>
<script type="text/javascript">
// 待触发 `UniAppJSBridgeReady` 事件后,即可调用 uni 的 API。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.postMessage({
data: {
action: 'message'
}
});
uni.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
});
document.querySelector('.btn-list').addEventListener('click', function(evt) {
var target = evt.target;
if (target.tagName === 'BUTTON') {
var action = target.getAttribute('data-action');
switch (action) {
case 'switchTab':
uni.switchTab({
url: '/pages/tabBar/API/API'
});
break;
case 'reLaunch':
uni.reLaunch({
url: '/pages/tabBar/component/component'
});
break;
case 'navigateBack':
uni.navigateBack({
delta: 1
});
break;
default:
uni[action]({
url: '/pages/component/button/button'
});
break;
}
}
});
document.getElementById('postMessage').addEventListener('click', function() {
uni.postMessage({
data: {
action: 'message'
}
});
});
});
</script>
</body>
</html>
Q:web-view 的页面怎么和应用内的页面交互? A:调用 uni 相关的 API,就可以实现页面切换及发送消息。参考:在 web-view 加载的 HTML 中调用 uni 的 API(opens new window)
Q:web-view 加载的 HTML 中,能够调用 5+ 的能力么? A:加载的 HTML 中是有 5+ 环境的,在 plusready 后调用即可。参考:一个简单实用的 plusready 方法(opens new window)
Q: web-view 加载 uni-app H5,内部跳转冲突如何解决 A:使用 uni.webView.navigateTo...
uni.webView.navigateTo 示例,注意uni sdk放到body下面
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<noscript>
<strong>Please enable JavaScript to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
<!-- uni 的 SDK -->
<!-- 需要把 uni.webview.1.5.2.js 下载到自己的服务器 -->
<script type="text/javascript" src="https://gitee.com/dcloud/uni-app/raw/master/dist/uni.webview.1.5.2.js"></script>
<script>
document.addEventListener('UniAppJSBridgeReady', function() {
uni.webView.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
});
// uni.webView.navigateTo(...)
});
</script>
</html>
nvue webview通信示例
<template>
<view>
<web-view ref="webview" @onPostMessage="handlePostMessage"></web-view>
<button @click="evalJs">evalJs(改变webview背景颜色)</button>
</view>
</template>
<script>
export default {
data: {
},
methods: {
// webview向外部发送消息
handlePostMessage: function(data) {
console.log("接收到消息:" + JSON.stringify(data.detail));
},
// 调用 webview 内部逻辑
evalJs: function() {
this.$refs.webview.evalJs("document.body.style.background ='#00FF00'");
}
}
}
</script>
条件编译 /* #ifdef APP-PLUS */ 代码区域 /*#endif*/
平台的定义
APP-PLUSApp
APP-PLUS-NVUE或APP-NVUEApp nvue
H5H5
MP-WEIXIN微信小程序
MP-ALIPAY支付宝小程序
MP-BAIDU百度小程序
MP-TOUTIAO字节跳动小程序
MP-LARK飞书小程序
MP-QQQQ小程序
MP-KUAISHOU快手小程序
MP-JD京东小程序
MP-360360小程序
MP微信小程序/支付宝小程序/百度小程序/字节跳动小程序/飞书小程序/QQ小程序/360小程序
QUICKAPP-WEBVIEW快应用通用(包含联盟、华为)
QUICKAPP-WEBVIEW-UNION快应用联盟
QUICKAPP-WEBVIEW-HUAWEI快应用华为
应用生命周期
uni-app 支持如下应用生命周期函数:
函数名说明
onLaunch当uni-app 初始化完成时触发(全局只触发一次)
onShow当 uni-app 启动,或从后台进入前台显示
onHide当 uni-app 从前台进入后台
onError当 uni-app 报错时触发
onUniNViewMessage对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯(opens new window)
onUnhandledRejection对未处理的 Promise 拒绝事件监听函数(2.8.1+)
onPageNotFound页面不存在监听函数
onThemeChange监听系统主题变化
<script>
// 只能在App.vue里监听应用的生命周期
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
全局变量机制。这套机制在uni-app里也可以使用,并且全端通用
App.vue 中定义globalData的相关配置:
<script>
export default {
globalData: {
text: 'text'
}
}
</script>
js中操作globalData的方式如下: getApp().globalData.text = 'test'
在应用onLaunch时,getApp对象还未获取,暂时可以使用this.globalData获取globalData。
如果需要把globalData的数据绑定到页面上,可在页面的onShow页面生命周期里进行变量重赋值。
nvue的weex编译模式中使用globalData的话,由于weex生命周期不支持onShow,但熟悉5+的话,可利用监听webview的addEventListener show事件实现onShow效果,或者直接使用weex生命周期中的beforeCreate。但建议开发者使用uni-app编译模式,而不是weex编译模式。
globalData是简单的全局变量,如果使用状态管理,请使用vuex(main.js中定义)
全局样式如:
<style>
@import "colorui/main.css";
@import "colorui/icon.css";
@import "@/uni_modules/uview-ui/index.scss";
</style>
何为scoped?
在vue文件中的style标签上,有一个特殊的属性:scoped。
当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,也就是说,该样式只能适用于当前组件元素。
通过该属性,可以使得组件之间的样式不互相污染。如果一个项目中的所有style标签全部加上了scoped,相当于实现了样式的模块化。
穿透scoped
scoped看起来很美,但是,在很多项目中,会出现这么一种情况,即:引用了第三方组件,需要在组件中局部修改第三方组件的样式,而又不想去除scoped属性造成组件之间的样式污染。此时只能通过特殊的方式,穿透scoped。
曲线救国的方法,即在定义一个含有scoped属性的style标签之外,再定义一个不含有scoped属性的style标签,即在一个vue组件中定义一个全局的style标签,一个含有作用域的style标签:
<style>
/* global styles */
</style>
<style scoped>
/* local styles */
</style>
此时,你只需要将修改第三方样式的css写在第一个style中即可
样例
{
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "@/components/uni-$1.vue", // 匹配components目录内的vue文件
"^vue-file-(.*)": "packageName/path/to/vue-file-$1.vue" // 匹配node_modules内的vue文件
}
},
/*懒加载
属性类型默认值描述
autoscanBooleantrue是否开启自动扫描,开启后将会自动扫描符合components/组件名称/组件名称.vue目录结构的组件
customObject-以正则方式自定义组件匹配规则。如果autoscan不能满足需求,可以使用custom自定义匹配规则*/
"pages": [{
"path": "pages/component/index",
"style": {
"navigationBarTitleText": "组件"
}
}, {
"path": "pages/API/index",
"style": {
"navigationBarTitleText": "接口"
}
}, {
"path": "pages/component/view/index",
"style": {
"navigationBarTitleText": "view"
}
}],
"condition": { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [{
"name": "test", //模式名称
"path": "pages/component/view/index" //启动页面,必选
}]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "演示",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"usingComponents":{
"collapse-tree-item":"/components/collapse-tree-item"
},
"renderingMode": "seperated", // 仅微信小程序,webrtc 无法正常时尝试强制关闭同层渲染
"pageOrientation": "portrait", //横屏配置,全局屏幕旋转设置(仅 APP/微信/QQ小程序),支持 auto / portrait / landscape
"rpxCalcMaxDeviceWidth": 960,
"rpxCalcBaseDeviceWidth": 375,
"rpxCalcIncludeWidth": 750
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"height": "50px",
"fontSize": "10px",
"iconWidth": "24px",
"spacing": "3px",
"list": [{
"pagePath": "pages/component/index",
"iconPath": "static/image/icon_component.png",
"selectedIconPath": "static/image/icon_component_HL.png",
"text": "组件"
}, {
"pagePath": "pages/API/index",
"iconPath": "static/image/icon_API.png",
"selectedIconPath": "static/image/icon_API_HL.png",
"text": "接口"
}],
"midButton": {
"width": "80px",
"height": "50px",
"text": "文字",
"iconPath": "static/image/midButton_iconPath.png",
"iconWidth": "24px",
"backgroundImage": "static/image/midButton_backgroundImage.png"
}
},
"easycom": {
"autoscan": true, //是否自动扫描组件
"custom": {//自定义扫描规则
"^uni-(.*)": "@/components/uni-$1.vue"
}
},
"topWindow": {
"path": "responsive/top-window.vue",
"style": {
"height": "44px"
}
},
"leftWindow": {
"path": "responsive/left-window.vue",
"style": {
"width": "300px"
}
},
"rightWindow": {
"path": "responsive/right-window.vue",
"style": {
"width": "300px"
},
"matchMedia": {
"minWidth": 768
}
}
}
main.js是uni-app的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如vuex。
首先引入了Vue库和App.vue,创建了一个vue实例,并且挂载vue实例。
import Vue from 'vue'
import App from './App'
import pageHead from './components/page-head.vue' //全局引用page-head组件
Vue.config.productionTip = false
Vue.component('page-head', pageHead) //全局注册page-head组件,每个页面将可以直接使用该组件
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount() //挂载Vue实例
使用Vue.use引用插件,使用Vue.prototype添加全局变量,使用Vue.component注册全局组件。
可以引用vuex,因涉及多个文件,此处没有提供示例,详见hello uni-app示例工程。
无法使用vue-router,路由须在pages.json中进行配置。如果开发者坚持使用vue-router,可以在插件市场 (opens new window)找到转换插件。
注意
nvue 暂不支持在 main.js 注册全局组件
uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的编译器在webpack配置中特殊处理了这个uni.scss,使得每个scss文件都被注入这个uni.scss,达到全局可用的效果
注意:
如要使用这些常用变量,需要在 HBuilderX 里面安装 scss 插件;
使用时需要在 style 节点上加上。
创建项目启用uniCloud
对于老的uni-app项目,也可以对项目点右键,菜单中选择“创建uniCloud云开发环境”
新建uni-app项目的模板中,有一个Hello uniCloud项目模板,演示了各种云函数的使用。
uniCloud云开发环境创建成功后,项目根目录下会有一个带有云图标的特殊目录,名为“uniCloud”。(即便是cli创建的项目,云函数目录也在项目的根目录下,而不是src下)
非uni-app项目也可以通过使用云函数Url化来享受云函数的带来的便利
目录结构
HBuilderX 3.0起目录结构做了调整如下:
┌──uniCloud-aliyun 云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb
| |——— cloudfunctions 云函数目录
| | │───common 云函数公用模块目录 详情
| | | └──hello-common 云函数公用模块
| | | │──index.js 公用模块代码
| | | └──package.json 公用模块package.json
| | │───uni-clientDB-actions
| | │ └──new_action.js clientDB action代码 详情
| | └───function-name 云函数目录
| | │──index.js 云函数代码
| | └──package.json 包含云函数的配置信息,如url化、定时设置、内存等内容 详情
│ └──database 云数据目录
│ │──validateFunction 数据库扩展校验函数目录
│ │ └──new_validation.js 扩展校验函数代码 详情
│ │──db_init.json db_init.json初始化数据库文件,其中不再包含schema 详情
│ └──xxx.schema.json 数据表xxx的DB Schema 详情
根目录
#注意:uniCloud目录是存放服务端文件的目录,他和前端代码在同一个项目下这里只是方便管理。在发行前端部分,比如打包app、小程序、h5的代码包里并不会包含uniCloud目录。
HBuilderX 3.0之前版本目录结构如下:
┌──cloudfunctions-aliyun 云空间目录,阿里云为cloudfunctions-aliyun,腾讯云为cloudfunctions-tcb
| │───function-name 云函数目录
| | │──index.js 云函数代码
| | └──package.json 标准package.json
| │───common 云函数公用模块目录 详情
| | └──hello-common 云函数公用模块
| | │──index.js 公用模块代码
| | └──package.json 公用模块package.json
| │───uni-clientDB-actions
| │ └──new_action.js clientDB action代码 详情
│ │───db_init.json 初始化数据库文件 详情
│ └───cloudfunctions_init.json 云函数初始化文件 详情
│
根目录
uniapp中slot插槽的使用
插槽主要实现分发,当父组件引用带有插槽的子组件时,引用处的子组件内如有内容,当组件渲染的时候, 将会被替换
组件可以包含多个slot 用name区分
1.默认插槽的使用:
slot-one组件:
<template>
<view>
<view>我是子组件</view>
<slot></slot>
</view>
</template>
父组件引用slot-one组件:
<template>
<view class="slot-item">
<slot-one>
父组件插槽内容
</slot-one>
</view>
</template>
<script>
import slotOne from "./slot1.vue"
export default {
components: {
slotOne,
}
}
</script>
<style scoped>
.slot-item{
padding:50rpx;
}
</style>
2.插槽内可以包含任何模板代码,包括 HTML:
slot-one组件如上不变。
父组件引用slot-one组件:
<view class="slot-item">
<slot-one>
<text style="color:red">插槽内可以包含任何模板代码,包括 HTML</text>
</slot-one>
</view>
3.插槽内可以包含其它的组件,下面的内容来自slotTwo组件:
slot-one组件如上不变,slot-two组件:
<template>
<view class="slottwo">
<view>slottwo</view>
</view>
</template>
父组件引用slot-one组件,slot-one包含slot-two组件:
<view class="slot-item">
<slot-one>
<text style="color:red">插槽内可以包含其它的组件,下面的内容来自slotTwo组件</text>
<slot-two></slot-two>
</slot-one>
</view>
4.后备内容:
有时为一个插槽设置具体的后备 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染,
但是如果我们提供内容,则这个提供的内容将会被渲染从而取代后备内容
slot-one组件(带有默认值):
<template>
<view>
<view>我是子组件</view>
<slot>slot后备内容</slot>
</view>
</template>
父组件引用slot-one组件:
<view class="slot-item">
<slot-one>
</slot-one>
<slot-one>
<text style="color:red">提供的内容将会被渲染从而取代后备内容</text>
</slot-one>
</view>
5.具名插槽:
有时我们需要多个插槽, 元素有一个特殊的 attribute:name,语法: ,用来定义额外的插槽
一个不带 name 的 出口会带有隐含的名字“default”
在向具名插槽提供内容的时候,我们可以在一个 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称
v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header
v-slot 只能添加在 上 ,绑定在其他元素上用slot=“**”
slot-two组件:
<template>
<view class="slottwo">
<view>slottwo</view>
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</view>
</template>
父组件引用slot-two组件:
<view class="slot-item">
<slot-two>
<view>default:没有指定name的默认插槽的内容</view>
<template v-slot:header>
<text>header:我是name为header的slot</text>
</template>
<text slot="footer">footer:我是name为footer的slot</text>
</slot-two>
</view>
6.解构插槽 Prop:
绑定在 元素上的 attribute 被称为插槽 prop。
在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字
slot-three组件:
<template>
<view>
我是作用域插槽的子组件
<slot :user="user" :city="city"></slot>
</view>
</template>
<script>
export default {
data() {
return {
user: [{name: 'Jack',sex: 'boy'},{name: 'Jone',sex: 'girl'},{name: 'Tom',sex: 'boy'}],
city: [{name: '北京'},{name: '上海'},{name: '广州'}]
};
}
}
</script>
父组件引用slot-three组件:
<view class="slot-item">
<slot-three>
<template v-slot="{user,city}">
<view v-for="(item, index) in user" :key="index">
{{item.name}}
</view>
<view v-for="(item, index) in city" :key="index">
{{item.name}}
</view>
</template>
</slot-three>
</view>
7.示例:
todoList组件:
<template>
<ul>
<li v-for="todoitem in todos" :key="todoitem.id">
<!-- 我们为每个 todoitem 准备了一个插槽, 将 `todoitem` 对象作为一个插槽的 prop 传入。 -->
<slot name="todo" :todoitem="todoitem">
<!-- 后备内容 -->
{{ todoitem.text }}
</slot>
</li>
</ul>
</template>
父组件引用todoList组件:
<view class="slot-item">
<todo-list :todos="todos">
<template v-slot:todo="{ todoitem }">
<span v-if="todoitem.isComplete">?</span>
{{ todoitem.text }}
</template>
</todo-list>
</view>
data() {
return {
todos: [{
text: "aa",
id: "aa",
isComplete: true
}, {
text: "bb",
id: "bb",
isComplete: true
}, {
text: "cc",
id: "cc",
isComplete: false
}]
};
},
上一篇:uniapp快速回顾