上篇说index目录下的四个同名文件构成了index页面。那么这些页面是怎么合作的呢?
上篇说index目录下的四个同名文件构成了index页面。那么这些页面是怎么合作的呢?
首先,来看wxml页面。
<!--index.wxml-->
<view class="container">
<view class="userinfo">
<block wx:if="{{canIUseOpenData}}">
<view class="userinfo-avatar" bindtap="bindViewTap">
<open-data type="userAvatarUrl"></open-data>
</view>
<open-data type="userNickName"></open-data>
</block>
<block wx:elif="{{!hasUserInfo}}">
<button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
<button wx:elif="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
<view wx:else> 请使用1.4.4及以上版本基础库 </view>
</block>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<!-- 只看下面👇这一段 -->
<view class="usermotto"><!-- 独占一行的view -->
<text class="user-motto">{{motto}}</text><!-- 行内元素的text-->
</view>
</view>
这个文档里写了很多,我们先只看最后一个view
这个文件是按照HTML语言的格式来写的。
它的作用呢相当于Android 项目中的xml布局文件。
排列规则:
在Android的xml布局中,所有的控件都是在有顺序规定的布局里面的,如LinearLayout规定垂直或水平排序,RelativeLayout则是所有的控件如果不指定位置的话都一层层摞在了左上角。
我看这个文档就很奇怪,各种view套view也没地方指明这个view放在父组件的什么位置。
问了问前端的朋友,他告诉
默认是垂直排序,从上往下排。
如果元素不够一行的,就是行内从左向右排。
那么怎么确定我们的元素是占了一行还是不占一行呢?
在HTML中,每一个元素都有一个内置属性叫做display,默认值为block(独占一行)或者inline(行内排列).
那么在wxml的语言中,都有哪些元素呢,它们是都占据一行呢?
https://developers.weixin.qq.com/miniprogram/dev/component/cover-image.html
这就是官方给出的微信的组件元素。就是说我们在wxml中可以写的<>中的元素。类似于罗列出了Android 中的textview imageview等控件。
容器类的大都是独占一行的,而基础内容类和表单组件等大都是行内,
实在不放心可以在wxss文件中重新定义display的属性。这是后话。
组件样式:
在修改样式前,我们要知道一个组件的样式是由哪些属性来决定的。
微信官方文档给的组件的属性有了说明,这些都是这个组件在微信中的特有属性。
但是并不全,比如width,height,margin,padding等其实这是每个元素都有的基本属性。
而这些基本属性叫什么名字,以及什么规则从哪里看呢,这里就要要邀请出CSS同学了。
https://www.w3school.com.cn/css/css_colors.asp
从这个教程可以看到css可以定义的属性。包括颜色,背景色和边距,边框等。
知道是这些属性和微信给的特色属性来决定一个组件的样式后。
我们再来谈如何设定他们的样式。
1.通过内联样式修改
这种方式就是给组件添加一个style属性,在style这个属性里规定这个组件的颜色等外观属性的设置。
如
<!-- index.wxml-->
<text style="color:red;font-size:40px">{{motto}}</text>
这个样式就是说把text的字体颜色设置为红色,同时字体大小设置为40像素
采取key:value的变现形式。同时不同的属性之间用;隔开。
这种内联样式的适用于修改一个或几个等少数的特殊样式的组件。
如果组件的样式比较统一的话推荐👇的修改方式。
2.通过选择器修改
这个就是更类似于Android写xml时指定了这个组件的style。同时style的样式存放于另外的文件中。
不过区别是
<!-- Android xml布局文件写法-->
<TextView style=“@style/txtStyle”/>
<!-- wxml中的写法 -->
<text class="usermotto">{{motto}}</text>
class就相当于Android 中的style,那么这个usermotto是表示引用的class名称。
而这个叫做usermotto的class实在哪里被定义的呢,这就用到了wxss文件。
WXSS文件
这个文件其实是和css文件的语法一样的
打开我们的index.css文件,在这里面可以看到有一个.usermotto
/** index.wxss **/
.usermotto {
margin-top: 200px;
}
这里可以看到里面有一个margin-top的属性。
把它改造一下。改为
/** index.wxss **/
.usermotto {
margin-top: 200px;
color: red;
font-size: 40px;
}
Ctrl+S保存一下,程序会自动编译
会看到页面
可以看到text的样式也是发生了变化。和上面的内联样式是一样的。
那么这种利用class属性来控制样式就叫做类选择器,是选择器的一种。
微信官方支持的选择器有如下几种。
分别试验一下
id选择器
/**index.wxss**/
/** id选择器用#标识,class选择器用. 标识**/
#usermotto-txt-blue{
color: blue;
display: block;
}
<!--index.wxml-->
<view class="container">
<view class="usermotto">
<image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" ></image>
<text style="color:red;font-size:40px">{{motto}}</text>
<!-- 使用id来设置样式 -->
<text id="usermotto-txt-blue">{{motto}}</text>
</view>
</view>
这样的组合就会使字体变为蓝色。不贴图了,自己可以去试验
元素选择器
/**index.wxss**/
/**所有的没指定样式的text组件的字体颜色都将是绿色**/
text{
display: block;
color: green;
}
<!--index.wxml-->
<view class="usermotto">
<image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" ></image>
<text style="color:red;font-size:40px">{{motto}}</text>
<!-- 未指定样式,所以是绿色 -->
<text >{{motto}}</text>
</view>
伪元素选择器:
/**index.wxss**/
/** 在每个text前面会加入“你好”两个字**/
text::before{
content: "你好";
color: blue;
font-size: 20px;
}
<!--index.wxml-->
<view class="container">
<view class="usermotto">
<image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" ></image>
<!-- 所有的text前面都会加上“你好”-->
<text style="color:red;font-size:40px">{{motto}}</text>
<text >{{motto}}</text> <!-- 未指定样式,所以是绿色 -->
</view>
</view>
选择器这几个样式大都以罗列完毕,平常写的时候组合使用即可。
记录一下图片组件加载本地和网络图片的情况
本地图片
根目录新建image文件夹来存放本地图片。
<!--index.wxml-->
<view class="container">
<view class="usermotto">
<!-- 指定图片路径,/表示根目录,./表示当前目录,../表示父目录 -->
<image class="userinfo-avatar" src="/image/test_blue.png" ></image>/
<text style="color:red;font-size:40px">{{motto}}</text><!-- 所有的text前面都会加上“你好”-->
<text >{{motto}}</text> <!-- 未指定样式,所以是绿色 -->
</view>
</view>
网络图片
<!--index.wxml-->
<view class="container">
<view class="usermotto">
<image class="userinfo-avatar" src="/image/test_blue.png" ></image>
<image class="userinfo-avatar" src="https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg" ></image>
<text style="color:red;font-size:40px">{{motto}}</text><!-- 所有的text前面都会加上“你好”-->
<text >{{motto}}</text> <!-- 未指定样式,所以是绿色 -->
</view>
</view>
OK,搞明白了样式的展示,接下来看看这些页面是怎么被附上数据的。
在上面有一句是<text>{{motto}}<text>,但是展示出来后,却显示的是helloworld
那么这个{{motto}}和helloworld有什么关系呢,这就说到了存放数据的js文件
JS文件
Android中如果用过MVVM架构,那么在xml中会有过这种写法
<TextView
android:text=“@{viewmodel.desc}”/>
这种写法,其实和小程序wxml的数据绑定有异曲同工之妙
<!-- index.wxml -->
<text >{{motto}}</text>
如果使用{{}}来为组件设置内容,那么默认这个{{}}是表达式。
而motto是指的什么呢,打开js文件就可以找到这个数据了。
// index.js
// 获取应用实例
const app = getApp()
Page({
data: {
motto: 'Hello World’,//这就是我们要找的motto
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo'),
canIUseGetUserProfile: false,
canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false
},
可以看到motto是一个类似json格式的key,同时它的值是helloworld也就是我们展示在页面上的值。
看到这里,再去了解一下官方对Page的说明
宿主环境提供了 Page() 构造器用来注册一个小程序页面,Page()在页面脚本page.js中调用。
它的参数是一个对象,这个对象有如下属性👇
可以理解为整个js文件就是写了一个Page(Object param)对象的构造函数。
而这个构造函数的参数是个对象param,这个参数param对象包括了data和各大生命周期的方法。
在Javascript中,对象的定义和Java略有不同。
比如Java中是int 1 = 3;那么Javascript中则会是 i:3;即属性和值用key:value来表示。所有的变量都是用var来表示,var可以涵盖字符串值,数值,布尔值,数组,对象。
wow,果真是强大的var.
JavaScript中 对象用花括号来书写。
对象属性是 name:value 对,由逗号分隔。
实例
var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};
这就是定义了一个person的JS对象。
比如page这个对象,它里面的data是对象,那么我们就可以这样写
Var dataContent = {
motto: 'Hello World',
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo'),
canIUseGetUserProfile: false,
}
Var content = {
date: dataContent,
onLoad:funciton(){
}
}
Page(content);
只不过,在index.js中,把所有的对象都展开显示了。类似于隐形声明了👆的content对象
总之呢,就是page这个构造器里面就包括了名为data的对象,这个对象的属性有作为了wxml的数据来源。
这也解释了为什么我们的text显示helloworld的原因。
JSON文件
这个文件主要用于设定页面的标题展示,标题风格,以及生命引用的自定义组件等。暂时不表,后期用到会说明。
OK,大体了解了小程序的页面显示样式和数据绑定,下一篇看一下如何修改数据以及对更复杂的数据的应用。