Dlingling

Dlingling 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑

个人动态

Dlingling 发布了文章 · 2020-08-12

【flash】html中使用flash

最近看别人的一些代码,里面用到了flash,之前没有用过,这次就学习了下~

<!--[if IE]>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="1200" height="900" id="falshBox">
    <param name="allowScriptAccess" value="sameDomain" />
    <param name="move" value="movie.swf?aname=abc" />
    <param name="FlashVars" value="aname=abc" />
    <param name="quality" value="high" />
    <param name="bgcolor" value="#fffff" />
    <embed data-original="movie.swf" quality="high" bgcolor="#ffffff" width="1200" height="900" name="flash test" align="middle" allowScriptAcccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
<![endif]-->
<!--[if !IE]>-->
<object type="application/x-shockwave-flash" data="movie.swf?aname=abc"  width="1200" height="900">
    <param name="allowScriptAccess" value="sameDomain" />
    <param name="move" value="movie.swf?aname=abc" />
    <param name="FlashVars" value="aname=abc" />
    <param name="quality" value="high" />
    <param name="bgcolor" value="#fffff" />
</object>
<!--<![endif]-->

上面的代码写了IE浏览器的判断,是因为IE10开始基本和现代浏览器一致,如果不写两种判断,那么在不支持embed的浏览器上就会展示两个flash的盒子~

主要说下FlashVars这个字段,很容易可以看出这个是向flash传参,同时也会看到param传入时在资源后面加了参数,但是在资源后加参数,有的浏览器不识别,所以新增了FlashVars,为了兼容浏览器,最好是两个地方都加上参数

我这里就简单记录下吧,想要了解更多的,可以参考我之前查阅的资料~

html向flash传递参数
Flash有关HTML参数详解

查看原文

赞 0 收藏 0 评论 0

Dlingling 发布了文章 · 2020-08-08

【Vue-cli3开始】vue.config.js配置:将请求代理到本地mock的json数据

在开发过程中,前后端的进度不统一,对于前端同学来说,往往需要自己mock json数据来处理接口逻辑,或者直接将请求代理到后端同学的开发机上(如果后端同学ready的话)~
vue-cli2的代理方法网上较多,这里就不介绍了~
vue-cli3开始高度集成,如果我们需要修改一些配置的话,需要在项目根目录下创建vue.config.js来配置~

介绍可见官网devServer,这个介绍比较简单,详细的可参考webpcak的devServer,或者http-proxy-middleware

接下来就来说说如何将请求代理到后端同学的机器上,这种方式比较简单~

// vue.config.js
module.exports = {
    devServer: {
        // 服务启动后是否自动打开浏览器
        open: true,
        // 域名
        host: '127.0.0.1',
        // 端口
        port: 8000,
        // 代理
        proxy: {
            // 可为不同的接口配置不同的代理地址
            '/user': {
                // 服务地址,即你要访问的服务器地址
                target: 'http://192.100.10.2:8000/',
                // 路径重写,将'/user/login'重写为'/login'
                pathRewrite: {
                    '^/user': ''
                },
                // 所有信息都在命令行工具打印
                logLevel: 'debug'
            },
            '/goods': {
                // 服务地址,即你要访问的服务器地址
                target: 'http://192.100.10.10:8000/',
                // 路径重写,将'/goods/list'重写为'/list'
                pathRewrite: {
                    '^/goods': ''
                }
            }
        }
    }
}

但是,大多数情况下,前端同学是需要自己写json数据的,上面的代理方式更适合联调阶段~下面就来说如何读取本地json数据

// vue.config.js
const path = require('path');

module.exports = {
    devServer: {
        before(app) {
            // 根据你的url规则来定
            app.all('/api/*', (req, res) => {
                // 根据你的json数据地址来适配,是否和请求url完全一致
                const url = req.path.replace('/api', '');
                // json数据
                const filePath = `/public/mock/${url}.json`;
                // json数据绝对地址
                const abPath = path.join(__dirname, filePath);
                const data = require(abPath);
                res.json(data);
            })
        }
    }
}

熟悉webpack的同学,看到这个是不是感觉很亲切~这里就是按照webpcak的devServer文档配置的~

好了,就到这里吧,这个问题搞了两天,搜了好多内容,终于搞定了~

查看原文

赞 1 收藏 1 评论 0

Dlingling 发布了文章 · 2020-08-06

git clone时出现RPC failed; curl 56 OpenSSL SSL_read

