На основе vue-cli3.0 для создания полнофункциональной полки мобильного терминала.

Vue.js

vue-cli4 был обновлен,нажмите на меня, чтобы посмотреть

На основе vue-cli3.0 для создания полнофункциональной полки мобильного терминала основные функции включают

  1. расширение упаковки webpack
  2. css: поддержка sass, normalize.css, _mixin.scss, _variables.scss
  3. vw, рем макет
  4. Междоменные настройки
  5. настройки эслинта
  6. cdn импорт
  7. Дизайн маршрутизации, перехват входа в систему
  8. аксиомы, дизайн API
  9. vuex управление состоянием

адрес проекта:vue-cli3-H5

демонстрационный адрес:Zhou Yupeng.GitHub.IO/v UE обрабатывает 3H5/#…

расширение упаковки webpack

После vue-cli3.* структура каталогов была сильно изменена, а предыдущие папки build и config были удалены.Для реализации изменений конфигурации добавьте vue.config.js в корневой каталог для настройки.

css: поддержка sass, normalize.css, _mixin.scss, _variables.scss

Используемый препроцессор css — sass.Для примеси css переменные импортируются глобально и импортируютсяnormalize.cssСделать так, чтобы стили HTML-элементов выглядели одинаково в разных браузерах конфигурация vue.config.js

css: {
        // 是否使用css分离插件 ExtractTextPlugin
        extract:isProduction ? true:false,
        // 开启 CSS source maps?
        sourceMap: false,
        // css预设器配置项
        // 启用 CSS modules for all css / pre-processor files.
        modules: false,
            sass: {
                data: '@import "style/_mixin.scss";@import "style/_variables.scss";' // 全局引入
            }
        }
    }

vw, рем макет

Для схемы адаптации мобильного терминалаНовости сетиМетоды, Использовать макет vw + rem

/**
750px设计稿
    取1rem=100px为参照,那么html元素的宽度就可以设置为width: 7.5rem,于是html的font-size=deviceWidth / 7.5
**/
html {
    font-size: 13.33333vw
}

