项目文件目录
├── src
| ├── components
| | ├── compon1.vue
| | ├── compon2.vue
| | ├── compon3.vue
| ├── app.vue
| ├── main.js
├── index.js
├── rollup.config.js
├── package.json
rollup.config.js
// rollup-plugin-vue插件需指定版本,@5.1.9对应的是vue2.x,@6.0.0以上对应的是vue3.x
import vue from "rollup-plugin-vue";
// import resolve from "rollup-plugin-node-resolve";
import resolve from "@rollup/plugin-node-resolve";
// import babel from "rollup-plugin-babel";
import babel from "@rollup/plugin-babel";
// import commonjs from "rollup-plugin-commonjs"
import commonjs from "@rollup/plugin-commonjs";
import json from '@rollup/plugin-json'
// import image from "@rollup/plugin-image"
// 处理css需要用到的插件是rollup-plugin-postcss。它支持css文件的加载、css加前缀、css压缩、对scss/less的支持等等
// import postcss from 'rollup-plugin-postcss'
// autoprefixer插件来给css3的一些属性加前缀--webkid,npm i autoprefixer@8.0.0 --D
const config = {
input: "./index.js", // 必须,入口文件
output: {
// 必须,输出文件 (如果要输出多个,可以是一个数组)
// exports: "named", // 输出多个文件
globals: {
vue: "Vue", // 告诉rollup全局变量Vue即是vue
},
},
external:['lodash'] //告诉rollup不要将此lodash打包,而作为外部依赖
plugins: [
// 引入的插件在这里配置
resolve({
preferBuiltins: true,
browser: true
}),
vue({
css: true,
compileTemplate: true
}),
babel({
exclude: "**/node_modules/**",
babelHelpers: "runtime",
}),
commonjs(),
json()
// image()
],
};
export default config;
index.js
// Import vue component
import Compon1 from "./src/components/compon1.vue";
import Compon2 from "./src/components/compon2.vue";
import Compon3 from "./src/components/compon3.vue";
import './flexible';// 为适配移动端用
const components = [
Compon1,
Compon2,
Compon3
];
const install = function (Vue) {
components.forEach((component) => {
// 组件compon1内部必须定义name
Vue.component(component.name, component);
});
};
if (typeof window !== "undefined" && window.Vue) {
install(window.Vue);
}
export default {
install,
// 按需导出
Compon1,
Compon2,
Compon3
};
package.json配置打包命令
{
"name": "vue2_demo",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"build:es": "rollup -c --format es --file dist/components.esm.js"
},
"dependencies": {
"axios": "^1.3.4",
"core-js": "^3.6.5",
"lodash": "^4.17.21",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@babel/core": "^7.21.0",
"@rollup/plugin-babel": "^6.0.3",// √
"@rollup/plugin-commonjs": "^24.0.1",// √
"@rollup/plugin-image": "^3.0.2",// √
"@rollup/plugin-json": "^6.0.0",// √
"@rollup/plugin-node-resolve": "^13.3.0",// √
"@vue/cli-plugin-babel": "~4.5.15",
"@vue/cli-plugin-eslint": "~4.5.15",
"@vue/cli-plugin-router": "~4.5.15",
"@vue/cli-plugin-vuex": "~4.5.15",
"@vue/cli-service": "~4.5.15",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"prettier": "^2.2.1",
"rollup": "^2.79.1",// √
"rollup-plugin-babel": "^4.4.0",// √
"rollup-plugin-commonjs": "^10.1.0",// √
"rollup-plugin-node-resolve": "^5.2.0",// √
"rollup-plugin-terser": "^7.0.2",// √
"rollup-plugin-vue": "^5.1.9",// √
"vue-template-compiler": "^2.6.11"//配合rollup-plugin-vue工作
}
}
// 推荐使用@rollup/xx开头的依赖包
main.js里注册use
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import YTUI from "./assets/components.esm";
Vue.config.productionTip = false;
Vue.use(YTUI);
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
这样就可以在所有页面直接使用啦
<template>
<div class="home">
<HelloWorld msg="Welcome to Your Vue.js App" />
<compon1 />
<compon2 />
<compon3 />
</div>
</template>
兼容移动端适配
flexible.js
;(function(win, flexible = {}) {
var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
if (metaEl) {
console.warn('将根据已有的meta标签来设置缩放比例');
var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = flexibleEl.getAttribute('content');
if (content) {
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
docEl.setAttribute('data-dpr', dpr);
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
function refreshRem(){
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
win.addEventListener('resize', function() {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener('pageshow', function(e) {
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === 'complete') {
doc.body.style.fontSize = 12 * dpr + 'px';
} else {
doc.addEventListener('DOMContentLoaded', function(e) {
doc.body.style.fontSize = 12 * dpr + 'px';
}, false);
}
refreshRem();
flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function(d) {
var val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
}
flexible.px2rem = function(d) {
var val = parseFloat(d) / this.rem;
// if (typeof d === 'string' && d.match(/px$/)) {
// val += 'rem';
// }
return val;
}
})(window, window['flexible'] || (window['flexible'] = {}));
compen1.vue
<template>
<div>
<h2 :style="{ width: wToRem, height: addUnit(height)}">component1</h2>
</div>
</template>
<script>
import Axios from "axios";// 用到的依赖会自动打包进去
// import Axios from 'axios/dist/axios';
export default {
name: "Compon1",
props: {
width: String | Number, // 100 or '100px'
height: String | Number,
},
created() {
console.log("Compon1",document.documentElement.clientWidth / 10 + "px");
Axios.get(
"https://mock.presstime.cn/mock/621ee0b1a977410016aaae08/yangtao/mock"
).then(({data}) => {
console.log(data);
});
},
computed: {
wToRem() {
return flexible.px2rem(this.width) / 2 + "rem";
},
hToRem() {
return flexible.px2rem(this.height) / 2 + "rem";
},
},
methods: {
testFn(data) {
if (/\px$/.test(data)) return data.replace(/px/g, "");
return data;
},
addUnit(data) {
return flexible.px2rem(data) / 2 + "rem";
}
},
};
</script>
<style lang="less" scoped>
@import "../assets/style.less";
</style>