react组件转换成vue组件(1)

今天完成了一个 react 组件的 vue 化–vue-lazyload-pic

顺手重新撸了一把 vue

vue 的模版语法写的我实在蛋疼所以直接上了 jsx 语法,也方便双向绑定
方法:
(1): 增加两个插件
yarn add @vue/babel-helper-vue-jsx-merge-props
yarn add @vue/babel-preset-jsx

(2): 在.babelrc文件内做如下修改:

1
2
3
{
"presets": ["@vue/babel-preset-jsx"]
}

就可以快乐的使用 jsx 语法了

例子: vue-lazyload-pic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
render() {
const that = this;
const { imgLoaded, imgClassName, img, alt, skeleton } = that;
const onLoad = () => {
that.$emit('onloads', true);
};

return (
<div class="P-container">
{imgLoaded ? (
<img class={ClassNames('defaultImg', imgClassName)} src={img} alt={alt} />
) : (
<div class={ClassNames('skeleton1', skeleton)}></div>
)}
<img class="noShow" src={img} alt={alt} onLoad={onLoad} />
</div>
);
},

上面代码 有个注意点就是

1
<img class="noShow" src={img} alt={alt} onLoad={onLoad} />

jsx 内的 img 标签有 onLoad 属性方法 意思就是当图片资源加载完成后会有回调通知所以在这个方法内我们可以使用 Vue 的 this.$emit 来派发一个 onloads 事件通知,在父组件内进行监听

代码例子为如下

1
2
3
4
5
6
7
8
<LazyLoad.PicLazyLoad 
img={Sevn} // 图片
skeleton="newSkeleton"//占位图css样式(className)
imgClassName="sevn" // 图片的样式(className)
alt="sevn"
imgLoaded={imgLoaded}
{...{ on: { onloads: onLoads }}} //监听图片加载
/>

使用{...{ on: { onloads: onLoads }}}来监听$emit派发的onload事件
详细代码以及使用方式请参阅这里

接下来是两个框架对于相同代码逻辑的不同实现对比
react版本的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class PicLazyLoad extends React.Component {
static propTypes = {
onLoaded: PropTypes.func.isRequired,
loaded: PropTypes.bool.isRequired,
img: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
imgClassName: PropTypes.string,
skeleton: PropTypes.string
};

static defaultProps = {
alt: ""
};

state = {
loaded: false
};

render() {
const that = this;
const { loaded } = that.state;
const { img, alt, imgClassName, skeleton } = that.props;

const onLoad = () => {
that.setState({
loaded: true
});
};

return (
<div className="container">
{loaded ? (
<img
className={ClassNames("defaultImg", imgClassName)}
src={img}
alt={alt}
/>
) : (
<div className={ClassNames("skeleton1", skeleton)}></div>
)}
<img className="noShow" src={img} alt={alt} onLoad={onLoad} />
</div>
);
}
}

Vue版本的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
const PicLazyLoad = {
name: 'PicLazyLoad',
props: {
imgLoaded: {
type: Boolean,
required: true,
},
img: {
type: String,
required: true,
},
alt: {
type: String,
required: true,
},
imgClassName: {
type: String,
required: false,
},
skeleton: {
type: String,
required: false,
},
},
data() {
return {};
},
render() {
const that = this;
const { imgLoaded, imgClassName, img, alt, skeleton } = that;
const onLoad = () => {
that.$emit('onloads', true);
};

return (
<div class="P-container">
{imgLoaded ? (
<img class={ClassNames('defaultImg', imgClassName)} src={img} alt={alt} />
) : (
<div class={ClassNames('skeleton1', skeleton)}></div>
)}
<img class="noShow" src={img} alt={alt} onLoad={onLoad} />
</div>
);
},
};

当然简单的组件Vue有了jsx的加持后基本和react没什么太大的差别下一篇带来稍微复杂一点点的另一个组件再次一起感受下两个框架的一些使用上的差别

PenZ wechat
交个朋友吧
点滴分享,您的支持将极大的鼓励我!