1.问题描述

在使用git clone项目时报错:error: RPC failed; curl 56 OpenSSL SSL_read: Connection was reset, errno 10054

2.解决方法

输入以下3个命令:
> git init
> git config http.postBuffer 524288000
> git config http.sslVerify "false"

3.问题解决

转载自:
【GIT】clone时出现RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errfno 10054

查看原文

赞 1 收藏 0 评论 0

Dlingling 发布了文章 · 2020-04-05

webpack学习笔记—plugins

plugins来啦~plugins是为了解决loader无法解决的事情~
plugins:Array
插件可以携带参数/选项,在config配置中,向plugins传入new实例。下面列举了一些常用plugin~

1.html-webpack-plugin:html入口文件
这个插件主要有两个用处:
1). 为html文件引入外部资源,如打包生成的js、css等,每次构建后不需要自己手动修改;
2). 生成创建html文件,一个html文件对应一个入口,可以配置N个html-webpack-plugin生成N个入口~也可以通过函数批量生成~

// html入口
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    plugins: [
        // 单个入口配置
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'src/index.html'),
            filename: 'search.html',
            // 使用chunk,与注入的打包好的文件名对应
            chunks: ['search'],
            // 打包出的chunk自动注入
            inject: true,
            minify: {
                html5: true,
                // 删除空格和换行符,若preserveLineBreaks参数设为true,则保留了换行符
                collapseWhitespace: true,
                preserveLineBreaks: false,
                minifyCSS: true,
                minifyJS: true,
                removeComments: false
            }
        })
    ]
};

以上是单个入口的配置,若需要配置多个入口呢?可以依次添加多个,也可以通过函数生成,类似多文件入口的做法,在之前的entry篇提到过,这次就在之前函数的基础上进行扩展~

const setMPA = () => {
    const entry = {};
    const htmlWebpackPlugins = [];

    const entryFiles = glob.sync(path.join(__dirname, './src/*/index.js'));
    Object.keys(entryFiles).map(index => {
        const entryFile = entryFiles[index];
        const match = entryFile.match(/src\/(.*)\/index\.js/);
        const pageName = match && match[1];
        entry[pageName] = entryFile;
        const htmlWebpackPlugin = new HtmlWebpackPlugin({
            template: path.join(__dirname, `src/${pageName}/index.html`),
            filename: `${pageName}.html`,
            // 使用chunk
            chunks: [pageName],
            // 打包出的chunk自动注入
            inject: true,
            minify: {
                html5: true,
                // 删除空格和换行符,若preserveLineBreaks参数设为true,则保留了换行符
                collapseWhitespace: true,
                preserveLineBreaks: false,
                minifyCSS: true,
                minifyJS: true,
                removeComments: false
            }
        });
        htmlWebpackPlugins.push(htmlWebpackPlugin);
    });
    return {
        entry,
        htmlWebpackPlugins
    };
};

const {entry, htmlWebpackPlugins} = setMPA();

// 直接在plugins的值上进行拼接
module.exports = {
    plugins: [].concat(htmlWebpackPlugins)
};

2.optimize-css-assets-webpack-plugin:压缩CSS
配合cssnano使用,对CSS做多方面的优化,保证最终生成的文件体积是最小的。

// css压缩
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

plugins: [
    new OptimizeCSSAssetsPlugin({
        assetNameRegExp: /\.css$/g,
        cssProcessor: require('cssnano')
    })
]

3.mini-css-extract-plugin:抽离CSS为单独文件

// 将CSS抽离成单独文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports ={
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name]_[contenthash:8].css'
        })
    ]  
};

使用时需要和loader结合使用,解析CSS时先用CSS-loader进行解析,然后通过MiniCssExtractPlugin.loader将CSS抽离成单独文件~在服务端渲染推荐使用~

4.clean-webpack-plugin:清理构建产物
每次打包都会生成dist文件夹,执行构建之前不删除的话,dist目录会越来越大~解决这种请求,有两种方法:
1).在package.json中配置命令

// package.json
"scripts": {
    "build": "rm -rf ./dist && build"
}

2).使用插件clean-webpack-plugin
注意:node v8.0+ && webpack v3.0+

// 清理构建产物,新版按需引入,不能直接引入
// TypeError: CleanWebpackPlugin is not a constructor
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

plugins: [
    new CleanWebpackPlugin()
]

