前提,建议先学会前端几大基础:HTML、CSS、JS、Ajax,还有一定要会Vue!(Vue2\Vue3)都要会!!!不然不好懂
一、去哪写?
就在【pages】的你的人一个页面文件夹里的【.vue】文件里的【<script> </script>】开始写
注意:
如果你用的是基于vue3版本语法,那么就不用uniapp自带的模板,把export default { ... }删掉,在<script>加上setup,然后再写
如果你还是用vue2版本的语法,那么就按uniapp模板自带的,在有export default { ... }包起来的区域,在这里面写
二、利用插值表达式把vue的数据渲染到HTML部分
插值表达式就是双花括号:{{ }}
然后插值表达式可以是变量、可以是函数(别忘了小括号( ))、可以是三元运算表达式、可以是对象表达式
三、利用ref定义响应式数据变量
首先回顾一下,在vue2里出现过这个ref,是用来获取具体某个组件内的DOM元素的(也就是比document.querySelector( )更精确 )
用法就是在DOM元素里加上【ref=" xxx "】,然后在vue语法区域写【this.$refs.xxx】就可绑定成功(注意,vue里的$refs后面必须跟DOM里的ref名字一样)
那么现在回到vue3,这里的ref是作为响应式数据的一个对象
当他用来绑定获取DOM元素的时候,语法差不多,只不过:
1、ref需要用import引入
2、用一个变量=ref()就行,但是这变量要和DOM元素的ref名字一样
3、要在【生命周期的挂载时期里用】(后面讲)
当他用来渲染响应式数据时:
我们都知道如果你直接在HTML部分用{{ }}绑定了vue的一个变量,但是这个变量不是在data里写的话,它在vue里面变化的时候HTML部分并不会跟着变化
那么使用data挂在数据去返回的方法是vue2版本的语法
如果不用vue2的话,那么vue3语法里可以用ref,ref可以把vue里变量变化——HTML那里也跟着变化
第一步:引入ref对象
第二步:用变量等于ref,ref对象括号( )里传入值
注意:此时这个变量还不是值,只是一个包含该值的对象!!!
那么要用值,只需要写成【对象.value】就行了
但是这里注意区分一个误区
1、在HTML部分的{{ }}直接绑定变量名字就行!
比如:<view> {{ num }} </view>
2、但是在script区域vue代码里,“变量名”是一个对象,要用“变量名.value”才行!
比如:let num = ref(1)
console.log( num.value )
普通变量也行、字符串也行、对象也行
至于底层原理先不讲,我们也用不不到
四、vue的v指令
其实学习uniapp之前就应该学完了或者多多少少学一半vue了,那么这一块也会尽量简单讲一下,不多说
1、v-bind指令改变标签的属性、类名、样式
写法:
【v-bind:属性 = "xxx"】这就是改变标签属性
比如:v-bind:title = "xxx"、v-bind:value = "xxx"......
还可以简写,去掉v-bind,直接写【:属性 = "xxx"】
比如::title = "xxx"、:value = "xxx"......
稍微提一下两个要注意的:
(1)利用v-bind搭配动态获取image的图片路径
前面说了要动态获取image的src图片路径的话,就需要用v-bind,注意!!!只能用v-bind!!!以前习惯vue语法的可能会习惯用插值表达式:<image scr="{{ item.src }}">,错!直接报错!!只能用v-bind来获取:<image :scr=" item.src ">
然后图片路径那边除了用require( )装起来,也可以用ref( ),根据自己喜好来,反正就是不能直接拿图片路径:
(2)要利用v-bind来修改标签的属性
v-bind可以修改属性,比如控制输入框至少输入1个字符的时候,按钮才可以点
那么要注意true和false这两个布尔值,不能直接当成“属性值”来写。比如我们前面学的像button的属性:loading、disabled,你只是写上去一个单词的形式,就默认是这样:loading = "true"、disabled = "true"
但其实我们要是真这样写是不对的,比如我们要是想改成false,系统会把false当成一个“字符串”而不是一个“布尔值”!!要用v-bind来把它变成布尔值
(3)利用v-bind添加类名样式
假设定义一个样式类名叫active
那么我们可以静态写死一个标签获取这个样式
也可以用v-bind获取
但是注意!!不能直接写v-bind:class="类名",会报错
要用''单引号把类名包起来,这样才是一个字符串形式
错!
对!
但是这还是写死的,要想动态判断获不获取这个类名,就要用【对象表达式】或【三元表达式】
对象表达式那意思就是:判断isActive变量是true还是false,true就获得active,false就不获得active类名
三元运算表达式就是:直接判断"?"前面是true还是false,true就获得active类名,false就获得“空字符串”也就是啥也没有
(4)v-bind修改样式
你想用v-bind修改style样式可不能直接:【v-bind:style = "width:100px"】
记住只要用了【v-bind】,“ ”双引号里的语法就应该写成js代码,那么我们修改样式就应该写成一个对象形式:【v-bind:style = "{ width: '100px' }",别忘了值要写成字符串!那么就要用' '单引号包起来!!
另外带“-”的样式属性需要想JS一样遵循“小驼峰”原则:
2、v-on指令(@时间指令)
我不多说了,v-on事件指令 = @事件指令,怎么用我也不多说了
就简单讲一下跟vue不太一样的一些注意点
原先我们学习JS知道了一些事件的名称,但是学习微信小程序的时候发现不一样,比如:
【click点击事件】在微信小程序里是【tap事件】(而且要带上bind,完整写法bindtap)
【mouseenter鼠标移入事件】对应的是【touchstart触摸开始事件】(bindtouchstart)
【mouseleave鼠标移出事件】对应的是【touchmove移动触摸点】(bindtouchmove)
还有一些:触摸结束(bindtouchend)以及长按事件(bindlongtap)......
不过tap事件和click事件,在uniapp里已经都归为click事件,他会自己转化成tap,因此你用@tap、@click都是可以的
下面是一些uniapp移动端事件对应的名字:
// 事件映射表,左侧为 WEB 事件,右侧为 ``uni-app`` 对应事件{click: 'tap',//点击事件touchstart: 'touchstart',//手指移入touchmove: 'touchmove',//手指移出touchcancel: 'touchcancel',//停止跟踪触摸时触发,不常用可以不记touchend: 'touchend',//触摸结束tap: 'tap',//也是点击事件longtap: 'longtap', //手指长按事件 //推荐使用longpress代替input: 'input',//输入事件change: 'change',//输入内容、表单元素改变事件,不会连续触发,只有当全部修改完成时才会触发submit: 'submit',//发生在表单对象<form>上,提交表单所有数据时的事件blur: 'blur',//失焦事件focus: 'focus',//聚焦事件reset: 'reset',//发生在表单对象<form>上,当表单重置(所有表单成员变回默认值)时触发confirm: 'confirm',columnchange: 'columnchange',linechange: 'linechange', //后面这些不常用,自己可以查查error: 'error',scrolltoupper: 'scrolltoupper',//屏幕向上滚动scrolltolower: 'scrolltolower',//屏幕向下滚动scroll: 'scroll'//屏幕滚动事件}
另外不同组件有对应着不同的事件,比如你<checkbox>复选框、sumbit开关选择器(这些组件可以去官方文档自己看组件使用的入门教程 | uni-app官网)肯定对应的只有@change改变事件了,你总不能让他两触发@click或者@scroll事件吧?人家没有这种事件啊......
也还是一样,去官方文档组件使用的入门教程 | uni-app官网,看每一个组件的【属性】,最底下会有对应的,比如:
swipper组件
from组件
input组件
多的不说了,自己去查
另外注意,绑定空参函数的时候" "双引号直接写函数名,传参的时候" "双引号里写函数名+( )
然后跟JS一样,每触发一个事件就会返回一个event事件对象,那么就可以根据这个事件对象获取有用的值进行一些操作,比如:
<!-- 给swith开关绑定一个改变事件 -->
<switch @change="onChange"></switch><script setup>//当swith开关组件改变开或关的状态时,会执行这个函数function onChange(e){//会返回一个事件对象e,然后e.detail.value,就是代表swith的change事件的状态console.log(e.detail.value)}
</script>
那么甚至可以根据一个组件的事件去影响另一个组件
套路就是:
1、在触发第一个组件事件的函数里传入事件对象,用一个变量去获取事件对象里的信息(别忘了让这个变量成为响应式变量,要么用data挂载,要么用ref( ) )
2、然后再让第二个组件通过【v-bind指令】通过这个变量去改变自己的属性
3、v-if、v-show指令,判断条件渲染组件
语法不用多说,它两是一个东西,跟if-else语句一样,自己看看就行
有一点v-if和v-show不一样,就是隐藏组件元素的方式不一样:
可以发现前者是完全隐藏,而后者会把资源加载过来,通过dispaly:none来决定它出现还是消失,那么如果有图片的话,v-show会把图片资源加载过来,会耗用一点资源,但是更换频繁的时候用它速度更快;而v-if则适合使用频率少的
最后补充:要让一块消失、出现,除了用view容器包起来,还可以用<template>结构容器,<template>的好处就是他不会作为一个实体的父容器,他只是一个结构,在网页检查可以看到他根本不存在
template的好处还有,在ul里包裹li的如果是别的容器,就会破坏ul它的结构导致出错,而用template包裹就没事了,就可以控制每个li的出现、隐藏
4、v-for循环遍历数组
这个更简单我也不打算说了,反正用它你就不用写一堆同样的元素
比如:几千几万条评论,你不看可能真的写几千几万个“评论区的HTML盒子代码吧”
只需设置一个“HTML评论盒子代码”,然后直接根据vue的data返回的动态数据,有获得的数组里几个评论,就遍历显示几个“HTML评论盒子”就行了
然后记住要用到数组下标的话就要写成【v-for=" (item, index) in 数组 "】,item在前index在后,别搞混了;另外一定要带上【v:key="索引"】(如果返回的是对象数组,里面有id索引就用id索引,没有就用v-for自带的index,不然会报错,具体原因学习数据库就知道了)
数据的数组你用ref也行(下面只是两个不相关的ref和data的形式例子)
用data也行
那么这里讲一下一些网站的“删除盒子、元素”功能是怎么实现的,添加和删除DOM元素本质就是【对数组进行添加、删除】,那么利用【数组.push( )】或【数组.splice( )】就能实现了
记住了数组添加用push(),删除用solice(),用ref的变量记得带上【变量.value】形式再用这两个函数
当然前面我说了:key可以设置为index,但是这是针对不报错的做法,index毕竟是一个会变得变量;那么假设我的需求是当我进行增删操作的时候,始终是选中一个元素,比如下面这个例子:我想在选中一个元素之后,不管我删了哪几个元素,√都一直选中刚刚我选的那个元素
这样的话,假若我选了index为1的元素(也就是第2个),当我删了index为0的元素(第1个),那么刚刚index为1得元素就会到第一位,index变为0
但是因为刚刚我传的index是1,:key="index"认为被选中打√的元素是index为1的,所以此时“√”会跑到刚刚被打“√”的下一位,说得可能你们都懵逼了,看一下例子
只有这样绑定了自定义每个元素的id,这样才是对的
5、最后最简单的v指令:v-model数据双向流通
在【表单元素】加入之后,表单元素更改、输入这些操作,都能把表单元素的【值】给到vue,而同时vue里对数据的更改也能传给表单元素,实在没什么好细说的,不会的真要去学一下vue再来看uniapp
五、一些API函数、属性
1、computed计算属性
在Vue脚手架开发里应该学过computed计算属性,可以去我这篇文章看一下:Vue全家桶:vue2+vue3全部搞懂:第四篇,Vue的计算属性,高效执行运算-CSDN博客,不过这是针对vue2版本语法的解释
这里再讲一次,针对vue3版本,下面有几点要注意:
第一、computed计算属性是一个属性!所以要在HTML的{{ }}绑定的时候直接用computed计算属性的变量名,不用像函数那样带( )
第二、computed计算属性里是一个函数,这个函数就是return回一个计算结果,以作为这个计算属性的值。(用ref的变量计算的时候,别忘了写.value)
第三、跟vue2不一样的是,vue3语法里必须要import { computed } from "vue"才能用
当然用函数方法也可以实现它的功能(函数别忘了带( ))
那么普通函数和computed计算属性有什么区别?
computed只会执行一次,他会把值加载好保留,下次用的时候直接给结果,而不是再次执行运算
普通方法函数则是你调用几次,他就执行几次函数运算
简单结合案例巩固一下理解
例子:几个商品复选框,选中谁就依次累加商品的价格
这里注意一个点:checkbox必须设置value值,不然的话获取不到对应的数据值
而且value必须是String字符串类型
修改后
然后接下来把@change事件绑定的函数里,把获取到checkbox的事件对象的value给到一个空数组里
然后通过计算属性获得数组长度,就完成了统计个数的这一步
(或者简单点直接在{{ 写selectGroup.length }}就行)
接下来给每个对象数据多添加一个属性,来标记这个checkbox复选框有没有被选中
然后这里的逻辑是在@change事件的函数里遍历整个原数组
然后判断在被选中的checkbox复选框中有没有当前这个成员(例子里的selectGroup.value就是指已经被选中的checkbox复选框的value组成的一个数组),通过includes( )函数判断有就true,没有就false;
然后就能让每一个成员的checked这个“标记属性”的值去等于判断的结果,也就是标记每个成员当前是被选中了还是没被选中
如果没懂给这些函数的可以去看我这一篇:JS的一些方便遍历数组的API函数-CSDN博客
最后根据被选中的来计算商品价格总数:
展开来是这样:
也就是通过filter( )函数过滤了原数组里没有被选中的checkbox的值,然后装到一个新数组,在对这个数组使用reduce( )函数统计总数,最后通过computed计算属性给到HTML
2、watch监听函数
这个我也在Vue脚手架项目开发里讲过:Vue全家桶:vue2+vue3全部搞懂:第五篇,Vue的watch监视器_vue2 监视器-CSDN博客,这是针对vue2版本的写法
可以去看看,这里借用一下我那篇文章的截图:
他就是监听一个元素的变化,有点像在表单元素的v-model,但是它是具体针对某一个变量、一个元素的变化的监听
现在讲一下针对vue3版本的用法:
watch( )对一个普通元素的监听:watch(参数1,参数2),参数1就是要监听的元素变量名,参数二是一个回调函数
这个参数2回调函数有两种形式:
1、回调函数(参数1,参数2)
这样的话会自动获取【这次改变的值】和【上一次的值】,参数1就是【这一次改变了的值】,参数2反之
2、回调函数(参数)
一个参数就是自动获取实时更新的值(上一个写法了解就行,没人用)
watch( )对对象的内部值变化的监听:
当我们对一个对象的内部值监听的时候,是不能直接把第一个参数写成【对象.属性】的
第一种方法:第一个参数写成回调函数,return【对象.value.属性】
第二种方法:开启深度监听!多加一个第三个参数,第三个参数是:{ deep:true }
这第三个对象参数就是一个用了加配置项的参数
那么watch不会立即自动监听,只有元素发生改变了才会监听;
如果想要一进页面就自动监听,在第三个参数里再加一个配置项:{ immediate: true }
当然还有一个了解一下,用的不多:watchEffect( )
它可以直接监听所有元素的变化
六、Vue3的生命周期和八大钩子函数
我之前的某篇文章里讲过vue2的生命周期和八大钩子函数,不了解的可以去看一下回顾:
Vue全家桶:vue2+vue3全部搞懂:第六篇,了解Vue生命周期,如何一进页面就马上发送请求、渲染页面-CSDN博客
这里简单带大伙过一遍生命周期
那么根据vue3的官方文档给出的生命周期以及各个时期的钩子函数,如下图所示:
可以注意到最开始的有一个setup函数,然后我们vue3的语法里也要在<script>里加上一个setup,这是vue3里比原来vue2里的beforeCreate更早的一个生命周期函数,当然vue3也删掉了【beforeCreate】和【created】,那么【setup】也就相当于代替了它两
然后vue官方文档:组合式 API:生命周期钩子 | Vue.js讲了vue3的具体几大生命周期函数
不过注意!!在uniapp种有一些是不支持的,所以不用全记,比如:在uniapp组件中,onBeforeUpdate、onUpdated、onActivated、onDeactivated,H5支持,小程序无法使用。
那么vue2和vue3有啥区别?盗用一下咸虾米博主的文章,看一下vue2和vue3生命周期钩子函数的区别:
那么看一下uniapp里一些常用的生命钩子的例子
用法统一:import { 生命周期钩子函数 } from "vue",然后再用
onMounted
DOM元素挂载阶段生命钩子函数,有他才可在vue里获取DOM元素
比如下面,没onMounted的时候,获取失效
有onMounted获取成功
onUnmounted
DOM元素被销毁阶段
比如下面例子,某个自定义组件里设置被销毁的时候提示“子组件被销毁了”,然后在父组件里设置一个定时器,多短时间销毁它
七、页面生命周期
前面讲的主要都是组件的生命周期,那么页面也有生命周期
uniapp页面生命周期函数与 Vue.js 的生命周期函数有所不同,因为 uni-app 是基于 Vue.js 的跨平台应用框架,因此它具有自己特定的生命周期函数。
可以在这些生命周期函数中编写相应的逻辑代码,以便在不同阶段对页面进行初始化、展示、隐藏和卸载时执行特定的操作。
那么页面有哪些生命周期钩子函数?
其他常用的生命周期,可以看官方发文档,页面生命周期函数
页面生命周期钩子函数的用法:
页面生命周期钩子函数是不能直接像vue2的选项式API一样,vue2可以直接使用onLoad、onShow等,而uniapp的vue3中需要先从“@dcloudio/uni-app”模块中导入才可以。
比如
那也不能像组件的钩子函数一样,直接一个import { } from "vur"就能用的
而是【import { 页面钩子函数 } from "@dcloudio/uni-app"】
onLoad
页面一进来就发生执行的钩子函数,其实它是属于setup阶段的
例子:
(这是首页面,点击navigator跳转到另一个页面,并给这个页面发送参数)
跳转到这个页面后,页面接收到参数,马上立即自动输出
onReady
当页面DOM元素加载完毕、资源请求加载准备完毕后就执行
跟组件生命周期的钩子函数onMounted差不多一个意思
onShow
跟onLoad差不多,它夹在onLoad和onReady之间
那么它跟onLoad最大的区别就在于
onLoad是页面加载时立刻执行,但是只要页面没被销毁,onLoad就永远只执行一次
(页面被销毁简单理解就是完全关掉,或者再次从别的页面跳转回来;如果你从这个页面跳转到另一个页面,然后点击返回又回去了,这个页面就没有被销毁)
而onShow是只要页面没销毁,一到页面就执行一次
onHide
页面一离开就触发执行
有啥用?比如视频播放的时候,有消息弹出,那你点击消息啥的离开了页面,视频就停止,等你一返回又继续自动播放......等等
补充一下:
App.vue还有全局的配置,这三个作用全局的生命钩子函数优先级更高
onUnLoad
页面完全卸载了,叉掉了,或者你那个navigator设置的open-type是relaunch(也就是跳转过后返回不了了),那么就会执行
onPageScroll页面滚动钩子函数
页面滚动就自动触发
案例:往下拉出现一个盒子,往上拉消失
或者
八、最后讲一下生命周期的钩子函数执行的顺序
不包含组件的页面
onLoad > onShow > onReady
包含组件的页面
onLoad > onShow > onBeforeMount > onReady > onMounted