您现在的位置是:网站首页> 小程序设计

uniapp重头到尾

摘要

uniapp快速回顾

页面传值

每个页面保存页面对象便于其他地方使用

条件编译uniapp直接调用微信小程序api

uniapp原生tabbar设置并添加数字角标或小红点提示

页面跳转

uniapp的目录结构

本地HTML文件

App.vue

全局变量机制。这套机制在uni-app里也可以使用,并且全端通用

全局样式

pages.json页面路由

main.js

uni.scss

uniCloud

uniapp中slot插槽的使用



页面传值

//在起始页面跳转到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

});


uniapp的目录结构

┌─uniCloud              云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud)

│─components            符合vue组件规范的uni-app组件目录

│  └─comp-a.vue         可复用的a组件

├─hybrid                App端存放本地html文件的目录,详见

├─platforms             存放各平台专用页面的目录,详见

├─pages                 业务页面文件存放的目录

│  ├─index

│  │  └─index.vue       index页面

│  └─list

│     └─list.vue        list页面

├─static                存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此

├─uni_modules           存放[uni_module](/uni_modules)规范的插件。

├─wxcomponents          存放小程序组件的目录,详见

├─main.js               Vue初始化入口文件

├─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 '包名'


本地HTML文件

─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>

platforms

条件编译  /* #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快应用华为


App.vue

应用生命周期

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中即可

pages.json页面路由

样例

{

"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

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

uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的编译器在webpack配置中特殊处理了这个uni.scss,使得每个scss文件都被注入这个uni.scss,达到全局可用的效果

注意:


如要使用这些常用变量,需要在 HBuilderX 里面安装 scss 插件;

使用时需要在 style 节点上加上。

uniCloud

创建项目启用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

        }]

      };

    },


Top