做那个网站销售产品比较好,付费资料网站开发,做网站用不用云服务器,做网站用什么语言简单【 0 】前言
【 0 】 这个就是js代码的存放地方 app.json
// pages/banner/banner.js
Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示…【 0 】前言
【 0 】 这个就是js代码的存放地方 app.json
// pages/banner/banner.js
Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {},/*** 生命周期函数--监听页面隐藏*/onHide() {},/*** 生命周期函数--监听页面卸载*/onUnload() {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {},/*** 页面上拉触底事件的处理函数*/onReachBottom() {},/*** 用户点击右上角分享*/onShareAppMessage() {}
})xxxx.wxml 这个就是存放html的地方
!--pages/banner/banner.wxml--
image src/images/31.jpg mode/view ----事件基本使用------ /viewbutton sizemini typewarn loading bind:taphandShow 点击看控制台 /buttonapp.wxss 这个分两种情况在小应用程序就是局部使用 只在一个页面使用的样式
/* pages/log/log.wxss */text {font-size: 50px;color: aqua;
}button{/* 距离顶部30rpx */margin-top: 300rpx; /* 距离底部30rpx */margin-bottom: 30rpx;/* 优先以这个样式为准 */background-color: rgb(147, 145, 255) !important;
}在根应用软件就是全局使用 view {font-size: 50px;background-color: aqua;
} 根目录的app.json路由 {pages: [pages/banner/banner,pages/log/log],window: {enablePullDownRefresh: false, backgroundColor: #00FFFF, backgroundTextStyle: dark },style: v2,sitemapLocation: sitemap.json
}【 1 】快速上手
-组件viewtextbuttoniconimage 。。。。-组件属性属性-尺寸单位和样式-rpx 等比例缩放-样式app.wxss xx.wxss---局部会覆盖全局【 2 】 tabbar使用
-app.json 中背景图【 3 】 首页案例
-轮播图
-公告样式
-flex布局
-通知
-宫格【 4 】引入矢量图
# 1 打开 https://www.iconfont.cn/-注册成功
# 2 搜索想要的图标-加入购物车-在购物车中添加至项目
# 3 我的项目--项目设置--》打开base64
# 4 选择font class --》生成代码--》点击链接地址打开
# 5 把打开的链接地址内容复制到项目中-static/css/iconfont.wxss
# 6 在app.wxss中引入
import /static/css/iconfont.wxss;# 7 在想用图标的位置加入text组件
text classiconfont icon-anquan【 一 】事件绑定 bind这是微信小程序中默认的绑定方式。当使用bind方式绑定事件时如果子元素触发了事件这个事件会冒泡到父元素如果父元素也绑定了该事件的处理函数那么父元素的事件处理函数也会被调用。catch这是另一种绑定方式用于阻止事件冒泡。当使用catch方式绑定事件时如果子元素触发了事件这个事件将不会冒泡到父元素即使父元素也绑定了该事件的处理函数父元素的事件处理函数也不会被调用。
1.1 基本使用 vue
v-on:事件名hand
v-on:click hand
简写成用的多
clickhand
方法必须放在methods中methods: {hand: function () {this.show !this.show // ! 取反}}微信小程序
# 1 方式一
view bind:tabjs中写方法/view
# 2 方式二
view bindtabjs中写方法/view# 3 js中写方法showLog(){console.log(我被点了)}!--pages/banner/banner.wxml--
image src/images/31.jpg mode/view ----事件基本使用------ /view!-- --
button sizemini typewarn loading bind:taphandShow 点击看控制台 /button 是的您提到的 button 标签和它的属性确实是微信小程序中的按钮组件的写法。在微信小程序中button 组件有一些特定的属性和事件。
这里是您给出的 button 组件的解析
sizemini设置按钮的大小为迷你型。微信小程序中的按钮有三种尺寸default默认大小、mini迷你大小和 small小尺寸但在某些版本或文档中可能不被支持建议使用 mini。typewarn设置按钮的类型为警告样式。微信小程序的按钮类型有 default默认样式、primary主要样式、warn警告样式和 success/success_no_circle成功样式不带/带圆形图标。loading如果设置了该属性无需赋值属性名本身就是布尔值按钮会显示为加载中状态。bindtaphandShow当按钮被点击时会触发 handShow 方法。在微信小程序中事件绑定的语法是 bindxxx 或 catchxxx其中 xxx 是事件名然后使用 指定要调用的方法。
所以这个 button 组件表示一个迷你的、警告样式的、加载中的按钮当点击时会触发 handShow 方法。
在您的 js 文件中您应该有一个名为 handShow 的方法例如
Page({ // ... 其他页面数据和方法 handShow: function() { console.log(按钮被点击了); // 在这里执行您希望在点击按钮时执行的操作 }
}); 当您在微信开发者工具中预览或运行小程序并点击这个按钮时您应该在控制台中看到 “按钮被点击了” 的输出。 1.2 阻止事件冒泡 事件冒泡
如果一个父元素或祖先元素和它的子元素都绑定了相同类型的事件监听器如click事件并且子元素被点击时这两个事件监听器都有可能被触发。默认情况下子元素的事件会首先被触发然后这个事件会冒泡到父元素并触发父元素的事件监听器如果绑定的话。这个过程就叫做事件冒泡。
1.阻止事件冒泡通常用于以下场景
当你只想让子元素的事件监听器被触发而不希望父元素或祖先元素的事件监听器也被触发时。当你希望优化性能避免不必要的事件处理时。
2. 如何阻止事件冒泡
在微信小程序中阻止事件冒泡的主要方式就是将bind替换为catch。例如如果你想阻止一个按钮的点击事件冒泡你可以这样写
button catchtaphandleClick点击我/buttonxxxx.wxml
!-- 阻止事件冒泡 --view styleheight:300rpx;display: flex;justify-content: center;align-items: center; background-color: orange; bind:taphandShow2
!-- catch:tap --
button typeprimary plain catch:taphandleButton2阻止事件冒泡/button
/viewxxxx.js
Page({handShow2: function() { console.log(爹的按钮被点击了); // 在这里执行您希望在点击按钮时执行的操作 } ,handleButton2: function() { console.log(这个是儿子事件); // 在这里执行您希望在点击按钮时执行的操作 } ,})1.3 事件对象和传参
data-*方案
mark:自定义属性
target :事件触发者 :dataset data定义的属性
currentTarget:事件绑定者 :dataset data定义的属性xxx.wxml
view-------------------/view
!-- 事件对象和传参 --
view styleheight:300rpx;display: flex;justify-content: center;align-items: center; background-color: pink; bind:taphandShow3
button typeprimary plain bind:taphandleButton3 data-nameJOINNN data-xxtian mark:namemao事件传参/button
/viewxxx.js
Page({handleButton3:(event) {console.log(event)console.log(mark传入的参数,event.mark.name)console.log(currentTarget)console.log(data-字段名传入的参数,event.currentTarget.dataset.xx)console.log(data-字段名传入的参数,event.currentTarget.dataset.name)console.log(target)console.log(data-字段名传入的参数,event.target.dataset.xx)console.log(data-字段名传入的参数,event.target.dataset.name)},handShow3:(event) {console.log(event)},})【 二 】页面跳转
2.1 wxml-组件跳转–声明式导航
# 1 使用 navigator 组件实现跳转-url 当前小程序内的跳转链接-open-type 跳转方式navigate保留当前页面跳转到应用内的某个页面。但是不能跳到 tabbar 页面redirect 关闭当前页面跳转到应用内的某个页面。但不能跳转到 tabbar 页面switchTab跳转到 tabBar 页面并关闭其他所有非 tabBar 页面reLaunch关闭所有页面打开到应用内的某个页面navigateBack关闭当前页面返回上一页面或多级页面# 2 普通跳转 --注意带 /
viewnavigator url/pages/login/loginbutton typeprimary登录/button/navigator/view# 3 open-type 属性## 3.1 navigate保留当前页面跳转到应用内的某个页面。但是不能跳到 tabbar 页面
view
navigator url/pages/my/my open-typenavigate不能跳转到我的/navigator
/viewview
navigator url/pages/login/login open-typenavigate跳转到登录/navigator
/view## 3.2 redirect 关闭当前页面跳转到应用内的某个页面。但不能跳转到 tabbar 页面
view
navigator url/pages/login/login open-typeredirect跳转到登录关闭上一个页面/navigator
/view## 3.3 switchTab跳转到 tabBar 页面并关闭其他所有非 tabBar 页面
view
navigator url/pages/my/my open-typeswitchTab跳转到my-tab页/navigator
/view## 3.4 reLaunch关闭所有页面打开到应用内的某个页面
view
navigator url/pages/my/my open-typereLaunch跳转到my-tab页/navigator
navigator url/pages/login/login open-typereLaunch跳转到login页/navigator
/view## 3.5 navigateBack关闭当前页面返回上一页面或多级页面
view
navigator url/pages/login/login open-typenavigate跳转到login页/navigator
/view# 默认只能返回一页通过delta 控制返回层级 delta2
navigator open-typenavigateBack跳转到login页/navigator# 4 携带参数
## 4.1 跳转
view
navigator url/pages/login/login?namejustinage19 open-typenavigate跳转到login页/navigator
/view## 4.2 在 onLoad的options中获取参数onLoad(options) {console.log(options)},## 4.3 注意跳转tabbar不能携带参数
2.2 js-跳转–编程式导航
# 1 5 个方法
wx.navigateTo({url: url,
})wx.redirectTo({url: url,
})wx.switchTab({url: url,
})wx.reLaunch({url: url,
})wx.navigateBack()# 2 页面
button typedefault bind:taphandlenavigateTonavigateTo/button
button typewarn bind:taphandleredirectToredirectTo/button
button typeprimary bind:taphandleswitchTabswitchTab/button
button typedefault bind:taphandlereLaunchreLaunch/button
button typewarn bind:taphandlenavigateBacknavigateBack/button# 3 jshandlenavigateTo(){wx.navigateTo({url: /pages/login/login,})},handleredirectTo(){wx.redirectTo({url: /pages/login/login,})},handleswitchTab(){wx.switchTab({url: /pages/my/my,})},handlereLaunch(){wx.reLaunch({url: /pages/login/login,})},handlenavigateBack(){// 关闭当前页面返回上一页或上某一页传入数字wx.navigateBack()wx.navigateBack({delta:2})},【 三 】wxml语法
3.1 模版语法
# 1 在页面 xx.js 的 Page() 方法的 data 对象中进行声明定义
# 2 在xx.wxml 中使用 {{}} 包裹显示数据
# 3 可以显示如下不能编写js语句或js方法-变量-算数运算-三元运算-逻辑判断# 4 只是单纯通过赋值js中变量会变化但是wxml中的页面不会变化没有联动效果需要使用setData()方法修改- 更新数据- 页面更新# 5 setData案例 修改数字
## 5.1 wxml
view
view姓名是{{name}}/view
view年龄是{{age}}/view
button bind:taphandleAddAge plaintrue typeprimary sizemini点击增加年龄/button
/view
##5.2 jshandleAddAge(){//this.data.ageconsole.log(this.data.age)this.setData({age:this.data.age1})},# 6 setData案例 修改对象
## 6.1 wxmlview
view姓名是{{userinfo.name}}/view
view年龄是{{userinfo.age}}/view
view爱好是{{userinfo.hobby}}/view
button bind:taphandleChangeName plaintrue typeprimary sizemini点击修改对象-姓名/button
/view## 6.2 jsdata: {name: justin,age: 19,userinfo: {name: lqz,age: 99}},handleChangeName() {// 增加数据this.setData({userinfo.hobby: 篮球})// 修改数据this.setData({userinfo.name: 彭于晏})// 修改多个数据--》简便方案--》展开运算符// const userinfo {// ...this.data.userinfo,// name: 新名字,// hobby: 乒乓球// }// this.setData({// // userinfo:userinfo// userinfo //简写形式// })// 修改多个数据--》简便方案--assignconst userinfo Object.assign(this.data.userinfo, {name: xxzz,hobby: 烫头})this.setData({// userinfo:userinfouserinfo //简写形式})//删除数据--单个delete this.data.userinfo.name // 页面删除不了需要用setData更新this.setData({userinfo:this.data.userinfo})//删除数据--多个--解构赋值const {name,age,...res}this.data.userinfothis.setData({userinfo:res})},# 7 setData 修改数组
## 7.1 js
data: {names:[刘亦菲,迪丽热巴,古力娜扎,马尔扎哈]},handleChangeList(){//1 增加数组// 1.1 增加再设置值this.data.names.push(亚瑟王)this.setData({names:this.data.names})// 1.2 通过数组拼接// const newListthis.data.names.concat(甄姬)// this.setData({// names:newList// })// 1.3 通过解构赋值const newList[...this.data.names,李白]this.setData({names:newList})// 2 修改数组this.setData({names[1]:justin})// 3 删除数组this.data.names.slice(1)this.setData({names:this.data.names.slice(1)})},
## 7.2 wxml
view wx:for{{names}} wx:keyindex
{{item}}/view
button bind:taphandleChangeList plaintrue typeprimary sizemini修改数组/button# 8 双向数据绑定input checkbox
view!-- 不支持数组和对象 --input typetext model:value{{name}} styleborder:orange solid 1rpx/checkbox model:checked{{isCheck}}/text{{isCheck}}/text
/view
3.2 列表渲染
# 1 基本使用
## 1.1 jsdata: {goodsList:[{id:1001,name:钢笔,price:9},{id:1002,name:铅笔,price:6},{id:1003,name:脸盆,price:99}]},
##1.2 wxmlview
!-- wx:key 提升性能不写会警告 可以用 index或 *this代指item本身 要唯一--
view wx:for{{goodsList}} wx:key*this
!-- 默认每个对象是item默认每个下标是index --
!-- text商品id:{{item.id}}--商品名字:{{item.name}}--商品价格:{{item.price}}/text --
/view
/view
# 2 修改wx:for-index wx:for-item
viewview wx:for{{goodsList}} wx:key*this wx:for-iteminfo
!-- 修改默认index和item--wx:for-index wx:for-item --
text商品id:{{info.id}}--商品名字:{{info.name}}--商品价格:{{info.price}}/text
/view
/view# 3 block
block商品id:{{info.id}}--商品名字:{{info.name}}--商品价格:{{info.price}}/block3.3 条件渲染
# 1 wx:if wx:elif wx:else
viewinput typetext model:value{{score}} styleborder:orange solid 1rpx/view wx:if{{score90score100}}优秀/viewview wx:elif{{score80score90}}良好/viewview wx:elif{{score60score80}}及格/viewview wx:else不及格/view
/view# 2 wx:if 和 hidden
## 2.1 js
showPhoto:true,
showPhotoHidden:truehandleShowPhoto(){this.setData({showPhoto:!this.data.showPhoto})console.log(this.data.showPhoto)},handleShowPhotoHidden(){this.setData({showPhotoHidden:!this.data.showPhotoHidden})},## 2.2 wxml
view
image src/images/b.jpg modewidthFix wx:if{{showPhoto}}/
button bind:taphandleShowPhoto plaintrue typeprimary sizemini显示隐藏图片(if)/button
view/view
image src/images/b.jpg modewidthFix hidden{{showPhotoHidden}}/
button bind:taphandleShowPhotoHidden plaintrue typeprimary sizemini显示隐藏图片(hidden)/button
/view【 四 】发送请求
前端
在项目上线的时候就要在小程序里面进行设置
[小程序 (qq.com)](https://mp.weixin.qq.com/] 里面的服务器域名 如果只是本地测试只需要在 xxx.wxml
!--pages/log/log.wxml--
!-- image src{{src}} mode/
text
{{name}}
/text --
button sizemini typedefault plain classmybutton bindtaphandLoad点我加载数据/buttonswiper
autoplay
interval2000
indicator-dots
indicator-color#00FF00
indicator-active-color#70DB93
circular!-- 解压赋值 --swiper-item wx:for{{bannerList}} wx:key*thisimage src{{item.image}} modewidthFix//swiper-item/swiperxxx.js
// pages/log/log.js
Page({/*** 页面的初始数据*/data: {src : /images/30.jpg,name : maojingyi,bannerList: []},handLoad(){console.log(asd),wx.request({url: http://127.0.0.1:8000/home/banner/,method:GET,data:{},header:{},success:(res){console.log(res.data.results)this.setData({bannerList:res.data.results})},fail:err{console.log(失败)},complete:(){console.log(成功或者失败都会执行代码)}})}})后端
models
from django.db import models# Create your models here.
from lufy.utils.utils_model import BaseModelclass Banner(BaseModel):title models.CharField(max_length16, uniqueTrue, verbose_name名称)image models.ImageField(upload_tobanner, verbose_name图片)link models.CharField(max_length64, verbose_name跳转链接)info models.TextField(verbose_name详情)class Meta:db_table home_bannerverbose_name_plural 轮播图def __str__(self):return self.title
views.py
from django.core.cache import cache# Create your views here.
from rest_framework.viewsets import GenericViewSet
# 引用公共文件夹的数据
from lufy.utils.utils_mixin import APIListModelMixin
# 导入轮播图表
from .models import Banner
from .serializer import Bannerserializer
# 这个就是导入自定义的common_setting的配置文件
from django.conf import settingsfrom utils.utils_response import APIResponsefrom utils.logg import loggerfrom rest_framework.mixins import ListModelMixin
# 引用自定义的视图类
class BannerView(GenericViewSet, ListModelMixin):# is_delete否删除、is_show上架和orders优先级queryset Banner.objects.all().filter(is_deleteFalse, is_showTrue).order_by(orders)[0:settings.BANNER_COUNT]serializer_class Bannerserializerdef list(self, request, *args, **kwargs):# 尝试从缓存中获取banner_listbanner_list cache.get(banner_list)if banner_list is None:logger.info(调用缓存)# 缓存中没有调用mixin或父类的list方法获取数据并序列化response super().list(request, *args, **kwargs)# 假设response.data是我们要缓存的数据banner_list response.data# 将数据放入缓存 这个就是1缓存时间一个小时30秒cache.set(banner_list, banner_list, timeout1 * 30) # 例如缓存1小时# 构造并返回自定义的APIResponse如果需要return APIResponse(resultsbanner_list)
Bannerserializer
from rest_framework import serializers
from .models import Bannerclass Bannerserializer(serializers.ModelSerializer):class Meta:model Bannerfields [id,title, image, link]urls.py
from django.urls import path
from . import views
from .views import BannerView
# 自动生成路由
from rest_framework.routers import SimpleRouter, DefaultRouterrouter SimpleRouter()# 轮播图
# http://127.0.0.1:8000/home/banner/
router.register(banner, BannerView, banner)urlpatterns [# 轮播图# path(banner/, BannerView.as_view()),
]urlpatterns router.urls【 五 】对话框
5.1 模态对话框
##### wxml
button typedefault sizemini bind:tapshowModel弹出模态框/button
### js ###
showModel(){wx.showModal({title: 这是标题,content: 这是内容部分~~,complete: (res) {if (res.cancel) {console.log(用户取消了)}if (res.confirm) {console.log(用户确认了)}}})
}5.2 消息对话框
#### wxml
button typedefault sizemini bind:tapshowToast弹出消息框/button
### js
showToast(){wx.showToast({title: 恭喜您秒杀成功,icon:success,duration:2000})
}【 六 】存储
##### 在调试窗口中可以通过appdata看到当前页面中的变量及变量变化#### wxml####
button typedefault plain bind:taphandleSave存储数据/button
button typeprimary plain bind:taphandleGet获取数据/button
button typedefault plain bind:taphandleDelete删除数据/button
button typeprimary plain bind:taphandleClear清空数据/button
###js### 同步####
handleSave() {wx.setStorageSync(name, justin)wx.setStorageSync(userinfo, {name:lqz,age:19})
},
handleGet() {const namewx.getStorageSync(name)const userinfowx.getStorageSync(userinfo)console.log(name)console.log(userinfo)
},
handleDelete() {wx.removeStorageSync(name)
},
handleClear() {wx.clearStorageSync()
}###js### 异步####
handleSave() {wx.setStorage({key:name,data:justin})wx.setStorage({key:userinfo,data:{name:lqz,age:19}})
},async handleGet() {const name await wx.getStorage({key:name})const userinfo await wx.getStorage({key:userinfo})console.log(name)console.log(userinfo)
},
handleDelete() {wx.removeStorage({key:name})
},
handleClear() {wx.clearStorage()
}ndleGet获取数据 删除数据 清空数据 ###js### 同步#### handleSave() { wx.setStorageSync(‘name’, “justin”) wx.setStorageSync(‘userinfo’, {name:‘lqz’,age:19}) }, handleGet() { const namewx.getStorageSync(‘name’) const userinfowx.getStorageSync(‘userinfo’) console.log(name) console.log(userinfo) }, handleDelete() { wx.removeStorageSync(‘name’) }, handleClear() { wx.clearStorageSync() }
###js### 异步#### handleSave() { wx.setStorage({ key:‘name’, data:“justin” }) wx.setStorage({ key:‘userinfo’, data:{name:‘lqz’,age:19} }) },
async handleGet() { const name await wx.getStorage({key:‘name’}) const userinfo await wx.getStorage({key:‘userinfo’}) console.log(name) console.log(userinfo) }, handleDelete() { wx.removeStorage({key:‘name’}) }, handleClear() { wx.clearStorage() }