使用mpVue开发微信小程序记录

一、新增页面

  1. 在src/pages下面新建文件夹,并且新建xxx.vue/main.js/main.json文件
  2. app.json文件新增页面路径
  3. ctrl+c退出 npm run dev重新编译
  4. xxx.vue页面结构
<template>
  <div class="container">
        // ... html 注意:template标签下只能有一个根元素 否则报错
  </div>
</template>

<script>
export default{
  data () {
    return {
      // ... 数据
    }
  },
  methods: {
    // ... 方法
  }
}
</script>

<style lang="less">
    // ... less 样式
</style> 
            或者
<style>
    // ... 普通的css样式
</style> 
  1. mpvue和mpvue-weui
    mpvue是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。

【官网】http://mpvue.com/mpvue/

mpvue-weui是基于mpvue框架和小程序原生组件的基础样式库,可供快速开发。
【官网】https://kuangpf.com/mpvue-weui/

二、新增组件

  1. 在src/components下新建test.vue文件
  2. test.vue (与页面结构一致)
<template>
  <div class="container">
  
  </div>
</template>

<script>
export default {
  data () {
    return {
      
    }
  },
  methods: {
    
  }
}
</script>

<style lang="less">
// ... 样式
</style>
  1. 使用组件
    在xxx.vue页面上使用
<script>
// ① 导入组件
import myTest from "@/components/test";

export default {
   // ② 声明组件
  components: { myTest },
  data () {
    return {
      // ...
    }
  },
}
</script>

<template>
  <div class="container">
    <!-- ③ 使用组件 -->
    <my-test></my-test>
  </div>
</template>
  1. 组件间的传值
    ① 父组件传值给子组件
    父组件.vue
<my-test :result="resultMsg"></my-test>  
// 使用:号绑定一个result属性名,传递的值为父组件的resultMsg

data () {
  return {
    resultMsg: '我是父组件传给子组件的值'
  }
},

② 子组件接收父组件传递过来的值
子组件.vue

<template>
  <div class="container">
    <p>{{result}}</p>   // ② 页面上使用  注:如果在vue对象中使用则为this.result
  </div>
</template>

export default {
   // ① 通过props接收信息 
   // 这里props引用的是父组件在子组件上绑定的属性名,它的值就是传递过来的值
  props:['result'], 
  data () {
    return {
      // ...
    }
  },
}
  • props的三种方式:
// 第一种:
props: ['result']

// 第二种:
props: {
    result: String  // 这里指定了字符串类型,如果类型不一致会警告的哦
}

// 第三种:
childCom: {
    type: String,   // 这里指定类型
    default() {
       return ''    // 这里设置默认值,如果父组件未传入则使用默认值
    }
}

③ 子组件向父组件传值
子组件.vue

// 给一个input绑定一个blur事件
<input type="text" v-model="inputValue" @blur="blurFn">

methods: {
  data: function () {
    return {
      inputValue: ''  
    }
  },
  blurFn () {
    this.$emit("changeValue", this.inputValue) 
    // 子组件发射自定义事件 testValue, 并且传递值 inputValue
    // 如果要传递多个值,写法为 this.$emit("事件名", 值1,值2,值3) 
  }
}

④ 父组件接收子组件传递过来的值
父组件.vue

<my-test @changeValue="parentChangeValue"></my-test>
// 父组件在子组件上使用@事件名="方法名"接收,其中事件名是子组件$emit发射的事件名

methods: {
  // 在方法里定义一个接收值的函数
  parentChangeValue(value){
    console.log(value);  // 这里的value就是子组件传递过来的inputValue的值
  }
}

三、模板语法

  1. for循环
<ul v-for="(item, index) in list">
    <li v-for="(v, i) in item">       // 注:嵌套循环需指定不同的索引
        {{v.value}}
    </li>
</ul>
  1. 条件渲染
<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>
  1. 属性绑定与事件绑定
<a @click.stop="chooseHome">a标签</a> 
// 用@事件名="函数名" 绑定事件  .stop是修饰符,阻止冒泡

<button :disabled="true"></button>
<img :src="item.deviceLogo">
// 用:属性名="变量名"绑定。注:布尔值也需要使用:号绑定,否则被视为字符串。