@media screen and (max-width: 320px) {
    html {
        font-size: 42.667PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 321px) and (max-width:360px) {
    html {
        font-size: 48PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 361px) and (max-width:375px) {
    html {
        font-size: 50PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 376px) and (max-width:393px) {
    html {
        font-size: 52.4PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 394px) and (max-width:412px) {
    html {
        font-size: 54.93PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 413px) and (max-width:414px) {
    html {
        font-size: 55.2PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 415px) and (max-width:480px) {
    html {
        font-size: 64PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 481px) and (max-width:540px) {
    html {
        font-size: 72PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 541px) and (max-width:640px) {
    html {
        font-size: 85.33PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 641px) and (max-width:720px) {
    html {
        font-size: 96PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 721px) and (max-width:768px) {
    html {
        font-size: 102.4PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 769px) {
    html {
        font-size: 102.4PX;
        font-size: 13.33333vw
    }
}

@media screen and (min-width: 769px) {
    html {
        font-size: 102.4PX;

        #app {
            margin: 0 auto
        }
    }


}

конфигурация vue.config.js

loaderOptions: {
    postcss: {
        // 这是rem适配的配置
        plugins: [
            require('postcss-px2rem')({
                remUnit: 100
            })
        ]
    }
}

Междоменные настройки во время разработки

devServer: {
        open: true, // 启动服务后是否打开浏览器
        host: '127.0.0.1',
        port: 8088, // 服务端口
        https: false,
        hotOnly: false,
        proxy: 'https://easy-mock.com/' // 设置代理
    }

После настройки baseUrl axios в локальной среде разработки должен быть записан как '' , что является пустой строкой. При публикации в Интернете, если внешний код не размещается вместе с внутренним APIгомологиявниз, фон также должен выполнять междоменную обработку,

стандартные настройки эслинта

используетJavaScript standardСпецификация кода, хороший стиль кодирования Это может помочь уменьшить трения между командами, а код чище и читабельнее, не надо раздражаться, используйте все это.Это полный текст стандартной спецификации кода JavaScript.

Пользовательская конфигурация, измененная в .eslintrc.js, вот конфигурация, которую я дал, отступ с 4 пробелами, не проверяйте завершающую точку с запятой, закройте одно объявление var, вы можете настроить его самостоятельно

rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    indent: [
        'error',
        4,
        {
            SwitchCase: 1
        }
    ],
    semi: 0, // 不检查结尾分号,
    // 强制使用单引号
    quotes: ['error', 'single'],
    // 关闭函数名与后面括号间必须空格规则
    'space-before-function-paren': 0,
    // 关闭var 声明,每个声明占一行规则。
    'one-var': 0
    }

cdn импорт

Для таких библиотек, как vue, vue-router, vuex, axios и т. д., которые не часто изменяются, мы позволяем webpack не упаковывать их, импортируя их через cdn, можно уменьшить размер кода и пропускную способность сервера. Здесь используется 360 cdn, и прилагается общедоступная оценочная статья cdn.я указываю

конфигурация vue.config.js

const externals = {
    vue: 'Vue',
    'vue-router': 'VueRouter',
    vuex: 'Vuex',
    'mint-ui': 'MINT',
    axios: 'axios'

}

const cdn = {
    // 开发环境
    dev: {
        css: [
            'https://lib.baomitu.com/mint-ui/2.2.13/style.min.css'
        ],
        js: []
    },
    // 生产环境
    build: {
        css: [
            'https://lib.baomitu.com/mint-ui/2.2.13/style.min.css'
        ],
        js: [
            'https://lib.baomitu.com/vue/2.6.6/vue.min.js',
            'https://lib.baomitu.com/vue-router/3.0.1/vue-router.min.js',
            'https://lib.baomitu.com/vuex/3.0.1/vuex.min.js',
            'https://lib.baomitu.com/axios/0.18.0/axios.min.js',
            'https://lib.baomitu.com/mint-ui/2.2.13/index.js'
        ]
    }
}

configureWebpack: config => {
        if (isProduction) {
            // externals里的模块不打包
            Object.assign(config, {
                externals: externals
            })
       
        } else {
            // 为开发环境修改配置...
        }
    },
chainWebpack: config => {
    // 对vue-cli内部的 webpack 配置进行更细粒度的修改。
    // 添加CDN参数到htmlWebpackPlugin配置中, 详见public/index.html 修改
    config.plugin('html').tap(args => {
        if (process.env.NODE_ENV === 'production') {
            args[0].cdn = cdn.build
        }
        if (process.env.NODE_ENV === 'development') {
            args[0].cdn = cdn.dev
        }
        return args
    })
}
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="utf-8" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<!-- DNS预解析 -->
	<link rel="dns-prefetch" href="//lib.baomitu.com" />
	<meta name="viewport"
		content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=0,minimal-ui,viewport-fit=cover" />
	<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
	<!-- 使用CDN加速的CSS文件,配置在vue.config.js下 -->
	<% for (var i in
    htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
	<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style" />
	<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
	<% } %>

	<title>vuedemo</title>
</head>

<body>
	<noscript>
		<strong>We're sorry but vuedemo doesn't work properly without JavaScript
			enabled. Please enable it to continue.</strong>
	</noscript>
	<div id="app"></div>
	<!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
	<% for (var i in
    htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
	<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
	<% } %>

	<!-- built files will be auto injected -->
</body>

</html>

Дизайн маршрутизации, перехват входа в систему

const router = new Router({
    routes: [
        {
            path: '/',
            name: 'home',
            component: Home,
            meta: {
                auth: false, // 是否需要登录
                keepAlive: true // 是否缓存组件
            }
        },
        {
            path: '/about',
            name: 'about',
            component: () =>
                import(/* webpackChunkName: "about" */ './views/About.vue'),
            meta: {
                auth: true,
                keepAlive: true
            }
        },
        {
            path: '/login',
            name: 'login',
            component: () =>
                import(/* webpackChunkName: "login" */ './views/login.vue'),
            meta: {
                auth: false,
                keepAlive: true
            }
        },
        {
            path: '*', // 未匹配到路由时重定向
            redirect: '/',
            meta: {
                // auth: true,
                // keepAlive: true
            }
        }
    ]
})

// 全局路由钩子函数 对全局有效
router.beforeEach((to, from, next) => {
    let auth = to.meta.auth
    let token = store.getters['login/token'];

    if (auth) { // 需要登录
        if (token) {
            next()
        } else {
            next({
                path: '/login',
                query: {
                    redirect: to.fullPath
                }
            })
        }
    } else {
        next()
    }
})

Установите, следует ли входить в систему и кэшировать ли текущий компонент в мета, В функции маршрутизации router.beforeEac оценивается разрешение на вход.Если нет входа, перейти на страницу входа, пройти текущую страницу и вернуться на эту страницу после входа.

Для кэширования страницы обработайте ее в app.vue

<keep-alive v-if="$route.meta.keepAlive" >
    <router-view class="router"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" class="router"></router-view>

аксиомы, дизайн API

Дизайн axios в основном включает перехватчик запроса, перехватчик ответа и вторичную инкапсуляцию get и post.

axios.defaults.timeout = 12000 // 请求超时时间
axios.defaults.baseURL = process.env.VUE_APP_BASE_API

axios.defaults.headers.post['Content-Type'] =
    'application/x-www-form-urlencoded;charset=UTF-8' // post请求头的设置
// axios 请求拦截器
axios.interceptors.request.use(
    config => {
        // 可在此设置要发送的token
        let token = store.getters['login/token'];
        token && (config.headers.token = token)
        Indicator.open('数据加载中')
        return config
    },
    error => {
        return Promise.error(error)
    }
)
// axios respone拦截器
axios.interceptors.response.use(
    response => {
        // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
        // 否则的话抛出错误 结合自身业务和后台返回的接口状态约定写respone拦截器
        Indicator.close()
        if (response.status === 200 && response.data.code === 0) {
            return Promise.resolve(response)
        } else {
            Toast({
                message: response.data.msg,
                position: 'middle',
                duration: 2000
            });
            return Promise.reject(response)
        }
    },
    error => {
        Indicator.close()
        const responseCode = error.response.status
        switch (responseCode) {
            // 401:未登录
            case 401:
                break
            // 404请求不存在
            case 404:
                Toast({
                    message: '网络请求不存在',
                    position: 'middle',
                    duration: 2000
                });
                break
            default:
                Toast({
                    message: error.response.data.message,
                    position: 'middle',
                    duration: 2000
                });
        }
        return Promise.reject(error.response)
    }
)
/**
 * 封装get方法,对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
function get (url, params = {}) {
    return new Promise((resolve, reject) => {
        axios
            .get(url, {
                params: params
            })
            .then(res => {
                resolve(res.data)
            })
            .catch(err => {
                reject(err.data)
            })
    })
    // 或者return axios.get();
}
/**
 * post方法,对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
function post (url, params) {
    return new Promise((resolve, reject) => {
        axios
            .post(url, qs.stringify(params))
            .then(res => {
                resolve(res.data)
            })
            .catch(err => {
                reject(err.data)
            })
    })
    //  或者return axios.post();
}


Чтобы упростить управление путем API, все запросы помещаются в папку API, например

import { get, post } from '@/axios/http.js'
function getIndex (params) {
    return get('/mock/5cb48c7ed491cd741c54456f/base/index', params)
}
function login(params) {
    return post('/mock/5cb48c7ed491cd741c54456f/base/login', params)
}
export {
    getIndex,
    login
}

разное

удалить console.log

Установите плагин uglifyjs-webpack-plugin.

 // 上线压缩去除console等信息
config.plugins.push(
    new UglifyJsPlugin({
        uglifyOptions: {
            compress: {
                warnings: false,
                drop_console: true,
                drop_debugger: false,
                pure_funcs: ['console.log'] // 移除console
            }
        },
        sourceMap: false,
        parallel: true
    })
)

установить псевдоним псевдонима каталога

Файлы в разных местах часто упоминаются в проекте, и их легче добавить после настройки.

config.resolve.alias
            .set('assets', '@/assets')
            .set('components', '@/components')
            .set('view', '@/view')
            .set('style', '@/style')
            .set('api', '@/api')
            .set('store', '@/store')

Переменные среды и шаблоны

В процессе начальной разработки продукта, как правило, он проходит через локальную разработку, тестовые сценарии, самотестирование разработки, тестовую среду и среду предварительного запуска, прежде чем он может быть официально выпущен. Соответствующие каждой среде могут быть разными, например, адрес сервера, адрес интерфейса, адрес веб-соркета... и так далее. При переключении между средами требуются разные параметры конфигурации, поэтому для облегчения нашего управления можно использовать переменные среды и режимы.

.env                # 在所有的环境中被载入
.env.local          # 在所有的环境中被载入,但会被 git 忽略
.env.[mode]         # 只在指定的模式中被载入
.env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略

Пользовательская переменная VUE_APP_ начинается с двух специальных переменных:

  1. NODE_ENV — будет одним из вариантов «разработка», «производство» или «тестирование». Точное значение зависит от режима, в котором работает приложение.
  2. BASE_URL — будет соответствовать параметру baseUrl в vue.config.js, т. е. базовому пути, по которому будет развернуто ваше приложение.

Как мы определили .env

NODE_ENV = 'development'
BASE_URL = '/'
VUE_APP_BASE_API = ''

.env.production

NODE_ENV = 'production'
BASE_URL = './'
VUE_APP_BASE_API = 'https://easy-mock.com/'

В проекте вы можете использовать process.env.VUE_APP_*, например, process.env.VUE_APP_BASE_API, чтобы получить определенное значение.

Импортировать фильтр глобально

Напишите фильтры, используемые в нескольких местах в js, и повторно используйте код.

// 过滤日期格式,传入时间戳,根据参数返回不同格式
const formatTimer = function(val, hours) {
    if (val) {
        var dateTimer = new Date(val * 1000)
        var y = dateTimer.getFullYear()
        var M = dateTimer.getMonth() + 1
        var d = dateTimer.getDate()
        var h = dateTimer.getHours()
        var m = dateTimer.getMinutes()
        M = M >= 10 ? M : '0' + M
        d = d >= 10 ? d : '0' + d
        h = h >= 10 ? h : '0' + h
        m = m >= 10 ? m : '0' + m
        if (hours) {
            return y + '-' + M + '-' + d + ' ' + h + ':' + m
        } else {
            return y + '-' + M + '-' + d
        }
    }
}
export default {
    formatTimer
}

импорт main.js

import filters from './filters/index'
// 注入全局过滤器
Object.keys(filters).forEach(item => {
    Vue.filter(item, filters[item])
})

использовать

{{1555851774 | formatTimer()}}

Использование mock.js в vue

Посмотрите мои предыдущие статьинажми на меня

Плагин инструмента визуального анализа ресурсов Wepback --- webpack-bundle-analyzer

Он используется для анализа того, какие модули представляют какой код, и целенаправленной оптимизации кода.

В среде упаковки используйте команду npm run build --report

if (process.env.npm_config_report) {
    config.plugins.push(new BundleAnalyzerPlugin())
}

111

кодовый адрес

адрес проекта:vue-cli3-H5

демонстрационный адрес:Zhou Yupeng.GitHub.IO/v UE обрабатывает 3H5/#…

Спасибо за прочтение, если у вас есть какая-то помощь, пожалуйста, подпишитесь и подпишитесь

Если вы сочтете это полезным, вы можете обратить внимание на общедоступную учетную запись [расширенный большой интерфейс] и каждый день добавлять для вас немного знаний.