这里,需要注意下版本~老版本可以直接引入,新版需要按需引入~目前我引用的是3.0版本,需要按需引入~大家使用的时候可以注意下,如果比3.0版本旧的话,可以先尝试直接引入,如果报错TypeError: CleanWebpackPlugin is not a constructor,再修改为按需引入~

5.html-webpack-externals-plugin:基础库不打包,直接CDN引入
开发时,有时候需要引入一些基础库,如react开发时,每个组件都需要引入react和react-dom,我们打包时这两个基础库体积较大,导致构建出来的包提交变大~这个时候,我们可以考虑将react和react-dom在html中用CDN引入~

// wepack.config.js
// 基础库不打包,直接CDN引入
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');

module.exports = {
    new HtmlWebpackExternalsPlugin({
        externals: [
            {
                module: 'react',
                entry: 'https://11.url.cn/now/lib/16.2.0/react.min.js',
                global: 'React'
            },
            {
                module: 'react-dom',
                entry: 'https://11.url.cn/now/lib/16.2.0/react-dom.min.js',
                global: 'ReactDOM'
            }
        ]
    })
};

// index.html
<script type="text/javascript" data-original="https://11.url.cn/now/lib/16.2.0/react.min.js"></script>
<script type="text/javascript" data-original="https://11.url.cn/now/lib/16.2.0/react-dom.min.js"></script>

6.friendly-errors-webpack-plugin:构建日志优化提示
执行构建时,每次都输出好多内容,有的时候,我们其实是不关注构建过程和构建结果的,只关心构建是否成功。这个插件就是一个不错的选择~

// 构建日志优化提示
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');

module.exports = {
    plugins: [
        new FriendlyErrorsWebpackPlugin()
    ]
};

还有一种方式可以改变输出内容,配置stats

module.exports = {
    stats: 'errors-only'
};

如果使用了webpack-dev-server,则stats这个配置项需要放在devServer中~

devServer: {
    contentBase: './dist/',
    hot: true,
    stats: 'errors-only'
}

暂时就到这里了~源码请移步demo

查看原文

赞 1 收藏 1 评论 0

Dlingling 发布了文章 · 2020-04-04

webpack学习笔记—module

继entry之后,module来了~

module配置如何处理模块。
通过loader可以支持各种语言和预处理器编写模块,一些常用loader如下:

// webpack.config.js

// 将CSS抽离成单独文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/,
                use: [
                    // 支持ES6
                    'babel-loader',
                    // 加入eslint检查
                    'eslint-loader'
                ]
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader, // 和style-loader互斥
                    // 'style-loader', // 创建style标签,链式调用,从右到左
                    'css-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader, // 和style-loader互斥
                    // 'style-loader', // 创建style标签,链式调用,从右到左
                    'css-loader',
                    'less-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: () => [
                                // 浏览器支持版本控制在package.json browserslist
                                require('autoprefixer')()
                                // require('autoprefixer')({

                                    browsers: \['last 2 version', '>1%', 'ios 7'\]

                                })
                            ]
                        }
                    },
                    {
                        loader: 'px2rem-loader',
                        options: {
                            // 1rem = 75px
                            remUnit: 75,
                            // 小数点位数
                            remPrecesion: 8
                        }
                    }
                ]
            },
            {
                test: /\.(png|jpg|gif|jpeg)$/,
                use: [
                    {
                        // 单独文件
                        loader: 'file-loader',
                        options: {
                            name: '[name]_[hash:8].[ext]'
                        }
                    }
                ]
            },
            // {
            //     test: /\.(png|svg|gif|jpg|jpeg)$/,
            //     use: [
            //         {
            //                 // 内联在代码中
            //             loader: 'url-loader',
            //             options: {
            //                 limit: 10240 // B
            //             }
            //         }
            //     ]
            // },
            {
                test: /\.(otf|woff2|eot|ttf|woff)$/,
                use: [
                    'file-loader'
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name]_[contenthash:8].css'
        })
    ]
};

// package.json
"browserslist": [
    "last 2 version",
    "> 1%",
    "ios 7"
]

各个loader的用法都在注释里~

解析ES6的loader,需要新增一个.babelrc文件配置一下~

// .babelrc

{
    "presets": [
        // 支持ES6
        "@babel/preset-env"
    ]
}

配置eslint检查,同样需要新增一个.eslintrc.js文件配置~具体配置可见ESlint

