Помочь вам получить большую статью о Vueconf

внешний интерфейс Vue.js
Помочь вам получить большую статью о Vueconf

предисловие

привет всем,самая популярная штука во фронтенд круге в последнее время это vueconf в 5.22.Очень интересно читать темы ниже.Учитывая что многие студенты не так знакомы с vue3,напишу превью к нескольким темам , Помогите всем получить больше 22 числа

Я заплачу всем, чтобы возместить три онлайн-билета на vueconf WeChat поиск и подписка花果山前端, ОтвечатьvueconfВы можете участвовать и дать вам красный конверт напрямую

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

image.png

проблема

Давайте по очереди введем подготовительные знания по вышеуказанным темам.официальный сайт vue3хлопнуть его

Экологический прогресс и планы Vue3

Ничего из этой репетиции, небольшой право включенного в сочетании с живой презентацией контента Vue3 и Vueconf US, слепой угадай синхронизацию Vue прогресс в развитии экосистем Личное чувство сейчас очень зрело, вы можете попробовать онлайн

Все недавно испытали опыт. Это не предварительное исследование. Когда вы хорошо слушаете, я с нетерпением жду возможности прослушивания следующего шага после прослушивания Vue3.

* Vue3近况
* Vuex 4
* Vue-router 4
* Nuxt
* 组件库
* IDE 插件 Volar啥的
* Vite2
* Vue2迁移指南
* Vue2.7 
* 展望美好的未来

Vite, новое поколение веб-инструментов

Совместное использование контента — это основная проблема существующей веб-разработки и решения Vite.

ViteНедавняя популярность не уменьшилась, и действительно решила болевые точки разработчиков, то есть веб-пакет слишком медленный, вы можете посмотреть на эту картинку.

image.png

Каждый раз, когда webpack запускает проект, его необходимо предварительно упаковать.После упаковки пакета можно запустить сервер разработки.Вот почему запуск npm run dev каждый раз занимает три минуты.Vite использует функцию импорта, которая поставляется с браузер, чтобы избежать этого шага.

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

image.png

Это просто простой принцип, для того, чтобы действительно достичь угодного состояния, Vite сделал много дополнительных усилий

* node_modules路径解析
* 插件机制 支持vue & react & svelte等框架
* 热更新 hmr
* 引入esbuild转译js, 速度贼快
* 预打包优化 node_modules/.vite
* 支持ssr
* 。。。。

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

Вы можете следить за официальным сайтом, чтобы ознакомиться с vite в последнее время, и слушать с вопросами, и урожай будет еще больше.

Новый интерфейсный инструмент — переход от вступления к реальному бою (1)

Усилия Vue3 по оптимизации компиляции

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

Два моих любимых момента в Vue3 — это композиция и оптимизация компилятора.Композиция решает проблему хаотической организации кода.Компилятор добавляется, когда мы об этом не знаем, и он действительно обеспечивает обновления по требованию.

Концепция компилятора предполагает, что вы сначала посмотрите на негоthe-super-tiny-compiler, понять основные понятия принципа компиляции, что значит paser, ast, transform, generate

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

export function baseCompile(
  template: string | RootNode,
  options: CompilerOptions = {}
): CodegenResult {
  const prefixIdentifiers =
    !__BROWSER__ && (options.prefixIdentifiers === true )

  const ast = isString(template) ? baseParse(template, options) : template
  transform(
    ast,
    extend({}, options, {
        ...
    })
  )
  return generate(
    ast,
    extend({}, options, {
      prefixIdentifiers
    })
  )
}

Чтобы упростить это

const ast = baseParse(template) // 把template解析成ast 也就是一棵树
transform(ast,option)           // 优化,比如标记和转化vue的特定语法
return genrate(ast)             // 生成的render 函数

Вы можете испытать это онлайнVue compilerрезультаты в режиме реального времени

Перед выходом в интернет мы хорошо помечаем весь динамический контент, а при выполнении браузера можем пропустить многие операции Например, на картинке выше,h1Он чисто статический и не изменится.Идентификатор и textContent div являются динамическими и могут быть изменены.Переданная функция также кэшируется.

Попробуем реализовать мини сами, посмотрим реальную стоимость внедрения.vue-next, новичкам читать немного сложно, да и правила тоже надо понимать

