首页 > 应用开发 > IT综合 > kbone 高级 - 使用小程序内置组件(一)
1、用法
需要明确的是,如果没有特殊需求的话,请尽量使用 html 标签来编写代码,使用内置组件时请按需使用。这是因为绝大部分内置组件外层都会被包裹一层自定义组件,如果自定义组件的实例数量达到一定量级的话,理论上是会对性能造成一定程度的影响,所以对于 view、text、image 等会被频繁使用的内置组件,如果没有特殊需求的话请直接使用 div、span、img 等 html 标签替代。
部分内置组件可以直接使用 html 标签替代,比如 input 组件可以使用 input 标签替代。目前已支持的可替代组件列表:
<
input /> --> input 组件
<
input
type=
"radio" /> --> radio 组件
<
input
type=
"checkbox" /> --> checkbox 组件
<
label>
<
label> --> label 组件
<
textarea>
</
textarea> --> textarea 组件
<
img /> --> image 组件
<
video>
</
video> --> video 组件
<
canvas>
</
canvas> --> canvas 组件
还有一部分内置组件在 html 中没有标签可替代,那就需要使用 wx-component 标签或者使用 wx- 前缀,基本用法如下:
<!-- wx-component 标签用法 -->
<
wx-component
behavior=
"picker"
mode=
"region" @
change=
"onChange">选择城市
</
wx-component>
<
wx-component
behavior=
"button"
open-type=
"share" @
click=
"onClickShare">分享
</
wx-component>
<!-- wx- 前缀用法 -->
<
wx-picker
mode=
"region" @
change=
"onChange">选择城市
</
wx-picker>
<
wx-button
open-type=
"share" @
click=
"onClickShare">分享
</
wx-button>
如果使用 wx-component 标签表示要渲染小程序内置组件,然后 behavior 字段表示要渲染的组件名;其他组件属性传入和官方文档一致,事件则采用 vue 的绑定方式。
wx-component 或 wx- 前缀已支持内置组件列表:
内置组件的子组件会被包裹在一层自定义组件里面,因此内置组件和子组件之间会隔着一层容器,该容器会追加 h5-virtual 到 class 上(除了 view、cover-view、text、scroll-view 和 picker-view 组件外,因为这些组件需要保留子组件的结构,所以沿用 0.x 版本的渲染方式)。
0.x 版本:在 0.x 版本中,绝大部分内置组件在渲染时会在外面多包装一层自定义组件,可以近似认为内置组件和其父级节点中间会多一层 div 容器,所以会对部分样式有影响。这个 div 容器会追加一个名为 h5-xxx 的 class,例如使用 video 组件,那么会在这个 div 容器上追加一个名为 h5-video 的 class,以便对其做特殊处理。另外如果是用 wx-component 或是 wx- 前缀渲染的内置组件,会在容器追加的 class 是 h5-wx-component,为了更方便进行识别,这种情况会再在容器额外追加 wx-xxx 的 class。
生成的结构大致如下:
<!-- 源码 -->
<
div>
<
canvas>
<
div>
</
div>
<
div>
</
div>
</
canvas>
<
wx-map>
<
div>
</
div>
<
div>
</
div>
</
wx-map>
<
wx-scroll-view>
<
div>
</
div>
<
div>
</
div>
</
wx-scroll-view>
</
div>
<!-- 1.x 版本生成的结构 -->
<
view>
<
canvas
class=
"h5-canvas wx-canvas wx-comp-canvas">
<
element
class=
"h5-virtual">
<
cover-view>
</
cover-view>
<
cover-view>
</
cover-view>
</
element>
</
canvas>
<
map
class=
"h5-wx-component wx-map wx-comp-map">
<
element
class=
"h5-virtual">
<
cover-view>
</
cover-view>
<
cover-view>
</
cover-view>
</
element>
</
map>
<
element
class=
"h5-wx-component wx-scroll-view">
<
scroll-view
class=
"wx-comp-scroll-view">
<
view>
</
view>
<
view>
</
view>
</
scroll-view>
</
element>
</
view>
<!-- 0.x 版本本生成的结构 -->
<
view>
<
element
class=
"h5-canvas">
<
canvas
class=
"wx-comp-canvas">
<
cover-view>
</
cover-view>
<
cover-view>
</
cover-view>
</
canvas>
</
element>
<
element
class=
"h5-wx-component wx-map">
<
map
class=
"wx-comp-map">
<
cover-view>
</
cover-view>
<
cover-view>
</
cover-view>
</
map>
</
element>
<
element
class=
"h5-wx-component wx-scroll-view">
<
scroll-view
class=
"wx-comp-scroll-view">
<
view>
</
view>
<
view>
</
view>
</
scroll-view>
</
element>
</
view>
PS:button 标签不会被渲染成 button 内置组件,同理 form 标签也不会被渲染成 form 内置组件,如若需要请按照上述原生组件使用说明使用。
PS:因为自定义组件的限制,movable-area/movable-view、swiper/swiper-item、picker-view/picker-view-column 这三组组件必须作为父子存在才能使用,比如 swiper 组件和 swiper-item 必须作为父子组件才能使用,如:
<
wx-swiper>
<
wx-swiper-item>A
</
wx-swiper-item>
<
wx-swiper-item>B
</
wx-swiper-item>
<
wx-swiper-item>C
</
wx-swiper-item>
</
wx-swiper>
PS:默认 canvas 内置组件的 touch 事件为通用事件的 Touch 对象,而不是 CanvasTouch 对象,如果需要用到 CanvasTouch 对象的话可以改成监听 canvastouchstart、canvastouchmove、canvastouchend 和 canvastouchcancel 事件。
PS:原生组件的表现在小程序中表现会和 web 端标签有些不一样,具体可参考原生组件说明文档。
PS:原生组件下的子节点,div、span 等标签会被渲染成 cover-view,img 会被渲染成 cover-image,如若需要使用 button 内置组件请使用 wx-component 或 wx- 前缀。
PS:如果将插件配置 runtime.wxComponent 的值配置为 noprefix,则可以用不带前缀的方式使用内置组件。
PS:某些 Web 框架(如 react)会强行将节点属性值转成字符串类型。对于普通类型数组(如 wx-picker 组件的 value 属性),字符串化会变成,连接,kbone 会自动做解析,开发者无需处理;对于对象数组(如 wx-picker 组件的 range 属性),如遇到被自动转成字符串的情况,开发者需要将此对象数组转成 json 串传入。
2、案例
在 kbone-advanced 目录下创建 03-native-components 目录。本案例在这个目录下实现。
2.1 创建 package.json
cd
03-
native-components
npm
init -y
编辑 package.json:
{
"scripts": {
"mp":
"cross-env NODE_ENV=production webpack --config build/webpack.mp.config.js --progress --hide-modules"
},
"dependencies": {
"vue":
"^2.5.11"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": {
"babel-core":
"^6.26.0",
"babel-loader":
"^7.1.2",
"babel-preset-env":
"^1.6.0",
"babel-preset-stage-3":
"^6.24.1",
"cross-env":
"^5.0.5",
"css-loader":
"^0.28.7",
"extract-text-webpack-plugin":
"^3.0.2",
"file-loader":
"^1.1.4",
"html-webpack-plugin":
"^4.0.0-beta.5",
"mini-css-extract-plugin":
"^0.5.0",
"optimize-css-assets-webpack-plugin":
"^5.0.1",
"stylehacks":
"^4.0.3",
"vue-loader":
"^15.7.0",
"vue-template-compiler":
"^2.6.10",
"webpack":
"^4.29.6",
"webpack-cli":
"^3.2.3",
"mp-webpack-plugin":
"latest"
}
}
安装依赖包:
npm install
2.2 配置 webpack
在 03-native-components 目录下创建 build 文件夹,在文件夹下创建 webpack.mp.config.js 文件,内容如下:
const
path
=
require('path')
const
webpack
=
require('webpack')
const
MiniCssExtractPlugin
=
require('mini-css-extract-plugin')
const
{
VueLoaderPlugin
}
=
require('vue-loader')
const
OptimizeCSSAssetsPlugin
=
require('optimize-css-assets-webpack-plugin');
const
TerserPlugin
=
require('terser-webpack-plugin')
const
MpPlugin
=
require('mp-webpack-plugin')
//
用于构建小程序代码的
webpack
插件
const
isOptimize
=
false
//
是否压缩业务代码,开发者工具可能无法完美支持业务代码使用到的
es
特性,建议自己做代码压缩
module.exports
=
{
mode:
'production'
,
entry:
{
index:
path.resolve(__dirname,
'../src/index/main.mp.js'
),
},
output:
{
path:
path.resolve(__dirname,
'../dist/mp/common'
),
//
放到小程序代码目录中的
common
目录下
filename:
'[name].js'
,
//
必需字段,不能修改
library:
'createApp'
,
//
必需字段,不能修改
libraryExport:
'default'
,
//
必需字段,不能修改
libraryTarget:
'window'
,
//
必需字段,不能修改
},
target:
'web'
,
//
必需字段,不能修改
optimization:
{
runtimeChunk:
false
,
//
必需字段,不能修改
splitChunks:
{
//
代码分隔配置,不建议修改
chunks:
'all'
,
minSize:
1000
,
maxSize:
0
,
minChunks:
1
,
maxAsyncRequests:
100
,
maxInitialRequests:
100
,
automaticNameDelimiter:
'~'
,
name:
true
,
cacheGroups:
{
vendors:
{
test:
/[\\/]node_modules[\\/]/,
priority:
-10
},
default:
{
minChunks:
2
,
priority:
-20
,
reuseExistingChunk:
true
}
}
},
minimizer:
isOptimize
?
[
//
压缩CSS
new
OptimizeCSSAssetsPlugin({
assetNameRegExp:
/\.(css|wxss)$/g,
cssProcessor:
require('cssnano'),
cssProcessorPluginOptions:
{
preset:
['default',
{
discardComments:
{
removeAll:
true
,
},
minifySelectors:
false
,
//
因为
wxss
编译器不支持
.some>:first-child
这样格式的代码,所以暂时禁掉这个
}],
},
canPrint:
false
}),
//
压缩
js
new
TerserPlugin({
test:
/\.js(\?.*)?$/i,
parallel:
true
,
})
]
:
[],
},
module:
{
rules:
[
{
test:
/\.css$/,
use:
[
MiniCssExtractPlugin.loader,
'css-loader'
],
},
{
test:
/\.vue$/,
loader:
'vue-loader'
,
},
{
test:
/\.js$/,
use:
[
'babel-loader'
],
exclude:
/node_modules/
},
{
test:
/\.(png|jpg|gif|svg)$/,
loader:
'file-loader'
,
options:
{
name:
'[name].[ext]?[hash]'
}
}
]
},
resolve:
{
extensions:
['*',
'.js'
,
'.vue'
,
'.json'
]
},
plugins:
[
new
webpack.DefinePlugin({
'process.env.isMiniprogram':
process.env.isMiniprogram,
//
注入环境变量,用于业务代码判断
}),
new
MiniCssExtractPlugin({
filename:
'[name].wxss'
,
}),
new
VueLoaderPlugin(),
new
MpPlugin(require('./miniprogram.config.js')),
],
}
在 03-native-components 文件夹下创建 miniprogram.config.js 文件,内容如下:
module.exports
=
{
origin:
'https://test.miniprogram.com'
,
entry:
'/'
,
router:
{
index:
[
'/'
,
],
},
redirect:
{
notFound:
'index'
,
accessDenied:
'index'
,
},
generate:
{
appWxss:
'none'
,
//
构建完成后是否自动安装小程序依赖。'npm':使用
npm
自动安装依赖
autoBuildNpm:
'npm'
},
runtime:
{
//
wxComponent:
'noprefix'
,
wxComponent:
'default'
},
app:
{
navigationBarTitleText:
'miniprogram-project'
,
},
projectConfig:
{
appid:
''
,
projectname:
'native-components'
,
},
packageConfig:
{
author:
'Felixlu'
,
},
}
2.3 创建 index.html
在 03-native-components 目录下创建 index.html 文件,内容如下:
<!DOCTYPE
html>
<
html
lang=
"en">
<
head>
<
meta
charset=
"utf-8">
<
meta
name=
"viewport"
content=
"width=device-width, initial-scale=1, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no,minimal-ui, viewport-fit=cover" />
<
meta
content=
"yes"
name=
"apple-mobile-web-app-capable"/>
<
meta
content=
"black"
name=
"apple-mobile-web-app-status-bar-style"/>
<
meta
name=
"format-detection"
content=
"telephone=no, email=no" />
<
title>vue
</
title>
<
style
type=
"text/css">
#app {
font-family:
'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color:
#2c3e50;
margin-top:
60px;
}
</
style>
</
head>
<
body>
<
div
id=
"app">
</
div>
</
body>
</
html>
2.4 创建小程序入口文件
在 03-native-components/src/index 目录下创建 main.mp.js 小程序入口文件,内容如下:
import Vue
from
'vue'
import App
from
'./App.vue'
export
default
function
createApp(
) {
const container =
document.createElement(
'div')
container.id =
'app'
document.body.appendChild(container)
return
new Vue({
el:
'#app',
render:
h => h(App)
})
}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69923331/viewspace-2711464/ ,如需转载,请注明出处,否则将追究法律责任。