// .eslintrc.js
module.exports = {
    parser: 'babel-eslint',
    // 继承哪个规则
    // extends: '',
    rules: {
        semi: 'warn'
    },
    env: {
        brower: true,
        node: true
    }
};

上面提到了一个mini-css-extract-plugin插件,这个插件是将解析好的CSS单独抽离成一个文件,style-loader是在html中创建一个style标签,所以,这两个是互斥的~插件形式也适用于SSR服务端渲染打包,因为没有document对象~之后在SSR打包中也会提到这点~

最后再说一个autoprefixer,这个由于版本不同,写法有一些不一样~最新版本建议把browserslist写在package.json,老版本直接在引用时传入~这块在上面代码有所提现,大家可以注意下~

就到这里了,列举了一些常用loader,说明比较少,更为详细的用法或者需要更多的loader可以在npm官网或者webpack官网查看~
直接上代码了~可以移步Demo

查看原文

赞 0 收藏 0 评论 0

Dlingling 发布了文章 · 2020-04-04

webpack学习笔记—entry

最近在系统学习webpack,记录一些小芝士点~
入口起点(entry points)
entry:String|Array<String>|Object
1.单个入口

module.exports = {
    entry: './src/index.js'
    
    // 指定打包输出文件名
    // entry: {
    //     index: './src/index.js'
    // }
};

webpack官网释义:当你向entry传入一个数组时会发生什么?entry属性传入「文件路径(file path)数组」将创建“多个主入口(multi-main entry)”。在你想要多个依赖文件一起注入,并且将它们的依赖导向(graph)到一个“chunk”时,传入数组的方式就很有用。

2.多个入口

module.exports = {
    entry: {
        index: './src/index.js',
        search: './src/search.js'
    }
};

如上配置,打包出的文件有多个入口,适合多页面应用打包

但是这样配置,有一个问题:之后新增一个页面,就要修改entry,能不能写个方法自动读取呢?

const path = require('path');
const glob = require('glob');

const setMPA = () => {
    const entry = {};

    // 入口文件路径
    const entryFiles = glob.sync(path.join(__dirname, './src/*/index.js'));
    Object.keys(entryFiles).map(index => {
        const entryFile = entryFiles[index];
        const match = entryFile.match(/src\/(.*)\/index\.js/);
        const pageName = match && match[1];
        entry[pageName] = entryFile;
    });
    return {
        entry
    };
};

// 引入entry
const {entry} = setMPA();

module.exports = {
    entry: entry
};

好了,以上就是entry的一些小记录了~具体可移步Demo

查看原文

赞 0 收藏 0 评论 0

Dlingling 发布了文章 · 2020-03-18

CSS使元素水平垂直居中

1.使用弹性布局

// 父元素设置
display: flex;
justify-content: center;
align-items: center;

2.position绝对定位

position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;

3.使用position定位和translate变换

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

4.知道元素宽高,使用position定位和calc()

width: 100px;
height: 100px;
position: absolute;
left: calc(50% - 50px);
top: calc(50% - 50px);

5.知道元素宽高,使用position定位

width: 100px;
height: 100px;
position: aboslute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;

6.行内元素水平垂直居中,使用display:table-cell和vertical-align:middle

// 父元素设置
display: table-cell;
vertical-align: middle;

7.文字水平垂直居中

text-alignn: center;
line-height: 父元素高度
查看原文

赞 0 收藏 0 评论 0

Dlingling 发布了文章 · 2020-02-17

node+multer实现图片上传

最近在学习node实现一个后台管理系统,用到了图片上传,有一些小问题记录一下~
直接上代码,问题都记录在注释里~

const express = require('express');
const path = require('path');
const multer = require('multer');
const app = new express();

// 设置静态目录 第一个参数为虚拟的文件前缀,实际上文件系统中不存在
// 可以用public做为前缀来加载static文件夹下的文件了
app.use('/public', express.static(path.join(__dirname, './static')));

// 根据当前文件目录指定文件夹
const dir = path.resolve(__dirname, '../static/img');
// 图片大小限制KB
const SIZELIMIT = 500000;

const storage = multer.diskStorage({
    // 指定文件路径
    destination: function(req, file, cb) {
        // !!!相对路径时以node执行目录为基准,避免权限问题,该目录最好已存在*
        // cb(null, './uploads');
        cb(null, dir);
    },
    // 指定文件名
    filename: function(req, file, cb) {
        // filedname指向参数key值
        cb(null, Date.now() + '-' + file.originalname);
    }
});

const upload = multer({
    storage: storage
});