4.Class 与 Style 动态绑定

<p :class="{ 'active': isActive }">xxxxx</p>   
// 'active' 类名  isActive 是否绑定的判断条件

<p :style="{ color: activeColor, fontSize: fontSize + 'px' }">xxxxx</p>
// 例: activeColor: '#ccc', fontSize: 24  转化后 
<p style="color:'#ccc';font-size: 24px;">xxxxx</p>

四、常用demo

  1. 上拉加载、下拉刷新
// ① 导入组件
import xview from "@/components/xview";

// ② 声明组件
components: { xview,noDevices,msgModal,devModal },

// ③ 使用组件
<scroll-view class="facilist-view">
  <xview @pulldownrefresh="pullDownRefresh" @scroll="scroll" @loadmore="loadmore" :refreshing="refreshing" :nomore="nomore" :hideLoadMore="hideLoadMore" ref="xview">
    <ul>
      <li></li>
    </ul>
  </xview>
</scroll-view>

// 注释: 
// pulldownrefresh 下拉刷新监听函数 在这个方法里做刷新列表动作
// loadmore 上拉加载监听函数 在这个方法里做加载下一页动作
// scroll 滚动事件 不做处理
// hideLoadMore 是否在加载完后隐藏上拉加载的文字
// ref="名称"   可通过 _this.$refs.名称.方法名 调用组件内部的方法
  1. 表单
<template>
  <form @submit="formSubmit" @reset="formReset">
    // ... 表单元素
    <view class="section btn-wrap">
      <button type="button" class="login-btn yh-btn-big" form-type="submit">登录</button>       // ... 提交按钮
    </view>
  </form>
</template>


methods: {
  formSubmit(e) {
    console.log('form发生了submit事件,携带数据为:', e.mp.detail.value)
  },
  formReset() {
    console.log('form发生了reset事件')
  }
}
  1. modal弹层组件
    xxxModal.vue 弹层组件结构
//  弹层结构
<template>           // v-if="变量" 控制弹层显示隐藏
  <view class="modal-wrap" v-if="showModal" @touchmove.stop="preventTouchMove">
    <!-- ① 遮罩层 -->
    <view class="modal-mask"></view>
    <!-- ② 弹出层 -->
    <view class="modal-dialog message-modal-wrap">
      <view class="modal-title">{{title}}</view>
      <view class="modal-content">
         <!-- ③ 内容 -->
      </view>
      <!-- ④ 底部放关闭图标 (也可以放按钮) -->
      <view class="modal-footer" @click="onCancel">
        <img src="/static/images/modal_icon_close@2x.png" data-status="cancel" class="icon-close">
      </view>
    </view>
  </view>
</template>

// props 接收父组件传递值: showModal控制显示隐藏 title弹层标题 
props: ['showModal','title'],

// 关闭弹层事件
methods: {
  preventTouchMove(){},  // 禁止屏幕滚动 只需要一个空的函数 
  onCancel() {
    this.$emit("hideModalFn")  // 触发父组件关闭方法(注意没有传递值)
  },
}

父组件.vue

// ① 导入弹层组件
import xxxModal from "@/components/xxxModal";

// ② 声明组件
components: { xxxModal },

// ③ 使用组件 使用:showModal :title传递值给弹层组件 @hideModal接收子组件发射的事件
<xxx-modal :showModal="showModal" :title="title" @hideModalFn="hideModalFn"></xxx-modal>

// ④ data定义要传递的值
data () {
  return {
    showModal: false,
    title: '提示'
  }
}

// ⑤ methods里定义子组件触发的父组件方法
methods: {
  hideModalFn(){
     this.$set(this.$data,'showModal',false);  // 关闭弹层
  }
}

// ⑥ 显示弹层的方法
<button @click="showModalFn"></button>  // 某个元素绑定showModalFn点击事件

// methods里定义showModalFn方法
methods: {     
  showModalFn(){ 
     this.$set(this.$data,'showModal',true);  // 显示弹层
  }
}
  1. 滑动删除demo