Мой код довольно разочаровывает, строки перебираются одна за другой, это очень дер реализация, самая протирка называетсяthe-der-tiny-compilerЧто ж, добро пожаловать в звезду

image.png

Давайте попробуем смоделировать и написать очень простую реализацию, чтобы всем было понятно используйте приведенный выше ввод


function compiler(template) {
  const ast = parse(template);
  transform(ast)
  const code = generate(ast)
  return new Function(code);
}

let tmpl = `<div id="app">
      <p @click="add" :id="name">{{name}}</p>
      <h1 class="item">技术摸鱼</h1>
  </div>`


let render = compiler(tmpl)

tokens

Сначала напишите, чтобы разбить строку на токены


function tokenizer(input) {
  let tokens = []
  let type = ''
  let val = ''
  // 粗暴循环
  for (let i = 0; i < input.length; i++) {
    let ch = input[i]
    if (ch === '<') {
      push()
      if (input[i + 1] === '/') {
        type = 'tagend'
      } else {
        type = 'tagstart'
      }
    } if (ch === '>') {
      push()
      type = "text"
      continue
    } else if (/[\s]/.test(ch)) { // 碰见空格夹断一下
      push()
      type = 'props'
      continue
    }
    val += ch
  }
  return tokens

Мы получили это

[
  { type: 'tagstart', val: 'div' },
  { type: 'props', val: 'id="app"' },
  { type: 'tagstart', val: 'p' },
  { type: 'props', val: '@click="add"' },
  { type: 'props', val: ':id="name"' },
  { type: 'text', val: '{{name}}' },
  { type: 'tagend', val: 'p' },
  { type: 'tagstart', val: 'h1' },
  { type: 'props', val: 'class="item"' },
  { type: 'text', val: '技术摸鱼' },
  { type: 'tagend', val: 'h1' },
  { type: 'tagend', val: 'div' }
]

parse

Затем придумайте ast, чтобы сгенерировать дерево

function parse(template) {
  const tokens = tokenizer(template)
  let cur = 0
  let ast = {
    type: 'root',
    props:[],
    children: []
  }
  while (cur < tokens.length) {
    ast.children.push(walk())
  }
  return ast

  function walk() {
    let token = tokens[cur]
    if (token.type == 'tagstart') {
      let node = {
        type: 'element',
        tag: token.val,
        props: [],
        children: []
      }
      token = tokens[++cur]
      while (token.type !== 'tagend') {
        if (token.type == 'props') {
          node.props.push(walk())
        } else {
          node.children.push(walk())
        }
        token = tokens[cur]
      }
      cur++
      return node
    }
    if (token.type === 'tagend') {
      cur++
      // return token
    }
    if (token.type == "text") {
      cur++
      return token
    }
    if (token.type === "props") {
      cur++
      const [key, val] = token.val.split('=')
      return {
        key,
        val
      }
    }
  }
}

наконец получить аст

{
  "type": "root",
  "props": [],
  "children": [
    {
      "type": "element",
      "tag": "div",
      "props": [
        {
          "key": "id",
          "val": "\"app\""
        }
      ],
      "children": [
        {
          "type": "element",
          "tag": "p",
          "props": [
            {
              "key": "@click",
              "val": "\"add\""
            },
            {
              "key": ":id",
              "val": "\"name\""
            }
          ],
          "children": [
            {
              "type": "text",
              "val": "{{name}}"
            }
          ]
        },
        {
          "type": "element",
          "tag": "h1",
          "props": [
            {
              "key": "class",
              "val": "\"item\""
            }
          ],
          "children": [
            {
              "type": "text",
              "val": "技术摸鱼"
            }
          ]
        }
      ]
    }
  ]
}

transform

Затем оптимизируйте его, в основном, чтобы сделать пометку, пометить атрибуты, статичен ли текст

function transform(ast) {
  // 优化一下ast
  let context = {
    // import { toDisplayString , createVNode , openBlock , createBlock } from "vue"
    helpers:new Set(['openBlock','createVnode']), // 用到的工具函数 
  }
  traverse(ast, context)
  ast.helpers = context.helpers
}
function traverse(ast, context){
  switch(ast.type){
    case "root":
      context.helpers.add('createBlock')
      // log(ast)
    case "element":
      ast.children.forEach(node=>{
        traverse(node,context)
      })
      ast.flag = {props:false,class:false,event:false}
      ast.props = ast.props.map(prop=>{
        const {key,val} = prop
        if(key[0]=='@'){
          ast.flag.event = true
          return {
            key:'on'+key[1].toUpperCase()+key.slice(2),
            val
          }
        }
        if(key[0]==':'){
          ast.flag.props = true
          return{
            key:key.slice(1),
            val
          }
        }
        if(key.startsWith('v-')){
          // pass such as v-model
        }
        return {...prop,static:true}
      })
      break
    case "text":
      // trnsformText
      let re = /\{\{(.*)\}\}/g
      if(re.test(ast.val)){
        //有{{
          ast.static = false
          context.helpers.add('toDisplayString')
          ast.val = ast.val.replace(/\{\{(.*)\}\}/g,function(s0,s1){
            return s1
          })
      }else{
        ast.static = true
      }
  }
}

в основном используютast.flag = {props:false,class:false,event:false}Чтобы отметить, если это ложно, все статично, и вы можете напрямую пропустить виртуальный dom diff

generate

Затем нужно сгенерировать код, написать строку

function generate(ast) {
  const {helpers} = ast 

  let code = `
import {${[...helpers].map(v=>v+' as _'+v).join(',')}} from 'vue'\n
export function render(_ctx, _cache, $props){
  return(_openBlock(), ${ast.children.map(node=>walk(node))})}`

  function walk(node){
    switch(node.type){
      case 'element':
        let {flag} = node // 编译的标记
        let props = '{'+node.props.reduce((ret,p)=>{
          if(flag.props){
            //动态属性
            ret.push(p.key +':_ctx.'+p.val.replace(/['"]/g,'') )
          }else{
            ret.push(p.key +':'+p.val )
          }

          return ret
        },[]).join(',')+'}'
        return `_createVnode("${node.tag}",${props}),[
          ${node.children.map(n=>walk(n))}
        ],${JSON.stringify(flag)}`
        break
      case 'text':
        if(node.static){
          return '"'+node.val+'"'
        }else{
          return `_toDisplayString(_ctx.${node.val})`
        }
        break
    }
  }
  return code
}

вы получаете этот код

import { openBlock as _openBlock, createVnode as _createVnode, createBlock as _createBlock, toDisplayString as _toDisplayString } from 'vue'

export function render(_ctx, _cache, $props) {
    return (_openBlock(), _createVnode("div", { id: "app" }), [
        _createVnode("p", { onClick: _ctx.add, id: _ctx.name }), [
            _toDisplayString(_ctx.name)
        ], { "props": true, "class": false, "event": true }, _createVnode("h1", { class: "item" }), [
            "技术摸鱼"
        ], { "props": false, "class": false, "event": false }
    ], { "props": false, "class": false, "event": false })
}

Хоть он и далек от vue, но имеет внутренний вкус.В будущем можно использовать пропсы и события.Эти теги помечены битовыми операциями.

Хотя реализация очень дер (голос), мастера слегка брызгают, но компилятору достаточно помочь понять vue3.Статью напишу, когда будет возможность сделать хорошо (@todo)

После прочтения знаний шерера я сделаю компилятор в стиле svelte, который в будущем компилирует прямо в дом.Действительно ли Vue хочет быть семейным ведром?

Оптимизация кода для инструментов сборки следующего поколения


要充分用上这些新工具的独特能力,如更快的模块热更新、跨模块代码复用、强构建缓存等,我们的项目代码也需要与时俱进。

本主题将会分享我在研究构建工具时总结的一些易于发挥工具潜力的编码技巧与开发流程实践。

Как бы это сказать, я не могу предсказать, что сказать.Слепое угадывание - новая идея и вспомогательная функция, предоставляемая этими инструментами? Я напишу резюме после прочтения vueconf

Это должен быть обмен, который может повысить эффективность разработки

Исследуйте JSX в Vue 3

Для JSX и шаблона шаблон рекомендуется в большинстве сценариев, особенно в бизнес-сценариях. Хотя шаблон Vue 3 обеспечивает множество оптимизаций производительности, для некоторых разработчиков библиотек шаблон может быть недостаточно гибким, а способ использования JSX более гибким. В этом обмене я расскажу вам о различиях между JSX и шаблоном, а также поделюсь некоторыми идеями дизайна плагинов Vue 3 JSX и навыками разработки плагинов Babel.

Компилятор jsx немного проще, чем тот, что идет с vue3, потому что оптимизаций разметки меньше, и можно в основном научиться участвовать в проектировании экологии vue3, а также навыкам работы с плагинами babel

Наш der-компилятор выше, если его изменить и добавить загрузчик, его тоже можно использовать для парсинга jsx.

Еще немного путаницы в том, что шаблон сделал много статических тегов, но я только что запустил демо. Производительность jsx на самом деле аналогична производительности шаблона. Разница между 5000 компонентами составляет около 10 мс. Я с нетерпением жду большего понимание шаблона и jsx завтра.

Composable Vue

Знакомство с базовыми принципами Vue Composition API, обмен навыками и шаблонами для написания качественных составных функций.

Принцип композиции хорош,Кодовый адрес vue-next здесь

  // 2. call setup()
  const { setup } = Component
  if (setup) {
    const setupContext = (instance.setupContext =
      setup.length > 1 ? createSetupContext(instance) : null)

    currentInstance = instance
    const setupResult = callWithErrorHandling(
      setup,
      instance,
      ErrorCodes.SETUP_FUNCTION,
      [__DEV__ ? shallowReadonly(instance.props) : instance.props, setupContext]
    )
 
 
 export function callWithErrorHandling(fn,instance,type,args) {
  let res
  try {
    res = args ? fn(...args) : fn()
  } catch (err) {
    handleError(err, instance, type)
  }
  return res

Другие оценки больше касаются его библиотеки vue.use, которая предназначена для инкапсуляции повседневных общих функций в стиле useXX, таких как изменение небольших значков веб-страниц.

import { useFavicon } from '@vueuse/core'
const icon = useFavicon()
icon.value = 'dark.png' // change current icon

На самом деле внутри нужно найти тег ссылки и изменить href, но API делает его очень удобным для вас.

export function useFavicon(
  newIcon: MaybeRef<string | null | undefined> = null,
  options: FaviconOptions = {},
) {
  const {
    baseUrl = '',
    rel = 'icon',
    document = defaultDocument,
  } = options

  const favicon = isRef(newIcon)
    ? newIcon
    : ref<string | null>(newIcon)

  const applyIcon = (icon: string) => {
    document?.head
      .querySelectorAll<HTMLLinkElement>(`link[rel*="${rel}"]`)
      .forEach(el => el.href = `${baseUrl}${icon}`)
  }

  watch(
    favicon,
    (i, o) => {
      if (isString(i) && i !== o)
        applyIcon(i)
    },
    { immediate: true },
  )

  return favicon
}

Кстати, фавикон тоже можно настроить на видео и камеру, вернусь и упомяну про 囧

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

Разработка технических инструментов для рыбалки (1) 60 строк кода для реализации favcion рыбалки

Создайте высокопроизводительное приложение Flutter с помощью Vue.js

В настоящее время кросс-энд стал темой, которую нельзя обойти фронтендом.С ростом популярности IoT-устройств в нашей повседневной разработке появляется все больше и больше «концов». Начиная с Hybrid и React Native (Weex), Flutter стал новым любимцем кросс-энда за последние два года благодаря оптимизированному конвейеру рендеринга и функциям самостоятельного рендеринга. Однако его модель разработки Dart + Widget и экология, отделенная от внешнего интерфейса, привели к высоким затратам на исследования и разработки. Основываясь на этом опыте, мы изучаем прикладное решение Flutter, основанное на стандарте W3C, которое соединяет интерфейсную экосистему вверх и обеспечивает многостороннюю согласованность за счет саморисования вниз. Я расскажу вам о решении для разработки приложений Flutter с помощью Vue.js, а также о практике и размышлениях, лежащих в основе Kraken.

Большой брат в Группе сказал, что это очень полезно, но я не очень заинтересован в трепетании.

Разработка мультитерминальных приложений на основе Vue 3.0

Новая версия компилятора uni-app была обновлена ​​до Vite, а среда выполнения была обновлена ​​до Vue 3.0.После обновления скорость компиляции uni-app была значительно улучшена, а также было проведено множество оптимизаций производительности во время выполнения.

本次我将分享 uni-app 在升级 Vue 3.0 过程中的系列探索和思考,主要内容包括:
1、基于 Vite 重新实现 uni 编译器
2、利用 Composition API 重写 uni-app 内置组件
3、更小、更快、可摇树的 uni runtime
4、根据平台差异,量身裁剪 Vue 3.0 runtime
5、使用 Vue 3.0开发多端应用的优势(运行性能/灵活性/编译速度等)

Кросс-энд Vue также является приложением с большим рынком.После того, как runtime-core и runtime-dom разделены, мы можем настроить рендерер на основе runtime-core. Рендеринг vue3 на любую платформу, которую вы хотите, я написал игрушку, которая рендерит холст, когда я учился

import { createRenderer } from '@vue/runtime-core'
let ctx

function draw(ele, isChild) {
  if (!isChild) {
    ctx.clearRect(0, 0, 500, 500)
  }
  ctx.fillStyle = ele.fill || 'white'
  ctx.fillRect(...ele.pos)
  if (ele.text) {
    ctx.fillStyle = ele.color || 'white'
    ele.fontSize = ele.type == "h1" ? 20 : 12
    ctx.font = (ele.fontSize || 18) + 'px serif'
    ctx.fillText(ele.text, ele.pos[0] + 10, ele.pos[1] + ele.fontSize)
  }
  ele.child && ele.child.forEach(c => {
    draw(c, true)
  })

}

const { createApp: originCa } = createRenderer({
  insert: (child, parent, anchor) => {
    if (typeof child == 'string') {
      parent.text = child
    } else {
      child.parent = parent
      if (!parent.child) {
        parent.child = [child]
      } else {
        parent.child.push(child)
      }
    }
    if (parent.nodeName) {
      draw(child)
      if (child.onClick) {
        ctx.canvas.addEventListener('click', () => {
          child.onClick()
          setTimeout(() => {
            draw(child)
          })
        }, false)
      }
    }


  },
  createElement(type, isSVG, isCustom) {
    return {
      type
    }
  },
  setElementText(node, text) {
    node.text = text
  },
  patchProp(el, key, prev, next) {
    el[key] = next
  },
  parentNode: node => node,
  nextSibling: node => node,
  createText: text => text,
  remove:node=>node

});
function createApp(...args) {
  const app = originCa(...args)
  return {
    mount(selector) {
      const canvas = document.createElement('canvas')
      canvas.width = window.innerWidth
      canvas.height = window.innerHeight
      document.querySelector(selector).appendChild(canvas)
      ctx = canvas.getContext('2d')
      app.mount(canvas)
    }
  }
}
export { createApp }



Затем вы можете играть так, превращая размер и положение холста в отзывчивые элементы управления.

<template>
<div @click="setName('vue3真棒')" :pos="[10,10,300,300]" fill="#eee">
    <h1 :pos="[20,20,200,100]" fill="red" color="#000">累加器{{count}}</h1>
    <span :pos="pos" fill="black" >哈喽{{name}}</span>
</div>

</template>

<script>

import {ref} from 'vue'
export default {
  setup(){
    const name = ref('kkb')
    const pos = ref([20,120,200,100])
    const count = ref(1)
    const setName = (n)=>{
      name.value = n
      pos.value[1]+=20
      count.value+=2
    }
    return {
      name,
      setName,
      pos,
      count
    }
  }
}
</script>



В нашей группе мы сотрудничали с pixijs, чтобы написатьреактивный истребитель vue3Вы можете ссылаться на игру

Converting Browser Libraries into Vue hooks/composables.

Единственный иностранец, который поделился Я чувствую, что могут быть конфликты с содержанием vueuse, и нет конкретного введения.Я не могу угадать, что сказать.От автора работа Джонатана

Еще ничего не видел, с нетерпением жду возможности поделиться

Молниеносная доля

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

Суммировать

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

Я заплачу всем, чтобы возместить три онлайн-билета на vueconf WeChat поиск и подписка花果山前端, ОтвечатьvueconfВы можете принять участие и вручить вам красный конверт напрямую

Отвечать读书Присоединяйтесь к группе и обсудите опыт и опыт Vueconf в групповом прямом эфире завтра, король также приветствуется