app.post('/upload', upload.single('file'), (req, res) => {
    // 即将上传图片的key值 form-data对象{key: value}
    // 检查是否有文件待上传
    if (req.file === undefined) {
        return res.send({
            errno: -1,
            msg: 'no file'
        });
    }
    const {size, mimetype, filename} = req.file;
    const types = ['jpg', 'jpeg', 'png', 'gif'];
    const tmpTypes = mimetype.split('/')[1];
    // 检查文件大小
    if (size >= SIZELIMIT) {
        return res.send({
            errno: -1,
            msg: 'file is too large'
        });
    }
    // 检查文件类型
    else if (types.indexOf(tmpTypes) < 0) {
        return res.send({
            errno: -1,
            msg: 'not accepted filetype'
        });
    }
    // 路径可根据设置的静态目录指定
    const url = '/public/img/' + filename;
    res.json({
        errno: 0,
        msg: 'upload success',
        url
    });
});

app.listen(3000, () => {
    console.log('service start');
});

附上文档参考链接:
express框架
path模块
multer
最后再附赠一个node自动重启工具nodemon

查看原文

赞 0 收藏 0 评论 0

Dlingling 发布了文章 · 2020-02-04

Mac环境安装、启动MongoDB

一、安装
官网下载安装需要输入邮箱等信息,可以用命令行安装。Mac安装如下

// 进入 
/usr/local cd /usr/local  
// 下载 
sudo curl \-O https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86\_64-4.0.9.tgz  
// 解压 
sudo tar \-zxvf mongodb\-osx\-ssl\-x86\_64\-4.0.9.tgz  
// 重命名为 mongodb 目录 
sudo mv mongodb\-osx\-x86\_64\-4.0.9/ mongodb

更多安装方法可参考菜鸟教程
安装完成后,设置环境变量,即将MongoDB的二进制命令文件目录添加到PATH中:
终端中输入以下命令

vi ~/.bash_profile
// i键进入insert模式
export PATH=/usr/local/mongodb/bin:$PATH
//Esc退出编辑,:wq保存退出
// 立即生效
source /.bash_profile
// 查看环境变量的值
echo $PATH

二、启动
MongoDB数据存放的默认路径为/data/db(即根目录下/data/db),但该目录在你的电脑不一定存在,可以手动创建

sudo mkdir -p /data/db

直接用命令行启动

mongod

这时发现/data/db是一个只读的,由于数据库需要读写数据,若没有root权限,根目录下创建的文件夹默认是没有写入权限的。可以通过以下命令修改

sudo chown -R 用户名 /data/db

若想绕开权限问题,也可以不在根目录创建data文件夹!!!
再次输入命令

mongod

若看到
MacHi 2020-02-04 11-56-14.png
证明启动服务成功。

三、操作
开启MongoDB服务后,当前命令面板无法进行其他操作,再打开一个新的命令面板。输入以下命令进入操作模式

mongo

四、命令

// 显示数据库列表
show dbs

好了,简单的介绍到这里了~欢迎大家留言交流补充~

查看原文

赞 0 收藏 0 评论 0

Dlingling 发布了文章 · 2019-11-15

taro小程序添加骨架屏

最近做了一些小程序方面的性能优化,如分包加载,添加骨架屏等,这次主要说一下骨架屏的相关内容。
关于骨架屏,有三种方法:
1.直接请UI同学帮忙P张图,当做loading图放上去。这种方法简单粗暴,但是需要请人帮忙~
2.根据每个页面,自己写一套相同的代码来覆盖样式。这种方法的工程量,你懂的~
3.能不能写个组件呢?该组件自动获取元素位置大小信息来渲染,数据返回后将其卸载。

