Эта статья гарантирует, что проблема будет только увеличиваться, а не уменьшаться, так что радиус поверхности знаний продолжает увеличиваться.
Что делать, если скорость vue упаковки webpack слишком низкая?
- настроить внешние
- Сжатие кода использует ParallelUglifyPlugin вместо встроенного плагина UglifyJsPlugin.
- Библиотеки плагинов, не требующие упаковки и компиляции, заменены на глобальные
<script>Как вводится лейбл - Используйте CommonsChunkPlugin для извлечения общих модулей, которые могут уменьшить размер файла и помочь кэшировать файлы на уровне браузера.
// 提取公共模块文件
new webpack.optimize.CommonsChunkPlugin({
chunks: ['home', 'detail'],
// 开发环境下需要使用热更新替换,而此时common用chunkhash会出错,可以直接不用hash
filename: '[name].js' + (isProduction ? '?[chunkhash:8]' : ''),
name: 'common'
}),
// 切合公共模块的提取规则,有时后你需要明确指定默认放到公共文件的模块
// 文件入口配置
entry: {
home: './src/js/home',
detail: './src/js/detail',
// 提取jquery入公共文件
common: ['jquery', 'react', 'react-dom']
},
- Используйте HappyPack для ускорения сборки
HappyPack будет использовать несколько процессов для упаковки и сборки, он довольно прост в использовании, но поддерживает не все загрузчики. Сначала введите, определите потоки, открытые этим плагином.Рекомендуемое количество — четыре.На самом деле, вы можете напрямую использовать те, что по умолчанию.
HappyPack = require('happypack'),
os = require('os'),
happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
Потом изменить его в правилах модуля и ввести, где id - это идентификатор
{
test: /\.jsx?$/,
// 编译js或jsx文件,使用babel-loader转换es6为es5
exclude: /node_modules/,
loader: 'HappyPack/loader?id=js'
// use: [{
// loader: 'babel-loader',
// options: {
// }
// }]
}
Затем мы вызываем плагин, устанавливаем соответствующий идентификатор, а затем соответствующая конфигурация может напрямую поместить часть использования правила: на загрузчики
new HappyPack({
id: 'js',
loaders: [{
loader: 'babel-loader',
options: {
// cacheDirectory: true
}
}]
}),
Первое, на что следует обратить внимание, это то, что он плохо поддерживает файловый загрузчик и URL-загрузчик, поэтому эти два загрузчика не нужно заменять на happypack, и другие загрузчики могут быть заменены аналогичным образом.
Второй момент, который следует отметить, заключается в том, что использование ExtractTextWebpackPlugin для извлечения файлов css не является полностью конвертируемым, поэтому требуется небольшое изменение, например
module: {
rules: [{
test: /\.css$/,
// loader: 'HappyPack/loader?id=css'
// 提取CSS文件
use: cssExtractor.extract({
// 如果配置成不提取,则此类文件使用style-loader插入到<head>标签中
fallback: 'style-loader',
use: 'HappyPack/loader?id=css'
// use: [{
// loader: 'css-loader',
// options: {
// // url: false,
// minimize: true
// }
// },
// // 'postcss-loader'
// ]
})
}, {
test: /\.scss$/,
// loader: 'HappyPack/loader?id=scss'
// 编译Sass文件 提取CSS文件
use: sassExtractor.extract({
// 如果配置成不提取,则此类文件使用style-loader插入到<head>标签中
fallback: 'style-loader',
use: 'HappyPack/loader?id=scss'
// use: [
// 'css-loader',
// // 'postcss-loader',
// {
// loader: 'sass-loader',
// options: {
// sourceMap: true,
// outputStyle: 'compressed'
// }
// }
// ]
})
}
Поскольку это прямой вызов функции, мы просто поместили его в правило использования на внутреннем уровне, а затем настроили подключаемый модуль.
plugins: [
new HappyPack({
id: 'css',
loaders: [{
loader: 'css-loader',
options: {
// url: false,
minimize: true
}
}]
}),
new HappyPack({
id: 'scss',
loaders: [{
'loader': 'css-loader'
}, {
loader: 'fast-sass-loader',
options: {
sourceMap: true,
outputStyle: 'compressed'
}
}]
}),
- Некоторые плагины представлены модульным образом, что в основном представляет собой полезный код.
// 原来的引入方式
import {debounce} from 'lodash';
//按模块化的引入方式
import debounce from 'lodash/debounce';
- Использовать асинхронную загрузку модулей
Это можно расценивать как уменьшение размера модуля, в какой-то степени это считается и для пользователя, используйте require.ensure, чтобы указать, какие модули нужно загружать асинхронно, а webpack упакует их в отдельный чанк.
Этот модуль загружается асинхронно для выполнения в какой-то момент (например, когда пользователь нажимает «Просмотр»).
$('.bg-input').click(() => {
console.log('clicked, loading async.js')
require.ensure([], require => {
require('./components/async2').log();
require('./components/async1').log();
console.log('loading async.js done');
});
});
- Иногда нет необходимости разрешать зависимости определенных модулей (которые не имеют зависимостей или вообще не модульны),
使用noParse,直接跳过解析
module: {
noParse: /node_modules\/(jquey\.js)/
}
- Оптимизация путей поиска во время сборки
Когда веб-пакет упакован, будут разные пути для запроса и поиска, мы можем добавить некоторые конфигурации, чтобы ускорить поиск.
Например,方便改成绝对路径的模块路径就改一下,以纯模块名来引入的可以加上一些目录路径
Достаточно хорошо善于用resolve alias别名 这个字段来配置
Существуют также такие конфигурации, как исключение, чтобы избежать избыточных файлов, например, использование babel, не забудьте удалить те, которые не нужно просматривать.
{
test: /\.jsx?$/,
// 编译js或jsx文件,使用babel-loader转换es6为es5
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
}
}]
}
- Позаботьтесь о модулях, участвующих в упаковке и сборке, проанализируйте, какие пакеты не нужно упаковывать, и упакуйте только необходимые модули.
После добавления параметра --json > stat.json при компиляции веб-пакета вы можете загрузить его на аналитические сайты, такие как webpack-analyse и webpack-visualizer, чтобы просмотреть информацию о упакованном модуле.
- Извлечь общедоступный код
Как решить проблему, что поставщик упаковки vue слишком велик?
-
Уменьшите размер общедоступного пакета: причина, по которой пакет поставщика слишком велик, заключается в том, что js, ссылающийся на сторонний плагин, слишком велик.Вы можете напрямую обратиться к зеркалу в сценарии индекса, чтобы решить проблему. ;
-
Пакет шаблона не будет слишком большим: по требованию вводится vue-router, который будет распаковывать
В чем проблема с белым экраном на главной странице Vue? Как это решить?
Проблема с белым экраном главной страницы:
Домашняя страница загружается слишком медленно, потому что это одностраничное приложение, и все необходимые ресурсы нужно загрузить в браузер и проанализировать. Следовательно, чем больше страница, тем дольше время загрузки и чем дольше время выполнения js, тем позже происходит dcl, поэтому экран будет пустым.
Решение:
- Оптимизируйте веб-пакет, чтобы уменьшить размер упаковки модуля, разделяйте загрузку кода по требованию.
- Рендеринг на стороне сервера, предварительная сборка html, необходимого для домашней страницы, на стороне сервера.
- Домашняя страница плюс экран загрузки или скелета (просто для оптимизации работы)
- Включить сжатие gzip на сервере
- Подпакет файла пакета, извлечь пакет общедоступного файла
Как оптимизировать скорость загрузки главной страницы?
- кеш браузера
- Gzip-сжатие
- Сеть доставки контента (CDN)
- Асинхронный скрипт
<script async src=""></script>
- Оптимизируйте код JavaScript, HTML и CSS, чтобы удалить все ненужные пробелы и комментарии, тем самым уменьшив размер файла.
- Отложенный разбор JavaScript, за счет задержки разбора скриптов можно сократить начальное время загрузки веб-сайта.
- Включить сохранение в живых
- Не используйте встроенный CSS
- Избегайте блокировки JavaScript и CSS
Отложите загрузку неважного кода JavaScript или загрузите его асинхронно. Другой вариант — встроить эти HTML-коды на веб-сайт, обеспечив при этом оптимизацию CSS.
- Форматы изображений и файлов
Рекомендуется использовать формат JPEG, а не изображения GIF и PNG, если только изображение не содержит альфа-фактор или не является прозрачным.
- разделение файлов
Файлы веб-сайта можно разделить на CSS, JavaScript и изображения. Однако разделение файлов напрямую не улучшает время загрузки сайта. Однако это может повысить стабильность сервера, особенно если происходит внезапный всплеск посещаемости веб-сайта. Субдомены также можно использовать для размещения файлов, что может увеличить количество параллельных загрузок.
- Минимизируйте HTTP-запросы
Когда веб-сайт получает слишком много HTTP-запросов одновременно, его посетители сталкиваются с задержкой времени ответа, что не только увеличивает загрузку ЦП, но и увеличивает время загрузки страницы. Итак, как уменьшить HTTP-запросы? См. шаги ниже.
- Уменьшите количество объектов на вашем сайте.
- Минимизируйте количество редиректов на вашем сайте.
- Используйте технику CSS Sprites (если вам нужна эта часть содержимого изображения).
- Комбинируйте JavaScript и CSS.
Проанализируйте причину, по которой появляется сообщение об ошибке 404 после того, как локальная разработка проекта Vue завершена и развернута на сервере?
-
Проверьте конфигурацию nginx, чтобы убедиться, что условия сопоставления ресурсов установлены правильно.
-
Check Vue.config.js настроен в PooksPath, если вы проверяете, размещены ли одинаковые файлы проекта и ресурсов в местоположении сервера
Какие приготовления мне нужно сделать, прежде чем начнется развертывание vue?
- Проверьте правильность среды конфигурации
- Верна ли версия git
- Правильно ли паковать дорогу
- конфигурация nginx
- удалить консоль
Каковы спецификации разработки Vue?
-
обязательный
- Имя компонента из нескольких слов
export default { name: 'TodoItem', // ... } 反例: export default { name: 'Todo', // ... }- Данные компонента должны быть функцией
- Определение реквизита максимально подробное, включая тип, значение по умолчанию, требуется ли это, валидация
- установить ключ для для
- Избегайте одновременного использования v-if и v-for
- Область действия стилей компонентов
- полными словами
-
предложение
- Использовать файлы компонентов
components/TodoItem.vue- Сокращенная инструкция
-
Используйте с осторожностью (потенциально опасный режим)
- с использованием селекторов элементов
- Предпочитайте связь между родительским и дочерним компонентами через реквизиты и события, а не this.$parent или изменение реквизитов
- Не использовать ключ в v-if/v-if-else/v-else
Если набор v-if + v-else имеет один и тот же тип элемента, то лучше использовать ключ
Как получить доступ к данным дочернего компонента при использовании слота в родительском компоненте
子组件
<template>
<div>
<h2>默认插槽</h2>
<slot :toParent="childrenData" :toParent2="childrenData2">
{{childrenData.data1}}
{{childrenData2.data1}}
</slot>
<h2>头部插槽</h2>
<slot name="header" :headerData="headerData">
{{headerData.data1}}
</slot>
</div>
</template>
<script>
export default{
data(){
return{
childrenData:{
data1:'子组件数据一',
data2:'子组件数据二',
},
childrenData2:{
data1:'子组件数据三',
data2:'子组件数据四',
},
headerData:{
data1:'子组件头部数据一',
data2:'子组件头部数据二',
},
}
},
}
</script>
slotProps — это набор реквизитов слота, и его имя может быть выбрано произвольно. На данный момент значение slotProps.toParent является значением childrenData.
父组件
<template>
<div>
<myComponent>
// slotProps和headerProps是代表插槽prop的集合,其命名可以随便取的
<template v-slot:default="slotProps">
{{slotProps.toParent.data2}}
{{slotProps.toParent2.data2}}
</template>
<template v-slot:header="headerProps">
{{headerProps.headerData.data2}}
</template>
//当有子组件slot上有多个插槽prop时,父组件调用时候可以ES6对象解构的方法
<template v-slot:default="{toParent,toParent2}">
{{toParent.data2}}
{{toParent2.data2}}
</template>
<template v-slot:header="{headerData}">
{{headerData.data2}}
</template>
//也可以给子组件slot上绑定的值重新命名
<template #default="{toParent:a,toParent2:b}">
{{a.data2}}
{{b.data2}}
</template>
<template #header="{headerData:c}">
{{c.data2}}
</template>
</myComponent>
</div>
</template>
Понимание опций DOM el, template, render?
- эль:
提供一个在页面上已存在的DOM元素作为Vue实例的挂载目标. Может быть селектором CSS или экземпляром HTMLElement.- Поскольку все смонтированные элементы будут заменены DOM, сгенерированным Vue. Поэтому не рекомендуется монтировать экземпляр Vue в html или body.
- Если эта опция существует в const vm = new Vue({}), экземпляр немедленно войдет в процесс компиляции, в противном случае вам нужно явно вызвать vm.$mount(), чтобы вручную запустить компиляцию.
vm = новый Vue({}) существует в el
<script>
const vm= new Vue({
el:'#app',
data:{
age:17
},
}
</script>
Чтобы вручную запустить компиляцию, явно вызвав vm.$mount()
<script>
const vm= new Vue({
data:{
age:17
},
})
vm.$mount('#app')
</script>
- шаблон: строковый шаблон
作为Vue实例的标识使用. Если el существует, шаблон заменит смонтированный элемент. Содержимое смонтированного элемента игнорируется, если в содержимом шаблона нет слота отправки.- Если значение начинается с #, то оно будет использоваться в качестве селектора, а innerHTML соответствующего элемента будет использоваться в качестве шаблона.
<script>
const vm= new Vue({
el:'#app',
data:{
age:17
},
template:'<div>我是template的内容:小明今年{{age}}岁了</div>',
})
</script>
<script type="x-template" id="mb">в сочетании с #
<script type="x-template" id="mb">
<div>我是template的内容:小明今年{{age}}岁了</div>
</script>
<script>
const vm= new Vue({
el:'#app',
data:{
age:17
},
template:'#mb',
})
</script>
шаблон, идентификатор и # вместе
<body>
<div id="app">
我是el挂载的内容:小明今年{{age}}岁了
</div>
<template id="mb">
<div>我是template的内容:小明今年{{age}}岁了</div>
</template>
</body>
<script>
const vm= new Vue({
el:'#app',
data:{
age:17
},
template:'#mb',
})
</script>
- render :
Vue 选项中的 render 函数若存在,则 Vue 构造函数不会从 template 选项或通过 el 选项指定的挂载元素中提取出的 HTML 模板编译渲染函数.
<body>
<div id="app">
我是el挂载的内容:小明今年{{age}}岁了
</div>
</body>
<script>
const vm= new Vue({
el:'#app',
data:{
age:17
},
template:'<div>我是template的内容:小明今年{{age}}岁了</div>',
render(h){
return h('div',`我是render的内容:小明今年${this.age}岁了`)
}
})
</script>
Каковы жизненные циклы (хуки-функции) пользовательских инструкций? Как написать пользовательскую инструкцию от руки?
- bind: вызывается только один раз, когда инструкция привязывается к элементу в первый раз, она может быть инициализирована в этой функции ловушки;
- вставленный: вызывается, когда связанный элемент вставляется в родительский узел, вызывается после связывания;
- update: вызывается при обновлении VNode связанного компонента, но может произойти до обновления его дочернего VNode.
Значение инструкции не обязательно изменяется при ее вызове, а ненужные обновления шаблона игнорируются путем сравнения значений до и после обновления;
- componentUpdated: вызывается после VNode компонента, в котором обновляются инструкция и ее дочерние VNode;
- unbind: вызывается только один раз, когда инструкция отсоединяется от элемента.
Vue.directive('color', {
bind:function(){
alert('bind')
},
inserted: function (el,binding) {
alert('inserted')
el.style.color=binding.value;
},
update:function(el,binding){
alert('update')
el.style.color=binding.value;
},
componentUpdated:function(el,binding){
alert('componentUpdated')
el.style.color=binding.value;
},
unbind:function(){
alert('v-color指令解绑')
}
})
В чем преимущество функции рендеринга?
шаблон тоже будет переведен в рендер, только один пункт,template中元素的tag_name是静态的,不可变化, используйте createEelment для генерации различных имен тегов, таких как h1 ... h6, которыми можно управлять с помощью числовой переменной
процесс монтирования vue
Посмотрите мой другой доклад:[Принцип Vue] Анализ исходного кода $mount
Вы понимаете, что такое компоненты высшего порядка?
Определение компонента высшего порядка (HOC): получает компонент в качестве параметра и возвращает новый компонент.
Особенности компонентов высшего порядка (HOC):
- Это должна быть чистая функция без побочных эффектов, и она не должна модифицировать исходный компонент, то есть исходный компонент нельзя изменить.
- Неважно, какие данные (реквизиты) вы передаете, а вновь созданным компонентам все равно, откуда берутся данные.
- Полученные реквизиты должны быть прозрачно переданы обернутому компоненту, т.е.
直接将原组件prop传给包装组件 - Полностью добавлять, удалять, изменять реквизит
Пример 1
<template>
<div>
<p @click="Click">props: {{test}}</p>
</div>
</template>
<script>
export default {
name: 'Base',
props: {
test: Number
},
methods: {
Click () {
this.$emit('Base-click')
}
}
}
</script>
Пример 2
export default function Console (BaseComponent) {
return {
template: '<wrapped v-on="$listeners" v-bind="$attrs"/>',
components: {
wrapped: BaseComponent
},
mounted () {
console.log('haha')
}
}
}
Вы слышали о Vue.observable?
Сделайте объект отзывчивым. Может использоваться как минимальное межкомпонентное хранилище состояний. Что-то вроде маленького Vuex
const store = Vue.observable({name:'hhy'});
const mutation = {
updateName(name){
store.name = name
}
}
store和mutaion可以分别在computed和methods中调用
Как решить проблему, что src динамической настройки img во Vue не действует?
Поскольку динамически добавляемый src рассматривается как статический ресурс, он не компилируется, поэтому добавьте require
Применение тега компонента и специальной функции к компонентам
- динамические компоненты
<component :is="componentName"></component>
componentName может быть именем локального компонента и именем глобального компонента, зарегистрированным на этой странице, или может быть объектом параметра компонента.
Когда элемент управления componentName изменяется, выбранный компонент может динамически переключаться.
- использование is
Некоторые элементы HTML, такие как<ul>、<ol>、<table> 和 <select>, существуют строгие ограничения на то, какие элементы могут появляться внутри него. и некоторые элементы, такие как<li>、<tr> 和 <option>, который может появиться только внутри какого-то другого конкретного элемента.
<ul>
<name-list></name-list>
</ul>
над<name-list></name-list>будет рассматриваться как недействительный контент提升到外部, и вызвать ошибку в конечном результате рендеринга. должно быть написано так
<ul>
<li is="nameList"></li>
</ul>
В чем разница между удалением объекта и Vue.delete?
- удалить: только член удаленного объекта становится '' или неопределенным, а значения ключей других элементов остаются неизменными;
- Vue.delete: удалить член объекта напрямую. Если объект отвечает, убедитесь, что удаление может вызвать обновление представления. Этот метод в основном используется, чтобы избежать ограничения, которое Vue не может обнаружить, что свойство удалено.
Вы когда-нибудь использовали шину событий (EventBus)? скажи мне свое понимание
Связь между компонентами vue достигается через пустой экземпляр vue в качестве моста. Это решение для реализации связи между компонентами, не являющимися родительскими и дочерними.
- Создайте экземпляр vue и экспортируйте этот экземпляр
import Vue from 'Vue'
export default new Vue
- Вставьте этот bus.js в два компонента, которые должны общаться
import Bus from '这里是你引入bus.js的路径' // Bus可自由更换喜欢的名字
- В компоненте, которая передает данные, имя события и передаваемые данные отправляются через метод экземпляра Vue $ Emit. (Отправить компонент данных)
Bus.$emit('click',data) // 这个click是一个自定义的事件名称,data就是你要传递的数据。
- Компонент, данные которого передаются слушают события и принимают данные через метод экземпляра Vue $.
Bus.$on('click',target => {
console.log(target) // 注意:发送和监听的事件名称必须一致,target就是获取的数据,可以不写target。只要你喜欢叫什么都可以(当然了,这一定要符合形参变量的命名规范)
})
- Используйте метод $off экземпляра vue для очистки eventBus в жизненном цикле vue перед уничтожением или уничтожением.
beforeDestroy(){
bus.$off('click')
}
Когда EventBus зарегистрирован глобально, событие будет запускаться повторно при переключении маршрута, как это решить?
существует有使用$on的组件中Для уничтожения с помощью $off в хуковой функции beforeDestroy.
После использования Vue Как сделать оптимизацию SEO для поисковых систем?
SEO:
- Структура веб-сайта: структура веб-сайта должна быть четкой и плоской.
- Навигация: страницы должны иметь краткую навигацию. Навигация позволяет поисковым системам узнать структуру веб-сайта, а также позволяет поисковым системам узнать уровень текущей страницы в структуре веб-сайта.
- Канонический URL-адрес: URL-адрес должен быть как можно короче, а переменные параметры, содержащиеся в динамическом URL-адресе, должны быть сведены к минимуму.
- Отправьте файл Sitemap: файлы Sitemap информируют поисковые системы о том, какие страницы на их сайте доступны для сканирования, чтобы поисковые системы могли сканировать ваш сайт более разумно.
- Разумный код возврата HTTP: другой код возврата, другая логика обработки поисковой системы.
- Подходящий заголовок: сообщает поисковым системам основное содержание страницы.
- подходящее описание
- HTML-семантика
Лучшим проектным решением для поддержки SEO является использование рендеринга на стороне сервера. Так что, если у проекта есть требования к SEO, то лучшим решением будет рендеринг на стороне сервера.
Почему Vue требует, чтобы шаблоны компонентов имели только один корневой элемент?
let vm = new Vue({
el:'#app'
})
<body>
<div id='app1'></div>
<div id='app2'></div>
</body>
Vue на самом деле не знает, какая из них является нашей записью, потому что для записи эта запись является «классом Vue», Vue необходимо отобразить, обработать и, наконец, повторно вставить в середину dom.
Если одновременно установлено несколько записей, vue не знает, какая из них является «классом».
Почему под шаблоном должен быть один и только один div?
Тег шаблона — это новый тег HTML5, который имеет три характеристики:
1. Скрытый: Метка не будет отображаться нигде на странице, даже если в ней много контента, она всегда будет скрыта;
2. Произвольный: Тег может быть написан где угодно на странице, даже в тегах head, body, sciprt;
3. Недействительность: любой HTML-контент в этом теге недействителен и не будет играть никакой роли;
Однако содержимое внутри можно получить через innerHTML.
На самом деле, по сути, однофайловый компонент будет перерабатываться в .js файл различными загрузчиками (потому что когда вы импортируете однофайловый компонент и распечатываете его, это Vue instance), через произвол шаблона Мы знаем, что HTML-код, завернутый в шаблон, может быть написан где угодно, поэтому для .vue содержимое шаблона — это содержимое, которое будет обработано vue как виртуальный дом и отображено, в результате чего результат вернется к началу: поскольку компонент .vue с одним файлом является экземпляром vue, так где же запись этого экземпляра?
Если в шаблоне есть несколько разделов, как указать корневую запись этого экземпляра vue?
为了让组件能够正常的生成一个vue实例, то этот div естественно будет обрабатываться как запись программы.
Через этот «корневой узел» рекурсивно пройдите все узлы под всем «деревом» vue, обработайте его как vdom и, наконец, отобразите его в реальном HTML и вставьте в правильное положение.
Тогда эта запись является «корнем» дерева, а каждый подэлемент и подкомпонент — «ветвью и листьями» дерева, и, естественно, это «дерево» относится к экземпляру Vue.
Вы знаете принцип nextTick?
Смотрите мою другую статью:[Принцип Vue] Анализ исходного кода $nextTick
Расскажите мне о своем понимании компиляции шаблонов Vue?
Проще говоря: сначала преобразуйте его в дерево AST и верните VNode (виртуальный DOM-узел vue) в результирующей функции рендеринга.
- Строка шаблона анализируется компилятором компиляции, а теги, инструкции, атрибуты и т. д. компилируются в синтаксическое дерево AST (то есть древовидное представление абстрактной синтаксической структуры исходного кода). createCompiler используется для создания компилятора. ) возвращаемое значение, compile отвечает за слияние опций
AST:
Node {
type: 'File',
start: 0,
end: 156,
loc:
SourceLocation {
start: Position { line: 1, column: 0 },
end: Position { line: 10, column: 0 } },
errors: [],
program:
Node {
type: 'Program',
start: 0,
end: 156,
loc: SourceLocation { start: [Object], end: [Object] },
sourceType: 'module',
interpreter: null,
body: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
directives: [] },
comments: [] }
- AST выполнит генерацию (процесс преобразования синтаксического дерева AST в строку функции рендеринга), чтобы получить функцию рендеринга.Возвращаемое значение рендеринга — VNode, который является виртуальным узлом DOM Vue, который содержит (имя тега, дочерний элемент узел, текст и т. д.)
Что такое прекомпиляция шаблона?
Предварительная компиляция: предварительная компиляция в функцию рендеринга на этапе упаковки (то есть в процессе сборки проекта).
Потому что, если возможно, часть компиляции в исходном коде vue может быть удалена для дальнейшего уменьшения размера; в то же время фактический компонент может пропускать рендеринг шаблона во время выполнения, тем самым повышая производительность.
Для компонентов Vue шаблон vue преобразуется в функцию рендеринга во время выполнения.模板编译只会在组件实例化时编译一次, Сгенерированная функция рендеринга не будет компилироваться повторно, поэтому компиляция приводит к потере производительности во время выполнения компонента. Так что подумайте о предварительной компиляции.
Каков процесс монтирования экземпляра Vue?
Крепления экземпляров в основном$mountРеализация метода имеет определение Vue.prototype.$mount в таких файлах, как src/platforms/web/entry-runtime-with-compiler.js и src/platforms/web/runtime/index.js.
В методе $mount он сначала оценивает, существует ли el в опциях, затем оценивает рендеринг (если есть шаблон, функция рендеринга также требуется), а затем снова оценивает шаблон. определенной степени, и, наконец, используемый compileToFunctions преобразует шаблон в визуализацию и staticRenderFns
Почему официальная рекомендация использовать axios вместо vue-resource?
- vue-resources больше не обновляется, и автор vue особо рекомендует axios.
- аксиос мощнее
- axios — это библиотека сетевых запросов на основе ES6 Promise, по сути, это упакованный XMLHttpRequests, то есть это тоже ajax-библиотека.
- axios создает XHR в браузере, делает http-запросы через nodejs, конвертирует или перехватывает данные запроса или данные ответа, поддерживает Promise API, может отменять запросы, автоматически преобразовывать JSON и может защищать от XSRF-атак!
- vue-resources предоставляет только версию для браузера
Как инкапсулировать аксиомы в vue?
import axios from 'axios'
axios.defaults.baseURL = ...
axios.defaults.timeout = 10000;
axios.defaults.headers.post['Content-Type'] = 'application/json';
//请求拦截
axios.interceptors.request.use(config => {
//可在此处登入
return config;
}, error => {
return Promise.reject(error);
});
//响应拦截
axios.interceptors.response.use(response => {
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
if (response.status === 200) {
if (response.data.code === 900) {
Message.error(response.data.msg)
//可在此处登出
}
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
}, error => {
if (error.response && error.response.status === 401) {
window.localStorage.removeItem('token');
}
});
/**
* axios封装get和post方法
*/
function get(url, params, config = {}) {
return new Promise((resolve, reject) => {
axios.get(url, {
params,
...config,
}).then(res => {
resolve(res.data);
}).catch(err => {
reject(err.data);
})
});
}
function post(url, params, config = {}) {
return new Promise((resolve, reject) => {
axios.post(url, params, {
...config,
})
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err.data);
})
});
}
Вы когда-нибудь сталкивались со сценарием, когда запросы axios прерывались, когда Vue переключал страницы? Как прервать?
Сценарий: В процессе одностраничной разработки Vue, когда я переключаю страницы, из-за большого времени выполнения запроса предыдущей страницы, когда я переключаюсь на эту страницу, она еще не выполнена, и запрос будет продолжать выполняться. выполняется в это время. Пока запрос не завершится, производительность страницы будет затронута в это время, и отображение данных текущей страницы может быть затронуто в некоторой степени.
Поэтому мы должны прервать все предыдущие запросы перед переключением страниц.
- Создайте токен отмены, используя фабричный метод cancelToken.source
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
- Создайте токен отмены, передав функцию-исполнитель конструктору CancelToken.
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
});
// cancel the request
cancel();
Как синхронизировать асинхронные запросы axios?
Синхронизируйте асинхронные запросы axios, используя async/await
async getData (params) {
try {
let res = await axios.get('url', {
params
})
this.tableData = res.data.result
} catch (err) {
console.log(err)
}
}
Вы также можете определить новое обещание и использовать его с async/await.
function getData (data) {
return new Promise((resolve, reject) => {
axios.get('url', {
params: data
}).then((res) => {
resolve(res)
}).catch((err) => {
reject(err)
})
})
}
async function useFun(){
try {
let res = await this.getData()
console.log(res)
//拿到返回数据res后再进行处理
} catch (err) {
console.log(err)
}
}
Принцип и анализ исходного кода axios?
Углубленный анализ исходного кода Axios
woo woo woo.cn blog on.com/IM client/afraid/780…
nuggets.capable/post/684490…(vue и реагировать разница)