小程序设计二

八、使用背景图片(background-image)

注意:

  • url不能指定为本地地址
  • 可以将图片转化为base64方式使用。
  • 使用网络地址:
background-image: url(https://img1.baidu.com);

考虑到版权问题,这里没有放具体路径。

  • 使用base64格式指定(不推荐,因为base64过长)

推荐转换网站(图片在线转换Base64 | 图片编码base64)

九、事件系统

(一)事件绑定和事件对象

A、事件绑定

小程序中绑定事件跟网页开发中绑定事件几乎一致。小程序绑定事件不用on也没有click事件,分别被bind关键字和tap事件来代替。绑定事件的调用函数,要写在页面的js文件的page方法的对象中。绑定事件方式有两种:

  1. bind:tap
  2. bindtap
  • 创建按钮和输入框,分别绑定点击事件和输入事件事件
<!--事件绑定-->
<button type="primary" size="default" bind:tap="consoleInfo">触发事件</button>
<input type="digit" bindinput="consoleInfo"/>
  • 对应处理函数
//测试事件绑定
  consoleInfo(event){
    //自动传入事件对象参数
    console.log("事件被触发了!");
    let num = event.detail.value;
    if(num != null){
      console.log(num);
    }else{
      console.log("没有数据!");
    }
  }

知识点:小程序为了统一,button组件的type中仅有两个值:primary、warn,一个绿色一个红色。

B、事件对象

在事件被触发时,事件对象会默认传到函数形参中,事件对象中包括关于事件的各种数据,包括事件传递的参数。

下面是大概的解释:

detail存入触发事件的坐标值(x,y)、input框输入值(value)
dataset(该属性在target,或者currentTarget属性下)参数值(属性名)
crrentTarget事件的绑定者,意为绑定了当前事件处理函数的组件。
Target事件的触发者,意为触发了当前事件处理函数的组件。

一般情况下:currentTarget和Target一致,即事件的绑定者和触发者一致,但是也存在特殊情况,二者不一致。

  • 绑定者和触发者分离 (通过事件冒泡方式触发)

C、事件冒泡

当有如下结构时:

<view bind:tap="consoleInfo">
<button type="primary" size="default" bind:tap="consoleInfo">触发事件</button>
</view>

当点击button时,触发自己事件后,会冒泡触发view的绑定事件。

  • 在这里
    • currentTarget 是button
    • target是view
  • 如何截断事件冒泡
    • 改bind:事件名 ----> catch:事件名

D、参数传递

(1 )使用data-*传递参数,*代表属性名,value是属性值
  • 参数传递方
<button  catch:tap="consoleInfo" data-name="路飞" data-age="23">触发事件</button>
  • 参数接收端
consoleInfo(event){
    //自动传入事件对象参数
    console.log("事件被触发了!");
    //获取组件传递数据
    console.log(event.currentTarget.dataset.name);
  }
  • 注意点:
  1. 当属性名涉及多个单词时,使用-连接,如:data-my-name,则在event对象中就为myName
  2. 如果为:data-myName,则event对象中自动转化为小写data-myname。
(2)使用自定义属性传递参数(mark)
  • 参数传递方
<button  catch:tap="consoleInfo" mark:name="路飞"mark:myAge="22">触发事件</button>
  • 参数接收方
//测试事件绑定
  consoleInfo(event){
    //自动传入事件对象参数
    console.log("事件被触发了!");
    //获取组件传递数据
    console.log(event.mark.name);
    console.log(event.mark.myAge);
  }

通过冒泡等触发的事件,定义的相关属性都会被保存在mark中。

重名属性,以最内层属性为主。

十、wxml语法

(一)声明和绑定数据

A、声明数据

在 页面.js 文件中的page中声明data并指定数据:

  data:{
    name:'杨旭',
    age: 23,
    lover: '天治国'
  }

然后再wxml中使用双括号语法,绑定数据:

<text class="{{lover}}">{{name}}</text>

双括号中可以使用:表达式 逻辑运算 判断 三元运算

不可以使用:jsAPI 语句

B、修改数据

  • 修改单属性

在方法中调用this.setData即可:

<button bind:tap="changeName">修改姓名</button>
 changeName(){
    this.setData({
      name:"天将"
    })
  }

这样修改数据会动态将更新后的结果响应到页面上(响应式的),直接赋值则不是响应式的。

  • 修改对象类型
data:{
    name:'杨旭',
    lover:"和之国",
    go:{
      name:"end",
      age: 20,
      body: "白皙"
    }
  }

方法一: 

changeGo(){
    this.setData({
      'go.name':"天降无双",
      'go.age':22
    })
  }

方法二:利用Object的assign方法,来合并对象,后面参数的对象在属性相同时,会覆盖前面参数的对象的属性,不一样则添加。

changeGo(){
    let newGo=Object.assign(this.data.go,{name:"未来未来",age:34,head:'头颅生光'});
    this.setData({
      go:newGo
    })
  }

方法三:利用展开运算符

changeGo(){
    let go = {
      ...this.data.go,
      name:"花间可",
    }
    this.setData({
     go //触发属性简写形式。
    })
  }

方法四:利用结构赋值删除对象属性

changeGo(){
   let {name,...rest} = this.data.go;
   //意为将go对象中name属性赋值到name,其他属性都赋值给rest对象,这样就巧妙删除了name属性。
    this.setData({
     go:rest
    })
  }
  • 修改数组类型

方式一:

<text wx:for="{{myList}}" wx:key="index">{{item}}</text>
<button bind:tap="changeGo">修改list</button>

结构上要使用循环实现。

data:{
    myList:[1,3,5,5,4,5],
  },
  changeGo(){
     let myList = this.data.myList.push(4);
     //压入数组后赋给原值
    this.setData({
     myList
    })
  }

方式二:展开运算符,附新值然后再用setData赋值

changeGo(){
    let myList = [...this.data.myList,7]
    this.setData({
     myList
    })
  }

方式三:splice方法(删除数组元素)

changeGo(){
    this.data.myList.splice(1,1);

    this.setData({
     myList:this.data.myList
    })
  }

方式四:使用过滤实现filter

changeGo(){
   let oldList = this.data.myList.filter(item => item != 5);
    this.setData({
     myList:oldList
    })
  }

方式五:修改指定下标元素的值

changeGo(){
    this.setData({
     'myList[4]':78
    })
  }

C、双向绑定数据

双向绑定数据就是指,当页面数据发生改变时,也会影响到后台数据的改变。

方法:要双向绑定属性前加:model:

  • input绑定数据
<input model:value="{{num}}"/>
data:{
    num:34
  }
  • 复选框绑定数据
<checkbox model:checked="{{isSelected}}"></checkbox>
data:{
    isSelected: false
  }

注意

  • 只能是一个单一字段的绑定,双引号中不能使用其他内容,错误示范:
<input model:value="值为{{num}}"></input>
  • 不能写data路径,即不支持数组和对象的双向绑定,错误示范:
<input model:value="{{end.num}}"></input>

 (二)列表渲染

通过循环遍历一个数组或者对象,将其中每个元素渲染到页面上。

在组件中使用wx:for属性绑定一个数组或者对象,即可每一项数据重复渲染当前组件。

每一项默认为item,下表变量名为index。

注意:在添加wx:key时不需要使用双括号包裹。如果确定列表为静态的,可以不添加wx:key属性。

A、渲染列表和对象

data:{
   furitList:[
     {id:1,name:'苹果'},
     {id:2,name:'香蕉'},
     {id:3,name:'梨子'}
   ]
  }
<list wx:for="{{furitList}}" wx:key="id">{{item.name}}</list>
data:{
   furitList:[
     2,234,'冲天香'
   ]
  }
<list wx:for="{{furitList}}" wx:key="index">{{item}}</list>

 index在遍历对象时,是对象的各个属性名,在遍历数组时是下标

当遍历对象时,wx:key中可以直接指定对象的属性名。

当item本身就具有唯一性时,可以直接在wx:key中使用*this指定自身,如下:

data:{
   furitList:[
     2,3,5
   ]
  }
<list wx:for="{{furitList}}" wx:key="*this">{{item}}</list>

 B、修改默认、同时渲染一个item到多个组件

使用:wx:for-item指定每个元素名称;wx:for-index指定下标或者属性名代称。

  data:{
   furitList:[
     {id:1,name:"苹果",price:10},
     {id:2,name:"栗子",price:89},
     {id:3,name:"香蕉",price:23}
   ]
  }
<list wx:for="{{furitList}}" wx:key="id" wx:for-item="itemFor"  wx:for-index="key">{{itemFor.name}}-{{key}}</list>

渲染到多个组件中 :注意,block不会被渲染到页面中。

<block wx:for="{{furitList}}" wx:key="id" wx:for-item="itemFor"  wx:for-index="key">
<view>{{itemFor.name}}</view>
<view>{{itemFor.price}}</view>
</block>

(三)条件渲染

A、wx:if

data:{
   isShow: true,
   num:0
  },
  addNum(){
   this.setData({
     num:this.data.num+1,
   })
  }
<text wx:if="{{num == 0}}">{{num}}</text>
<text wx:elif="{{num == 1}}">{{num}}</text>
<text wx:else>{{num}}</text>
<button bindtap="addNum">数字加1</button>

 注意:

  • 只用当条件为true时,组件才会显示
  • if、elif、else必须连续使用,否则报错,elif、else不能离开if单独使用(wx省写了)
  • 这种方式,若不显示,就是真的将该组件从文件中移除了,在页面中不存在。

B、hidden

<text hidden="true">{{num}}</text>

若hidden为true,则元素不显示,原理是css中display:none。

为false,则显示。 

十一、小程序机制

(一)小程序运行机制

小程序分为四种状态,前台、后台、挂起、销毁

前台:当小程序界面被展示给用户时,就处于前台状态。

后台:当用户通过主页面键、小程序关闭按钮、关机键让小程序离开展示界面,则会处于后台状态。

挂起:小程序进入“后台”状态一段时间后(5s),微信停止小程序JS线程执行,小程序进入“挂起”状态,当开发者使用了后台播放音乐、后台地理位置等功能时,小程序仍然可以保持后台运行,不会进入到挂起状态。

销毁:如果用户很久没有使用小程序,或者系统资源紧张,小程序会被销毁,即完全终止运行。当小程序进入后台并被“挂起”后,如果很长时间(目前是30分钟)都未再次进入前台,小程序会被销毁,当小程序占用系统资源过高时,可能会被系统或者微信客户端主动回收。

  • 冷启动和热启动:

冷启动:在小程序没有在后台运行,从零开始打开的过程。

热启动:小程序仅仅在后台,没有被销毁,随时可以被切换到前台叫做热启动。

(二)小程序更新机制

在访问小程序时,微信会将小程序代码包缓存到本地。开发者在发布了新的小程序版本以后,微信客户端会检查本地缓存的小程序有没有新版本,并进行小程序代码包的更新。

小程序的更新机制有两种:启动时同步更新启动时异步更新

启动时同步更新:微信运行时,会定期检查最近使用的小程序是否有更新,如果有更新,下次小程序启动时会同步进行更新,更新到最新版本后再打开小程序,如果用户长时间未使用小程序时,会强制同步检查版本更新

启动时异步更新:在启动前没有发现更新,小程序每次冷启动时,都会异步检查是否有更新版本。如果发现有新版本,将会异步下载新版本代码包,将新版本的小程序在下一次冷启动进行使用,当前访问使用的依然是本地的旧版本代码。

在启动时异步更新的情况下,如果开发者希望立刻进行版本更新,可以使用wx.getUpdateManager API进行处理。在有新版本时提示用户重启小程序更新版本。

// 声明周期钩子,在冷启动时一定会执行该函数
  onLaunch(){
    //获取更新管理者对象,以方便下面操作
    const updateManager = wx.getUpdateManager();
    //执行在更新准备好时的方法
    updateManager.onUpdateReady(function(){
           wx.showModal({
             title:"更新提示",
             content:"新版本已准备好,是否重启应用使用最新版?",
            //  成功时的回调函数,如果用户选择重启,执行更新。
             success(res){
               if(res.confirm){
                 updateManager.applyUpdate();
               }
             }
           })
    })
  }

接下来在开发者工具中模拟版本更新,首先点击“普通编译”下拉框,点击添加编译模式

然后点击“在下一次更新时模拟更新”即可。

(三)小程序生命周期介绍

A、区别应用声明周期和小程序生命周期

应用生命周期是指应用程序进程从创建到消亡的整个过程。小程序的生命周期指的是小程序从启动到销毁的整个过程

一个小程序完整的生命周期由应用生命周期、页面生命周期组件生命周期三部分来组成。

小程序生命周期伴随着一些函数,这些函数由小程序框架本身提供,被称为生命周期函数,生命周期函数会按照顺序一词自动触发调用。帮助程序员在特定的时机执行特定的操作,辅助程序员完成一些比较复杂的逻辑。


这里大概介绍一下小程序的结构:

应用页面构成,页面组件构成。这一切所有就是小程序。

B、应用生命周期

应用生命周期声明在app.js中

应用周期分为三个:

-->onLaunch(小程序初始化)

-->onShow(小程序启动或者切到前台)

--> onHide(小程序切后台)

冷启动时:执行onLaunch、onShow、切到后台后执行onHide。

热启动时:从后天切前台执行onShow(大前提是应用进程没有被销毁)、切后台执行onHide

 C、页面生命周期

页面生命周期声明在 页面.js文件中:

页面生命周期如下:

页面生命周期细节
onLoad监听页面加载,在页面加载时执行。
onShow监听页面展示,会在页面加载前,或者切到其他页面(关闭应用程序在卸载之前)再次切回来时。
onReady监听初次渲染完成,该流程仅仅会在程序冷加载过程中仅仅执行一次。
onUnload页面在卸载的过程总会被执行。例如路由的时候,如果open-type为redirect,其他页面被销毁的时候,其他页面的redirect会被执行。
onHide页面被切走时,会被调用执行。

注意:

一、tabBar切换页面,原页面不会被销毁

二、导航open-type=navigator方式切到的页面,点击左上角小标返回后,原页面会被销毁

十二、小程序API

(一)什么是小程序API

是小程序提供给开发者使用的一系列接口,通过这些接口,开发者可以方便地实现一些功能,如获取用户信息、微信登录、微信支付等,小程序提供的API几乎都挂载在wx对象下,例如:wx.request(),wx.setStorage()等,wx对象实际上就是小程序的宿主环境微信所提供的全局对象。

接口分为三大类:

  • 异步API:通常都接受一个object类型的参数,例如:wx.request({});
  • 同步API:约定以Sync结尾,例如:wx.setStorageSync();
  • 事件监听API:约定以on开头,例如:wx.onAppHide();

注意,异步API支持callback&Promise两种调用方式:

  1. 当接口参数Object对象中不包含success/fail/complete时将默认返回Promise
  2. 部分接口如request,uploadFile本身就有返回值,因此不支持Promise风格的调用方式,它们的promisify需要开发者自行封装。

(二)wx.request(网络请求API)

  • 首先需要将自己要请求的服务器通过公众号平台,添加后才可以使用,开发时可以使用ip地址,没有域名,但是上线时一定要变为正式域名。

  • 取消合法域名校验:点开开发者工具中的“详情”-->“本地设置”

  • 而后就可以使用了:
<text>获得的每日一句是:{{textMe}}</text>
<button type="primary" bind:tap="getTextFromInternet">点我获取每日一句</button>
data: {
    textMe:'嘿嘿嘿'
  },
      getTextFromInternet(){
        wx.request({
          url: 'https://v1.hitokoto.cn/?c=f&encode=text',//一个自动获取随机一句话的网站
          method:'get',
          header:{},//请求头
          data:{},//要携带的参数
          //请求成功后执行的回调
          //注意这里用使用函数简便写法,负责this指向会变,导致API无法使用
          success:(resReturn)=>{
            //根据后端返回内容决定,我这里返回内容保存在data中。
            this.setData({
              textMe:resReturn.data
            })
             console.log(resReturn.data);
          },
          //执行失败后调用的回调
          fail(error){
            console.log("失败了,原因是:" + error);
          },
          //无论成功或者失败都会执行的回调
          complete(resInfo){
            console.log(resInfo);
          }
        })
      }

(三)wx.showLoading(展示加载提示框)

wx.hideLoading(隐藏加载提示框)

二者需要配合使用,我们在上面网络请求的例子中使用提示框:

getTextFromInternet(){
        //在请求前就开启加载提示框
        wx.showLoading({
          title:'加载中...',
          //设置加载框的消息提示内容,注意不会自动换行,若提示内容过多,会被多余部分会被隐藏。
          mask:true,
          //是否打开透明层,防止加载框存在,而用户继续触发页面内容。
        })
wx.request({
          //这里省略与本知识点无关内容
          complete(resInfo){
            // 请求完成后,关闭加载框
            wx.hideLoading();
          }
        })
      }

mask:开启模态透明层,防止加载框打开后,用户继续与页面交互产生。

(四)wx.showModel(模态对话框)、

wx.showToast(消息提示框)

A、wx.showModel

常常用于询问用户是否执行一些操作,例如:询问用户是否退出登录、是否删除该商品等等。

案例:我们在网路请求方法前加上模态对话框,询问是否需要网络请求:

async changeText(){
    //添加模态对话框,询问是否要请求每日一句,该API是异步的,所以可以使用Promise对象格式。
    const {confirm,cancel}= await wx.showModal({
      title:'提示',//为模态对话框,说明模态对话框的主题
      content:'是否要更换每日一句?'//消息的具体内容。
    });
    //根据返回值类型,判断用户选择结果
    if(confirm == true){
      //如果用户选择确定,则调用请求获取每日一句方法。
      this.getTextFromInternet();
    }else if(cancel == true){
      console.log("用户取消更新每日一句!");
    }
  }

这里展示下,返回的Promise对象的结构:

B、wx.showToast(消息提示框)

消息提示框,根据用户的某些操作来告知操作的结果,例如:退出成功给用户提示,提示删除成功等等。

这里我们模拟每日一句更新成功提示:

//弹出消息提示框,提示每日一句更新成功
      wx.showToast({
        title:'更新成功!',
        icon:"success",
        //四个值,代表不同的图标
      })

icon四个值分别是:

success成功图标,title最多个汉字
loading加载中图标,title最多个汉字
error失败图标,title最多个汉字
none无图标,最多两行汉字。

(五)本地存储相关

分为同步和异步两种API,如下:

在微信环境中,存储或获取对象类型的数据,不需要JSON.parse()或者JSON.stringify()进行转换。

A、同步方式

setDataToStore(){
   wx.setStorageSync('name', "少年李小龙");
   wx.setStorageSync('people',{name: "少年李小龙",age: 23});
  },
getDataToStore(){
   
   console.log(wx.getStorageSync("people"));
},
removeDataToStore(){
  wx.removeStorageSync('people');
},
clearDataToStore(){
  wx.clearStorageSync();
}

B、异步方式

setDataToStore(){
    //注意,因为异步方式,参数大多数以对象形式呈现。
   wx.setStorage({key:'name', data:"少年李小龙"});
   wx.setStorage({key:'people',data:{name: "少年李小龙",age: 23}});
  },
async getDataToStore(){  
   const {data} = await wx.getStorage({key:"people"});
   console.log(data);
},
removeDataToStore(){
 const promise =  wx.removeStorage({key:'people'});
 console.log(promise);
},
clearDataToStore(){
  wx.clearStorage();
}

(六)编程式路由导航

其实就是五个微信提供的API,代替了navigtor组件的open-type属性指定跳转方式的页面跳转模式。

API如下:

编程式路由导航API
wx.navigateTo保留当前页面,并跳转到新的非tabBar页面。
wx.redirectTo销毁当前页面,并跳转到新的非tabBar页面。
wx.switchTab跳转到其他tabBar页面
wx.reLaunch关闭其他页面,重新加载指定页面。
wx.navigateBack关闭当前页面,返回一级或多级页面。

A、如何指定要跳转的页面?

wx.navigateTo({
      url: '/pages/list/list',
    })

B、指定多级页面

wx.navigateBack({
    delta: 3//指定返回三级页面
  })

C、携带参数

 wx.navigateTo({
      url: '/pages/list/list?name=苏爱&age=32',
    })

D、接收参数

//被跳转页面的onLoad生命周期函数
onLoad(options) {
    console.log(options);
  }

(七)上拉加载页面

使用onReachBottom事件监听用户上拉加载行为。

默认触发onReachBottom的页面距离是50px,可以在app.json或者page.json中进行修改。

下面案例模拟下拉触发事件后加载新内容:

onReachBottom() {
    //打开信息提示框,提示正在加载
    wx.showToast({
      title: '加载中...',
      icon:"loading"
    })
    //通过定时器模拟请求过程
      setTimeout(()=>{
      let newIconList = [this.data.iconNumList[this.data.iconNumList.length -1]+1,this.data.iconNumList[this.data.iconNumList.length -1]+2,this.data.iconNumList[this.data.iconNumList.length -1]+3];
        //将新产生的标签,加到标签list中,推动视图更新
        this.setData({
          iconNumList:[...this.data.iconNumList,...newIconList]
        });
        //完成后,关闭消息提示框
        wx.hideToast();
      },2000)

  }
view{
  display:flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 230px;
}
view:nth-of-type(odd){
  //给单数标签设置背景色
  background-color: greenyellow;
}
view:nth-of-type(even){
  //给双数标签设置背景色
  background-color: indianred;
}
<view wx:for="{{iconNumList}}" wx:key="*this">{{item}}</view>

(八)下拉加载页面

需要再json配置页面开启允许下拉:

"enablePullDownRefresh": true,
"backgroundTextStyle":"light",

然后在页面,下拉时会触发onPullDownRefresh函数。我们通过该函数,将上拉增加的数组,置为初始状态:

onPullDownRefresh() {
       this.setData({
         iconNumList:[1,2,3]
       });
       //声明新的方法,在数组被置为0时,关闭下拉加载页面
       if(this.data.iconNumList.length == 3){
         //调用停止下拉刷新API
         wx.stopPullDownRefresh();
       }
  }

(九)scroll-view实现上拉和下拉

首先数据和样式先展示:

data: {
    iconNumList:[1,2,3],
    isRefreshed: false  //用来控制下拉刷新的开始和停止
  },
getMore() {
    中间过程跟上面上拉刷新一致

  },
refreshHandler() {
       this.setData({
         iconNumList:[1,2,3]
       });
       //声明新的方法,在数组被置为0时,关闭下拉加载页面
       if(this.data.iconNumList.length == 3){
         //更改属性值为true
         this.setData({
           isRefreshed: false
         })
         
       }
  },
.scroll-y{
  height:100vh;//让scroll-view元素填满整个页面。
}
view{
  display:flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 230px;
}
view:nth-of-type(odd){
  //给单数标签设置背景色
  background-color: greenyellow;
}
view:nth-of-type(even){
  //给双数标签设置背景色
  background-color: indianred;
}
<scroll-view
scroll-y
class="scroll-y"
lower-threshold="100"
bindscrolltolower="getMore"
enable-back-to-top
refresher-enabled
refresher-default-style="black"
refresher-background="#ccc"
bindrefresherrefresh="refreshHandler"
refresher-triggered="{{isRefreshed}}"
>
<view wx:for="{{iconNumList}}" wx:key="*this">{{item}}</view>
</scroll-view>

关键在scroll-view标签的各个属性值,下面列出各属性值具体作用:

属性细节
scroll-y设置上下滚动模式
lower-threshold设置触发上拉刷新的距离
bindscrolltolower指定触发上拉刷新要调用的函数
enable-back-to-top允许快捷返回顶部
refresher-enabled允许下拉刷新
refresher-default-style设置刷新界面风格
refresher-background刷新背景色

bindrefresherrefresh

指定下拉刷新后要调用的函数

refresher-triggered

指定控制是否刷新的变量,要求变量为boolean值。

十三、自定义组件

小程序支持组件化开发,可以将页面中的功能模块抽取成自定义组件,以便在不同的页面重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。

(一)全局自定义组件和局部自定义组件

A、公共组件

将页面内的功能模块抽取成自定义组件,以便在不同的页面中重复使用。

  • 声明 

在项目路径下,创建components文件夹,在文件夹下继续创建已组建名命名的文件夹(比如my_view),最后在该文件下“创建component”(my_view)文件(无后缀)后,开发者工具会自动补全文件夹内的文件,其结构和一个界面的结构一样,但作为组件来用。

  • 注册组件

在app.json中全局注册,配置参数,key是组件名,value是组件路径。

"usingComponents": {
    "my_view":"./components/my_view/my_view"
  }

这样子,这个组件在整个项目的任何地方都可以使用了!

  • 使用

直接在随意的页面wxml中声明即可。

<my_view></my_view>

B、页面组件

将复杂的页面拆分成多个低耦合模块,有助于代码维护。注册后只能由本页面使用。

  • 声明

和全局组件相同,唯一不一样之地是,页面组件只需要声明在页面文件夹内部。

  •  注册

和全局注册一致,不同是页面组件在页面内部的json中注册。

  • 使用

与上同,但注意只能使用在页面内部。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/578890.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Vue】可拖拽排序表格组件的实现与数据保存

1、描述 使用el-table-draggable组件来创建一个可拖拽的表格。 表格中的数据存储在tableData数组中&#xff0c;每个对象都有sortOrder、id、name和age属性。 当用户拖拽表格行并释放时&#xff0c;handleRowOnEnd方法会被调用&#xff0c; 更新tableData中每个对象的sortO…

SpringBoot 缓存

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 目录 一、缓存的作用二、SpringBoot启用缓存三…

腾讯云邮件推送如何设置?群发邮件的技巧?

腾讯云邮件推送功能有哪些&#xff1f;怎么有效使用邮件推送&#xff1f; 腾讯云邮件推送以其稳定、高效的特点&#xff0c;受到了众多企业的青睐。那么&#xff0c;腾讯云邮件推送如何设置呢&#xff1f;又有哪些群发邮件的技巧呢&#xff1f;下面AokSend就来详细探讨一下。 …

Express进阶升级

Express进阶升级&#x1f199; 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2; 文章简单学习总结&#xff1a;如有错误 大佬 &#x1f449;点. 前置知识&#xff1a;需要掌握了解&#xff1a; JavaScript基础语法 、Node.JS环境API 、前端工程\模块化、Expr…

nvm基本使用

nvm基本使用 文章目录 nvm基本使用1.基本介绍2.下载地址3.常用指令 1.基本介绍 NVM是一个用于管理 Node.js 版本的工具。它允许您在同一台计算机上同时安装和管理多个 Node.js 版本&#xff0c;针对于不同的项目可能需要不同版本的 Node.js 运行环境。 NVM 主要功能&#xff…

【Redis | 第十篇】Redis与MySQL保证数据一致性(两种解决思路)

文章目录 10.Redis和MySQL如何保证数据一致性10.1双写一致性问题10.2数据高度一致性10.3数据同步允许延时10.3.1中间件通知10.3.2延迟双删 10.Redis和MySQL如何保证数据一致性 10.1双写一致性问题 Redis作为缓存&#xff0c;它是如何与MySQL的数据保持同步的呢&#xff1f;特…

PHP 错误 Unparenthesized `a ? b : c ? d : e` is not supported

最近在一个新的服务器上测试一些老代码的时候得到了类似上面的错误&#xff1a; [Thu Apr 25 07:37:34.139768 2024] [php:error] [pid 691410] [client 192.168.1.229:57183] PHP Fatal error: Unparenthesized a ? b : c ? d : e is not supported. Use either (a ? b : …

『FPGA通信接口』串行通信接口-SPI

文章目录 1.SPI简介2.控制时序3.Dual、Qual模式4.例程设计与代码解读5.SPI接口实战应用5.1时序要求5.2仿真时序图5.3代码设计 6.传送门 1.SPI简介 SPI是串行外设接口&#xff08;Serial Peripheral Interface&#xff09;的缩写&#xff0c;通常说SPI接口或SPI协议都是指SPI这…

将文件导入数据库

#include <stdio.h> #include <sqlite3.h> #include <string.h> int main(int argc, const char *argv[]) { //打开数据库 sqlite3 *db NULL; if(sqlite3_open("./dict.db",&db) ! SQLITE_OK){ printf("sqlite…

5G随身WiFi推荐测评:品速5G VS 格行5G随身WiFi,随身wifi哪个品牌网速好?性价比更高?

玩游戏卡顿遭吐槽&#xff0c;直播掉线成笑柄&#xff0c;4G网络已难满足需求。5G随身wifi虽受追捧&#xff0c;但价格较高令人犹豫。面对众多品牌&#xff0c;随身WiFi哪个品牌靠谱呢&#xff1f;性价比高呢&#xff1f;今天就来测评一下口碑最好的无线随身WiFi格行5G随身wifi…

新能源车载芯片分析

新能源汽车市场正迸发出巨大的活力&#xff0c;传统主机厂和新势力都纷纷推出各种车型&#xff0c;打起了价格战&#xff0c;各种新技术让人眼花缭乱。当前&#xff0c;战场硝烟弥漫&#xff0c;新能源汽车公司犹如春秋时期的各诸侯国。车载芯片作为新能源汽车的关键组成部分&a…

NDK 基础(一)—— C 语言知识汇总

1、数据类型 在 C 语言中&#xff0c;数据类型可以分为如下几类&#xff1a; 基本数据类型&#xff1a; 整数类型&#xff08;Integer Types&#xff09;&#xff1a;是算数类型&#xff0c;包括如下几种&#xff1a; int&#xff1a;用于表示整数数据&#xff0c;通常占用四个…

nvm 切换 Node 版本失败

创建vue3项目时&#xff0c;需要切换到更高版本的 node&#xff0c;于是使用 nvm (node 包版本管理工具)进行版本切换 切换版本时&#xff0c;显示成功&#xff0c;但再次查看当前 node 版本时&#xff0c;发现没切换过来。 解决方法&#xff1a; where node 查看node的安装…

车道分割YOLOV8-SEG

车道分割YOLOV8-SEG&#xff0c;训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;支持C,PYTHON,ANDROID开发 车道分割YOLOV8-SEG

深圳工厂车间降温通风设备

深圳工厂降温方案多种多样&#xff0c;可以根据工厂的具体情况和需求来选择合适的方案。以下是一些常见的降温方案&#xff1a; 通风换气&#xff1a;通过安装负压风机或冷风机等设备&#xff0c;加强通风换气&#xff0c;将室内热空气排出&#xff0c;吸入室外相对凉爽的空气…

零基础俄语培训哪家好,柯桥俄语培训

1、Мощный дух спасает расслабленное тело. 强大的精神可以拯救孱弱的肉体。 2、Единственное правило в жизни, по которому нужно жить — оставаться человеком в лю…

WSL及UBUNTU及xfce4安装

如何拥有Linux服务器&#xff1f; wsl 是适用于 Linux 的 Windows 子系统&#xff08;Windows Subsystem for Linux&#xff09;。是一个为在Windows 10和Windows Server 2019上能够原生运行Linux二进制可执行文件&#xff08;ELF格式&#xff09;的兼容层&#xff0c;可让开发…

Docker 的数据管理 端口映射 容器互联 镜像创建

一 Docker 的数据管理 1 管理 Docker 容器中数据主要有两种方式&#xff1a; 数据卷&#xff08;Data Volumes&#xff09; 数据卷容器&#xff08;DataVolumes Containers&#xff09;。 1.1 数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机…

数据污染对大型语言模型的潜在影响

大型语言模型&#xff08;LLMs&#xff09;中存在的数据污染是一个重要问题&#xff0c;可能会影响它们在各种任务中的表现。这指的是LLMs的训练数据中包含了来自下游任务的测试数据。解决数据污染问题至关重要&#xff0c;因为它可能导致结果偏倚&#xff0c;并影响LLMs在其他…

linux 中 make 和 gmake的关系

1. 关系 gmake特指GNU make。 make是指系统默认的make实现; 在大多数Linux发行版中&#xff0c;make就是GNU make&#xff0c;但是在其他unix中&#xff0c;gmake可以指代make的某些其他实现&#xff0c;例如BSD make或各种商业unix的make实现。 gmake是GNU Make的缩写。 Linux…