下面主要说第三种方法~
主框架采用taro,一套代码兼容多端,但是今天这个代码,需要考虑兼容性~
根据上面的思路,我们首先要找到骨架屏的容器,然后找到需要P成灰色的元素,获取该元素的位置大小信息,最后就是渲染了~
获取元素,taro提供了API,Taro.createSelectorQuery()。通过这个API返回一个SelectorQuery对象实例,然后再通过selectAll()来查找骨架中带有特定类的class名,查找之后通过boundingClientRect()获取元素的位置大小信息,把这些信息存放在数组中。
我这边写了两个类,一个是skeleton-radius,渲染圆形;一个是skeleton-rect,渲染长方形。后续大家可以自行扩展。
文字有点多,大家可能看着有点云里雾里的,下面上代码~

    // 百度小程序目前不支持跨自定义组件的后代选择器: >>>
    // 但是H5使用后代选择器(.the-ancestor .the-descendant)的时候,可以自动识别自定义组件内的后代
    // 微信小程序支持跨自定义组件都后代选择器(.the-ancestor >>> .the-descendant),可修改为如`.${this.props.selector} >>> .${this.props.selector}-radius`
    if (process.env.TARO_ENV === 'weapp') {
        Taro.createSelectorQuery().selectAll(`.${this.props.selector} >>> .${this.props.selector}-radius`)
            .boundingClientRect().exec(rect => {
                that.setState({
                    radiusList: rect[0]
                });
            });
    }
    else {
        Taro.createSelectorQuery().selectAll(`.${this.props.selector} .${this.props.selector}-radius`)
        .boundingClientRect().exec(rect => {
            that.setState({
                radiusList: rect[0]
            });
        });
    }

大家也看到上面的注释了,如果要在多端运行,可先判断环境,根据环境使用不同的选择器。上面代码是实现一个圆形的灰色区域~大家如果有多个形状的需求的话,可以简单封装一个函数,这里我就不再细说了,具体的可以到Demo详细查看~
细说一下后代选择器的兼容性问题:

  1. 百度小程序目前不支持跨自定义组件的后代选择器: >>>。
  2. 但是H5使用后代选择器(.the-ancestor .the-descendant)的时候,可以自动识别自定义组件内的后代。使用自定义组件时,外层是否有元素包裹,都可识别到自定义组件内部的指定类选择器。
  3. 微信小程序支持跨自定义组件的后代选择器(.the-ancestor >>> .the-descendant),但使用自定义组件时,外层不能嵌套元素,否则无法识别。

接下来就是渲染了,这个比较简单,直接上代码~这里背景色和将要P成条状等的元素的背景色都可以在使用组件时自定义传入,也可以不传,有默认色~

  <View className='skeleton-container' style={{background: `${bgColor}`}}>
            {
                radiusList.map(radiusItem => (
                    <View className='skeleton-item skeleton-item-radius' style={{width: `${radiusItem.width}PX`, height: `${radiusItem.height}PX`,
                        background: `${itemColor}`, top: `${radiusItem.top}PX`, left: `${radiusItem.left}PX`}}
                    />
                ))
            }
            {
                rectList.map(rectItem => (
                    <View className='skeleton-item' style={{width: `${rectItem.width}PX`, height: `${rectItem.height}PX`,
                        background: `${itemColor}`, top: `${rectItem.top}PX`, left: `${rectItem.left}PX`}}
                    />
                ))
            }
        </View>

到这里,组件已经完成了,使用的时候可以直接引入组件,然后传入selector就可以了,注意,由于数据是动态获取的,页面开始为空,这里就需要mock一些假数据来填充页面了~要覆盖的元素类名必须和组件中的图形类保持一致~

   <View className='container' style={{fontSize: '20PX'}}>
            {
                showSkeleton && <Skeleton
                    selector='skeleton'
                    bgColor='pink'
                    itemColor='skyblue'
                />
            }
            <View className='skeleton'>
                <View className='userInfo'>
                    <Image
                        data-original={userInfo.avatarUrl}
                        alt='用户头像'
                        className='userInfo-avatar skeleton-radius'
                    />
                    <Text>{userInfo.nickName}</Text>
                </View>
                <View>
                    {
                        list.map(item => (
                            <View className='skeleton-rect' style={{marginBottom: '30PX'}}>{item}</View>
                        ))
                    }
                </View>
                {/* 自定义组件外层最好没有元素包裹,否则微信小程序无法识别,但是H5可以识别 */}
                <List />
            </View>
        </View>

看到注释了吗?使用自定义组件时一定要注意噢~自定义组件若被元素包裹,微信小程序无法识别到自定义组件内的图形类!!!

最后要说一下适合使用骨架屏的场景:页面结构简单,元素的宽高固定~若元素宽高不固定的话,你写的mock假数据可能和实际渲染出来的页面差距较大,例如瀑布流~

好了,这次的一些收获就到这里了~大家如果有更好的方法,可以留言交流~最后,附上完整的代码地址~

查看原文

赞 0 收藏 0 评论 0

认证与成就

  • 获得 5 次点赞
  • 获得 1 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 1 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2019-06-29
个人主页被 1.3k 人浏览