// demo结构
<ul>
  <li v-for="(item,index) in List" :key="index" @touchstart="touchStart($event)" @touchend="touchEnd($event,index)" :data-type="item.type">
    <view class="content">
      // ... 展示出来的demo内容
    </view>
    <div class="delect" @click="delete(index,item.id)"> 
      删除
    </div>    // 删除按钮,滑动前隐藏,左滑后展示
  </li>
</ul>

// 函数
methods: {
    // ① 在加载列表数据时初始化滑动属性type
    queryList(){
      // 添加滑动参数
      this.List.forEach(function (item) {
        this.$set(item,'type',0);   // type 0 默认没有左滑
    })
    },
    // ② 滑动开始获取startX
    touchStart(e){
      // 获取移动距离,可以通过打印出e,然后分析e的值得出
      this.startX = e.mp.changedTouches[0].clientX;
    },
    // ③ 滑动结束获取endX
    touchEnd(e,index){
        // 获取移动距离
        this.endX = e.mp.changedTouches[0].clientX; 
        // 移动距离大于60,滑动元素的type设为1,其它为零
        if(this.startX-this.endX > 60){
            for(let i=0;i<this.List.length;i++){
                  this.List[i].type = 0
            }
            this.List[index].type = 1
        }
        // 反向滑动(向右)则恢复原状
        else if(this.startX-this.endX < -60){
            for(let i=0;i<this.List.length;i++){
                  this.List[i].type = 0
            }
        }
    },
    // ④ 点击回复原状的函数(可选)
    recover(index){
      this.List[index].type = 0
    },
    // ⑤ 删除按钮的操作
    delete(index,Id){
      let _this = this;
      wx.showModal({
        title: '提示',
        content: '确定删除吗?',
        success(res) {
          if (res.confirm) {
            console.log('用户点击确定')
            // 在这里发起删除请求
            _this.List.splice(index,1);
          } else if (res.cancel) {
            console.log('用户点击取消')
          }
        }
      })
    },
}

// 主要样式
<style lang="less">
ul {
  width: 100%;
  li {
    -webkit-transition: all 0.2s;  // 动画过渡
    transition: all 0.2s;
    width: calc(~'100% + 90px');   // 这里的90px是删除按钮和左右间距的宽度
    height: 74px;
    line-height: 74px;
    align-items:center;
    display:flex;
    .content {
       width: calc(~'100% - 90px');  // 内容区减去这个宽度
    }
    .delect{
      width: 40px;
      height: 40px;
      line-height:40px;
    }
    &[data-type="0"]{   
      transform: translate3d(0,0,0);   // 没有滑动【重要】
    }
    &[data-type="1"]{
        transform: translate3d(-40px,0,0);  // 滑动后向左移动40px【重要】
    }
  }
}
</style>

五、样式类

  1. 公共样式放在App.vue的<style></style>标签内

  2. 模块私有样式放在各模块的<style></style>标签内

  3. less常用语法
    ① 嵌套

<div class="parent">
  <div class="child-one"></div>
  <div class="child-two"></div>
</div>

// css写法
.parent {
  background: #f8f8f8;
  margin: 0 auto;
}
.parent .child-one {
  color: red;
  font-size: 14px;
}
.parent .child-two {
  color: blue;
  font-size: 16px;
}

// less写法
.parent {
  background: #f8f8f8;
  margin: 0 auto;
  .child-one {
    color: red;
    font-size: 14px;
  }
  .child-two {
    color: blue;
    font-size: 16px;
  }
}

② &的使用

<ul>
  <li class="active"></li>
  <li></li>
</ul>

// css 写法
ul li {
  color: #333;
}
ul li.active {
  color: blue;
}

// less 写法
ul {
  li {
    color: #333;
    &.active {            // 这里的 &.active == li.active
      color: blue;
    }
  }
}

// 例如
li:after {

}

也可以写成

li {
  &:after {

  }
}

& 向上寻找

③ calc()

// css 写法
div {
  calc(100% - 60px);
}

// less 写法
div {
  calc(~'100% - 60px');
}

④ 注释

// less 
div {
  width: 100%;
  height: 100%;
  // color: #333;
  // background: #f8f8f8;      // 这两行就被注释掉了,不会被编译在样式里
  margin: 0 auto;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容