微信小程序组件开发,打造更强大的小程序体验
1093
2022-09-11
Vue、 React 和 Angular 是当前应用最广的三大前端框架,仅从 GitHub 趋势来看,Vue 目前已经达到 17 万 Star,排在第一位。
目前,不管是 BAT 大厂,还是创业公司,Vue 都有广泛的应用,对于任何一个前端工程师来说,Vue 都是一门非常值得学习的前端框架。
但在国内小程序成为移动开发的破局者之后,Vue 的名字又经常和小程序关联在了一起,下面我们就一同探究两者之间的关系。
Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和 Vue 生态系统支持的库开发的复杂单页应用。
Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
上述是Vue官方网站给出解释,对于大部分用户读起来还是非常抽象和晦涩难懂的,看完之后可能还是不懂这个框架到底是用来做什么的,什么是“渐进式框架”?什么是“自底向上增量开发”?什么是“视图层”?什么是“单文件组件”?什么是“复杂的单页应用?”第二段话里面“响应的数据绑定和组合的视图组件”这又是个啥?
想必大家上网浏览新闻都是用APP或者网页,Vue.js就是一个用于搭建类似网页的表单项繁多、内容需要根据用户的操作进行修改的网页版应用。
单页应用一般指的就是一个页面就是应用,当然也可以是一个子应用,比如一个页面就可以视为一个子应用。单页应用程序中一般交互处理非常多,而且页面中的内容需要根据用户的操作动态变化。
现在我们把一个网页应用抽象一下,那么HTML中的DOM其实就是视图,一个网页就是通过DOM的组合与嵌套,形成了最基本的视图结构,再通过CSS的修饰,在基本的视图结构上“化妆”让他们看起来更加美观。最后涉及到交互部分,就需要用到JavaScript来接受用户的交互请求,并且通过事件机制来响应用户的交互操作,并且在事件的处理函数中进行各种数据的修改,比如说修改某个DOM中的innerHTML或者innerText部分。我们把HTML中的DOM就可以与其他的部分独立开来划分出一个层次,这个层次就叫做视图层。
这里的响应式不是@media 媒体查询中的响应式布局,而是指vue.js会自动对页面中某些数据的变化做出响应。至于是如何响应的,大家可以先把下面这段代码随便粘贴到一个扩展名为html的文件然后用浏览器打开,随便在文本框里面输入一些文字,观察一下页面变化。
做单页应用,页面交互和结构十分复杂,一个页面上就有许许多多的模块需要编写,而且往往一个模块的代码量和工作量就非常庞大,如果还按照原先的方法来开发,那么会累死人。而且遇到以后的产品需求变更,修改起来也非常麻烦,生怕动了其中一个div之后,其他div跟着雪崩,整个页面全部乱套,或者由于JavaScript的事件冒泡机制,导致修改一些内层的DOM事件处理函数之后,出现各种莫名其妙的诡异BUG。
在面向对象编程中,我们可以使用面向对象的思想将各种模块打包成类或者把一个大的业务模块拆分成更多更小的几个类。在面向过程编程中,我们也可以把一些大功能拆分成许多函数,然后分配给不同的人来开发。
在前端应用,我们是否也可以像编程一样把模块封装呢?这就引入了组件化开发的思想。
Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件(component)中,我们只要先在父级应用中写好各种组件标签(占坑),并且在组件标签中写好要传入组件的参数(就像给函数传入参数一样,这个参数叫做组件的属性),然后再分别写好各种组件的实现(填坑),然后整个应用就算做完了。
首先需要说明的一点Vue和小程序开发是没有直接关系的。
但是受到Vue的影响,以及Vue众多的开发者,不少组织将小程序二次开发,以类似Vue语法的形式进行小程序开发(最后通过自己的工具转成原生小程序的语法),比如美团的mpVue(Vue.js in mini program)。好处在于降低了Vue开发者学习小程序开发的成本,以及优化了很多小程序的不足点,例如小程序不能使用Npm,不能使用CSS预处理器,原生是callback语法等。
在理解如何基于Vue开发小程序后,那也可以顺着了解如何更好的发挥小程序价值,这就不得不提到 Hybrid 模式渐渐开始流行, Native + 小程序 的架构模式成为趋势,它解决了传统App带来的迭代不敏捷、代码量堆积、多平台维护等问题,同时又有远超 H5 的体验。
这里要推荐到的是已经在市场上比较成熟的小程序容器技术-FinClip,通过集成SDK便可让自己的APP快速拥有小程序运行能力。
此外,FinClip的视图层与逻辑层分离也带来了许多好处:
1、方便多个小程序页面之间的数据共享和交互。在小程序的生命周期中具有相同的上下文可以为具备原生应用程序开发背景的开发人员提供熟悉的编码体验;
2、Service和View的分离和并行实现可以防止JS执行影响或减慢页面渲染,这有助于提高渲染性能;
3、因为JS在Service层执行,所以JS里面操作的DOM将不会对View层产生影响,所以小程序不能操作DOM结构的,这也使得小程序的性能比传统的H5更好。
其中还有一点很值得推荐, 兼容微信小程序开发规范 。
也就是说,原来通过Vue开发的微信小程序也可以在不改代码的情况下,顺带手把这个小程序放在自己的 APP 里。同时,提供后台管理页面,可以统一管理自有和外部开发上架的小程序,以及对收集到的小程序数据进行分析。
全局安装
npm install -g @vue/cli 1
创建项目
vue create -p dcloudio/uni-preset-vue my-project 1
启动项目(微信小程序)
npm run dev:mp-weixin 1
微信小程序开发者工具导入项目
根目录
进入目录 再导入
建立完成
目录结构
┌─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 配置页面路由、导航条、选项卡等页面类信息,详见 1234567891011121314151617
pages.json
用来注册页面,排在第一的页面是首页
{ "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages //新增页面 { "path": "pages/index2/index", "style": { //页面名,呈现在小程序上方 "navigationBarTitleText": "2" } }, { "path": "pages/index/index", "style": { "navigationBarTitleText": "uni-app" } } ], "globalStyle": { "navigationBarTextStyle": "black", "navigationBarTitleText": "uni-app", "navigationBarBackgroundColor": "#F8F8F8", "backgroundColor": "#F8F8F8" } } 123456789101112131415161718192021222324252627
支持小程序的rpx 和 h5的vm,vh
内置有sass的配置了 ,只需要安装对应的依赖即可
npm install sass-loader node-sass
sass版本和Node版本对应关系
如果出现版本报错,移步:
https://blog.csdn-/xiakekeali/article/details/112766575
1
vue组件中,在style 标签上加入属性 <style>
即可
index2/index.vue
<template> <view> <view>rpx</view> <view>rpx</view> <view>sass</view> </view> </template> <script> export default { } </script> <style> .rpx{ /* rpx 小程序中的单位 750rpx = 屏幕的宽度 */ width :750rpx; height: 100rpx; background-color:aqua; } .vw{ /* vm h5单位 100vw = 屏幕的宽度 100vh = 屏幕的高度 */ width:50vw; height: 50vh; background-color: tan; } .content{ .sass{ background-color:red; color:$uni-color-primary; } } </style> 12345678910111213141516171819202122232425262728293031323334353637
效果图
在js的data中定义数据
在template中通过{{}}来显示
在标签的属性上通过 :data-index=‘数据’ 来使用
<!-- 使用数据 --> <view>{{msg}}</view> <view>{{money}}</view> <view>{{isRich}}</view> <view>{{person}}</view> <view>{{person.name}}</view> <view>{{person.skill}}</view> <!-- 标签上通过属性的方式使用数据 --> <view :data-color="color">color</view> <script> export default { data(){ return{ //存放数据 msg:"黑马程序员", //数字 money:100, //boolean类型 isRich:false, //对象 person:{ name:"孙悟空", skill:"72变" }, //颜色 color:"auqa", //数组 list:[ { id:0, text:"苹果" } , { id:1, text:"🍌" } , { id:2, text:"🚗" } ] } } } </script> 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
结果
通过v-for来指定要循环的数组
item 和 index 分别为 循环项 和 循环索引
:key 指定唯一的属性,用来提高循环效率
<template> </template>
中
<view>==========================</view> <view v-for="(item,index) in list" :key="item.id"> {{item.id}} -- {{item.text}}-- {{index}} </view> 123456
<script> export default { data(){ return{ //数组 list:[ { id:0, text:"苹果" } , { id:1, text:"🍌" } , { id:2, text:"🚗" } ] } } } </script> 12345678910111213141516171819202122232425
运行结果
通过 v-if 来决定显示和隐藏 不适合做频繁的切换显示
通过 v-show 来决定显示和隐藏,适合做频繁的切换显示
<template> </template>
中
<view>==========================</view> <view> <view v-if="true">v-if </view> <view v-show="false">v-show</view> </view> 123456
效果
可以理解为是对 data中的数据提供了一种加工或过滤的能力
通过computed 来定义计算属性
示例1 实现功能 输出 ¥1000
<template> </template>
中
<view>$ {{money}}</view> <view>{{cnMoney}}</view> 1234
<script> export default { data(){ return{ money:100 } }, //计算属性 computed:{ //直接把 cnMoney看成是再data中的普通的数据一样来使用即可 cnMoney(){ //$ 1000 return "$"+ this.money; } } } </script> 1234567891011121314151617
示例3 实现功能 ,过滤掉数组id大于0的内容
<template> </template>
中
<view> <view v-for="(item,index) in filterList" :key="item.id"> {{item.text}} -- {{index}} </view> </view> 1234567
<script> export default { data(){ return{ list:[ { id: 0, text:"苹果" } , { id: 1, text:"🍌" } , { id: 2, text:"🚗" } ] } }, //计算属性 computed:{ //过滤数组 filterList(){ //只要id > 0 都不要 return this.list.filter(v=>v.id<= 0); } } } </script> 123456789101112131415161718192021222324252627282930313233
结果
v-for 和 v-if 不建议一起使用,建议用computed
注册事件 @click = “handleClick”
定义事件监听函数 需要在 ”methods“中定义
事件的传参
如何拿到标签中的属性
<template> <view> <view data-index="11" @click="handleClick(1,$event)">点击我试试1</view> <view data-index="22" @click="handleClick(2,$event)">点击我试试2</view> </template> <script> export default { methods:{ handleClick(index,event){ console.log(index); console.log(event); } } } </script> 123456789101112131415
那么如何调用属性中自定义的index呢??
handleClick(index,event){ console.log(index); console.log(event); console.log(event.currentTarget.dataset.index); } 12345
组件的定义
在src目录下新建文件夹components 用来存放组件
在 components 目录下直接新建组件 *.vue
组件的引入
在页面中 引入 组件 ”import 组件名 from ’组件路径‘ “
组件的注册
属性 components是一个对象,把组件放进去注册
组件的使用
在页面的标签中,直接使用引入的组件 ”<组件></组件>“
定义
<template> <image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.yygx-%2FfileYYGX%2Fjournal%2Farticle%2Fyygx%2F2020%2F3%2F9257-1.jpg&refer=http%3A%2F%2Fwww.yygx-&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1640596226&t=6b86c267d92c15be48a1816dc1a005d7"> </image> </template> <script> export default { } </script> <style> .img-border{ border-radius: 50%; } </style> 123456789101112131415161718
引入-注册-使用
<template> <view> <!-- 4 使用组件 --> <img-border></img-border> </view> </template> <script> //2 引入自定义组件 import imgBorder from "@/components/img-border" export default { //3 注册组件 components:{ imgBorder } } </script> <style> </style> 123456789101112131415161718192021222324
效果
父向子传递参数 通过 属性 的方式
子向父传递参数 通过 触发事件 的方式
通过全局数据传递参数
通过 挂载 vue 的原型上
通过 globalData 的方式
父页面向子组件 ul-com 通过属性名 list 传递了一个数组数据
子组件 通过props 进行接收数据
结果
子组件通过 触发事件 的方式向父组件传递数据
父组件通过 监听事件 的方式来接收数据
通过 Vue 的原型共享数据
通过 globalData 共享数据
vuex(未讲)
本地存储(未讲)
假如想项目一启动时,就做一些定义数据
就可以找到main.js
App.vue中定义
标签其实也是数据的一种,想实现动态的给子组件传递 标签, 就可以使用插槽 slot
通过slot 来实现占位符
my-form.vue
<template> <view> <view>标题</view> <view>内容</view> </view> </template> <script> export default { } </script> <style> </style> 123456789101112131415
index6/index.vue
<template> <view> <my-form> <view> <input type="text"> <radio></radio> <checkbox></checkbox> </view> </my-form> </view> </template> <script> import myForm from "@/components/my-form" export default { components: { myForm }, } </script> <style> </style> 12345678910111213141516171819202122232425262728
text文本框并没有显示出来, 这就需要在组件里面写一个占位符(即插槽)
uni-app框架的生命周期结合了 vue 和 微信小程序的生命周期
全局的APP中 使用 onLaunch 表示应用启动时
页面中 使用 onLoad 或者 onShow 分别表示 页面加载完毕时 和 页面显示时
组件中使用mounted组件挂载完毕时
应用 指的是 App.vue
页面
组件
结果
uniapp生命周期详解链接
https://uniapp.dcloud.io/frame?id=%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f
微信生命周期
vue生命周期
终端运行
npm run dev:mp-weixin
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~