当前位置: 首页 > news >正文

东莞网站建设市场/做网站平台需要多少钱

东莞网站建设市场,做网站平台需要多少钱,哪些网站做京东的团购,玉溪做网站的公司文章目录 Vue 3.0 和 2.x 的区别源码组织方式packages 目录结构 不同构建版本Composition API 设计动机设计动机Options API Demo:Composition API Demo:对比: 性能提升响应式系统升级编译优化优化打包体积 ViteESModuleVite as Vue-CLIVite 特点 Composition APICo…

文章目录

    • Vue 3.0 和 2.x 的区别
    • 源码组织方式
      • packages 目录结构
    • 不同构建版本
    • Composition API 设计动机
      • 设计动机
        • Options API Demo:
        • Composition API Demo:
        • 对比:
    • 性能提升
      • 响应式系统升级
      • 编译优化
      • 优化打包体积
    • Vite
      • ESModule
      • Vite as Vue-CLI
      • Vite 特点
    • Composition API
      • Composition API
      • 生命周期钩子函数
      • reactive|toRefs|ref
      • computed
      • watch
      • watchEffect
    • todoList
      • todoList - 功能演示
      • todoList - demo

Vue 3.0 和 2.x 的区别

  • 源码组织方式的变化
  • Composition API
  • 性能提升
  • Vite

源码全部采用 TS 重写,组织方式也发生变化,使用 Monorepo 的方式来组织项目的结构,把独立的功能模块都提取到不同的包中。

虽然重写,但是 90% 都兼容 2.x 的API,根据社区反馈,增加了 Composition API,组合式API,旨在解决开发超大型项目遇到超大组件使用Options API 不好拆分重用的问题。

性能方面,大幅度提升,使用 Proxy(代理对象) 重写了响应式代码,并且对编译器做了优化,重写了虚拟DOM,让渲染和update的性能有了大幅度的提升。另外,官方介绍,服务端渲染的性能也提升了 2-3 倍。

Vite 工具的发布,使开发阶段不需要打包直接运行项目,提升开发效率。

源码组织方式

在这里插入图片描述

packages 目录结构

在这里插入图片描述

不同构建版本

Vue3.0中不再构建 UMD 模块化的方式,因为冗余太多。
构建版本:4类
在这里插入图片描述
CommonJS:

  • cjs
    • vue.cjs.js
    • vue.cjs.prod.js

Global: 可以直接通过 script 标签直接导入

  • global
    • vue.global.js
    • vue.global.prod.js
    • vue.runtime.global.js
    • vue.runtime.global.prod.js

Browser: ESModule ,可以直接通过 script type=module 的方式导入

  • browser
    • vue.esm-browser.js
    • vue.esm-browser.prod.js
    • vue.runtime.esm-browser.js
    • vue.runtime.esm-browser.prod.js

Bundler: 需要配合打包工具来使用,ESM 方式

  • bundler
    • vue.esm-bundler.js
    • vue.runtime.esm-bundler.js

Composition API 设计动机

  • RFC(request for comments)
    • https://github.com/vuejs/rfc
  • Composition API RFC
    • https://composition-api.vuejs.org

设计动机

  • Options API

    • 包含一个描述组件选项(data.methods.props等)对象
    • Options API 开发复杂组件,同一个功能逻辑的代码被拆分到不同选项
  • Composition API

    • Vue.js 3.0 新增的一组 API
    • 一组基于函数的 API
    • 可以更灵活的组织组件的逻辑

Options API Demo:

在这里插入图片描述

Composition API Demo:

在这里插入图片描述

对比:

在这里插入图片描述

性能提升

  • 响应式系统升级
  • 编译优化
  • 源码体积的优化

响应式系统升级

在这里插入图片描述

编译优化

在这里插入图片描述

优化打包体积

在这里插入图片描述

Vite

Vite 来自于 法语,意思是 快。

ESModule

在这里插入图片描述

Vite as Vue-CLI

在这里插入图片描述
在这里插入图片描述

Vite 特点

在这里插入图片描述

Composition API

注意:Composition API 仅仅是 Vue3中新增的 API,我们依然可以使用 Options API。

Composition API

生命周期钩子函数

在这里插入图片描述

reactive|toRefs|ref

ref demo:

<body><div id="app"><button @click="increase">加加</button><span>{{count}}</span></div><script type="module">import { createApp, ref } from './node_modules/vue/dist/vue.esm-browser.js'function useCount(){const count = ref(0)return {count,increase:()=>{count.value ++}}}const app = createApp({setup() {return {...useCount()}}})app.mount('#app')</script>
</body>

Composition API 生命周期 reactive toRefs ref demo:

<body><div id="app">x: {{x}}<br />y: {{y}}</div><script type="module">import { createApp, reactive, onMounted, onUnmounted, toRefs } from './node_modules/vue/dist/vue.esm-browser.js'function useMousePosition() {let position = reactive({x: 0,y: 0})const update = (e) => {position.x = e.pageXposition.y = e.pageY}onMounted(() => {window.addEventListener('mousemove', update)})onUnmounted(() => {window.removeEventListener('mousemove', update)})return toRefs(position)}const app = createApp({setup() {// const position = useMousePosition()const { x, y } = useMousePosition()return { x, y }}})app.mount('#app')</script>
</body>

computed

<body><div id="app"><button @click="push">按钮</button>未完成:{{activeCount}}</div><script type="module">import { createApp, reactive, computed } from './node_modules/vue/dist/vue.esm-browser.js'const data = [{ text: '看书', completed: false },{ text: '敲代码', completed: false },{ text: '约会', completed: true }]const app = createApp({setup() {const todos = reactive(data)const activeCount = computed(() => {return todos.filter((item) => !item.completed).length})return {activeCount,push:()=>{todos.push({text: '看电视',completed: false})}}}})app.mount('#app')</script>
</body>

watch

在这里插入图片描述

<body><div id="app"><p>请问一个 yes/no 的问题:<input v-model="question"></p><p>{{answer}}<img :src="img"></p></div><script type="module">// https://www.yesno.wtf/apiimport { createApp, ref, watch } from './node_modules/vue/dist/vue.esm-browser.js'const app = createApp({setup() {const question = ref('')const answer = ref('')const img = ref('')watch(question, async (newValue, oldValue)=>{console.log()const response = await fetch('https://www.yesno.wtf/api')const {answer: as, image: src} = await response.json()answer.value = asimg.value = src})return {question,answer,img}}})app.mount('#app')</script>
</body>

watchEffect

在这里插入图片描述

<body><div id="app"><button @click="increase">increase</button><button @click="stop">stop</button><br>{{count}}</div><script type="module">// https://www.yesno.wtf/apiimport { createApp, ref, watchEffect } from './node_modules/vue/dist/vue.esm-browser.js'const app = createApp({setup() {const count = ref(0)const stop = watchEffect(()=>{console.log(count.value)})return {count,stop,increase:()=>{count.value ++}}}})app.mount('#app')</script>
</body>

todoList

todoList - 功能演示

在这里插入图片描述
在这里插入图片描述

todoList - demo

vue 代码:

<template><section id="app" class="todoapp"><header class="header"><h1>todos</h1><inputclass="new-todo"placeholder="请输入代办项目"autocomplete="off"autofocusv-model="input"@keyup.enter="addTodo"/></header><section class="main" v-show="count"><input id="toggle-all" class="toggle-all" type="checkbox" v-model="allDone"/><label for="toggle-all">Mark all as complete</label><ul class="todo-list"><liv-for="todo in filteredTodos":key="todo":class="{ editing: todo === editingTodo, completed: todo.completed }"><div class="view"><input class="toggle" type="checkbox" v-model="todo.completed"/><label @dblclick="editTodo(todo)">{{ todo.text }}</label><button class="destroy" @click="remove(todo)"></button></div><inputclass="edit"type="text"v-editing-focus="todo === editingTodo"v-model="todo.text"@keyup.enter="doneEdit(todo)"@blur="doneEdit(todo)"@keyup.esc="cancelEdit(todo)"/></li></ul></section><footer class="footer" v-show="count"><span class="todo-count"> <strong>{{remainingCount}}</strong> {{remainingCount > 1 ? 'items' : 'item'}} left(剩余) </span><ul class="filters"><li><a href="#/all">全部</a></li><li><a href="#/active">待完成</a></li><li><a href="#/completed">已完成</a></li></ul><button class="clear-completed" @click="removeCompleted" v-show="count > remainingCount">Clear completed</button></footer></section><footer class="info"><p>双击编辑单个项目</p><!-- Remove the below line ↓ --><p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p><!-- Change this out with your name and url ↓ --><p>Created by <a href="https://www.lagou.com">教瘦</a></p><p>Part of <a href="http://todomvc.com">TodoMVC</a></p></footer>
</template>
<script>
import "@/assets/index.css";
import useLocalStorage from "./utils/useLocalStorage";
import { computed, onMounted, onUnmounted, ref, watchEffect } from "vue";
const storage = useLocalStorage()
// 添加代办事项
const useAdd = (todos) => {const input = ref("");const addTodo = () => {const text = input.value && input.value.trim();if (text.length === 0) return;todos.value.unshift({text,completed: false,});input.value = "";};return {input,addTodo,};
};
// 删除代办事项
const useRemove = (todos) => {const remove = (todo) => {const index = todos.value.indexOf(todo);todos.value.splice(index, 1);};const removeCompleted = ()=>{todos.value = todos.value.filter(todo=>!todo.completed)}return { remove, removeCompleted };
};
// 编辑代办事项
const useEdit = (remove) => {// 1、双击待办事项,展示文本框// 2、按回车或者编辑文本框失去焦点,修改数据// 3、按ESC取消编辑// 4、把编辑文本框清空,按回车,删除这一项// 5、显示编辑文本框的时候,获取焦点let beforeEditingText = ""; // 编辑之前的数据const editingTodo = ref(null); // 正在编辑的对象,标识编辑的状态const editTodo = (todo) => {beforeEditingText = todo.text;editingTodo.value = todo;};const doneEdit = (todo) => {if (!editingTodo.value) return;todo.text = todo.text.trim();todo.text || remove(todo);editingTodo.value = null;};const cancelEdit = (todo) => {editingTodo.value = null;todo.text = beforeEditingText;};return {editingTodo,editTodo,doneEdit,cancelEdit,};
};
/*** 切换代办项完成状态* 1、点击 checkbox 改变所有代办项状态* 2、All/Active/Completed* 3、其他* 3-1、显示未完成代办项个数* 3-2、移除所有已完成项目* 3-3、如果没有代办项,隐藏 main 和 footer*/
const useFilter = todos => {const allDone = computed({get(){return !todos.value.filter(todo=>!todo.completed).length},set(value){todos.value.forEach(todo=>{todo.completed = value})}})const filter = {all: list => list,active: list=>list.filter(todo=>!todo.completed),completed: list=>list.filter(todo=>todo.completed)}const type = ref('all')const filteredTodos = computed(()=>filter[type.value](todos.value))const remainingCount = computed(()=>filter.active(todos.value).length)const count = computed(()=>todos.value.length)const onHashChange = ()=>{const hash = window.location.hash.replace('#/','')if(filter[hash]){type.value = hash} else {type.value = 'all'window.location.hash = ''}}onMounted(()=>{window.addEventListener('hashchange',onHashChange)onHashChange()})onUnmounted(()=>{window.removeEventListener('hashchange', onHashChange)})return {count,allDone,filteredTodos,remainingCount}
}// 存储待办事项
const useStorage = ()=>{const KEY = 'TODOKEYS'const todos = ref(storage.getItem(KEY) || [])watchEffect(()=>{storage.setItem(KEY, todos.value)})return todos
}export default {name: "App",setup() {// const todos = ref([]);const todos = useStorage();const { remove, ...removes } = useRemove(todos);return {todos,remove,...removes,...useAdd(todos),...useEdit(remove),...useFilter(todos)};},directives: {editingFocus: (el, binding)=>{binding.value && el.focus()}}
};
</script>
<style scoped>
</style>

index.css

html,
body {margin: 0;padding: 0;
}button {margin: 0;padding: 0;border: 0;background: none;font-size: 100%;vertical-align: baseline;font-family: inherit;font-weight: inherit;color: inherit;-webkit-appearance: none;appearance: none;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;
}body {font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;line-height: 1.4em;background: #f5f5f5;color: #111111;min-width: 230px;max-width: 550px;margin: 0 auto;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;font-weight: 300;
}:focus {outline: 0;
}.hidden {display: none;
}.todoapp {background: #fff;margin: 130px 0 40px 0;position: relative;box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),0 25px 50px 0 rgba(0, 0, 0, 0.1);
}.todoapp input::-webkit-input-placeholder {font-style: italic;font-weight: 300;color: rgba(0, 0, 0, 0.4);
}.todoapp input::-moz-placeholder {font-style: italic;font-weight: 300;color: rgba(0, 0, 0, 0.4);
}.todoapp input::input-placeholder {font-style: italic;font-weight: 300;color: rgba(0, 0, 0, 0.4);
}.todoapp h1 {position: absolute;top: -140px;width: 100%;font-size: 80px;font-weight: 200;text-align: center;color: #b83f45;-webkit-text-rendering: optimizeLegibility;-moz-text-rendering: optimizeLegibility;text-rendering: optimizeLegibility;
}.new-todo,
.edit {position: relative;margin: 0;width: 100%;font-size: 24px;font-family: inherit;font-weight: inherit;line-height: 1.4em;color: inherit;padding: 6px;border: 1px solid #999;box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);box-sizing: border-box;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;
}.new-todo {padding: 16px 16px 16px 60px;border: none;background: rgba(0, 0, 0, 0.003);box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
}.main {position: relative;z-index: 2;border-top: 1px solid #e6e6e6;
}.toggle-all {width: 1px;height: 1px;border: none; /* Mobile Safari */opacity: 0;position: absolute;right: 100%;bottom: 100%;
}.toggle-all + label {width: 60px;height: 34px;font-size: 0;position: absolute;top: -52px;left: -13px;-webkit-transform: rotate(90deg);transform: rotate(90deg);
}.toggle-all + label:before {content: '❯';font-size: 22px;color: #e6e6e6;padding: 10px 27px 10px 27px;
}.toggle-all:checked + label:before {color: #737373;
}.todo-list {margin: 0;padding: 0;list-style: none;
}.todo-list li {position: relative;font-size: 24px;border-bottom: 1px solid #ededed;
}.todo-list li:last-child {border-bottom: none;
}.todo-list li.editing {border-bottom: none;padding: 0;
}.todo-list li.editing .edit {display: block;width: calc(100% - 43px);padding: 12px 16px;margin: 0 0 0 43px;
}.todo-list li.editing .view {display: none;
}.todo-list li .toggle {text-align: center;width: 40px;/* auto, since non-WebKit browsers doesn't support input styling */height: auto;position: absolute;top: 0;bottom: 0;margin: auto 0;border: none; /* Mobile Safari */-webkit-appearance: none;appearance: none;
}.todo-list li .toggle {opacity: 0;
}.todo-list li .toggle + label {/*Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/*/background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');background-repeat: no-repeat;background-position: center left;
}.todo-list li .toggle:checked + label {background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E');
}.todo-list li label {word-break: break-all;padding: 15px 15px 15px 60px;display: block;line-height: 1.2;transition: color 0.4s;font-weight: 400;color: #4d4d4d;
}.todo-list li.completed label {color: #cdcdcd;text-decoration: line-through;
}.todo-list li .destroy {display: none;position: absolute;top: 0;right: 10px;bottom: 0;width: 40px;height: 40px;margin: auto 0;font-size: 30px;color: #cc9a9a;margin-bottom: 11px;transition: color 0.2s ease-out;
}.todo-list li .destroy:hover {color: #af5b5e;
}.todo-list li .destroy:after {content: '×';
}.todo-list li:hover .destroy {display: block;
}.todo-list li .edit {display: none;
}.todo-list li.editing:last-child {margin-bottom: -1px;
}.footer {padding: 10px 15px;height: 20px;text-align: center;font-size: 15px;border-top: 1px solid #e6e6e6;
}.footer:before {content: '';position: absolute;right: 0;bottom: 0;left: 0;height: 50px;overflow: hidden;box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),0 8px 0 -3px #f6f6f6,0 9px 1px -3px rgba(0, 0, 0, 0.2),0 16px 0 -6px #f6f6f6,0 17px 2px -6px rgba(0, 0, 0, 0.2);
}.todo-count {float: left;text-align: left;
}.todo-count strong {font-weight: 300;
}.filters {margin: 0;padding: 0;list-style: none;position: absolute;right: 0;left: 0;
}.filters li {display: inline;
}.filters li a {color: inherit;margin: 3px;padding: 3px 7px;text-decoration: none;border: 1px solid transparent;border-radius: 3px;
}.filters li a:hover {border-color: rgba(175, 47, 47, 0.1);
}.filters li a.selected {border-color: rgba(175, 47, 47, 0.2);
}.clear-completed,
html .clear-completed:active {float: right;position: relative;line-height: 20px;text-decoration: none;cursor: pointer;
}.clear-completed:hover {text-decoration: underline;
}.info {margin: 65px auto 0;color: #4d4d4d;font-size: 11px;text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);text-align: center;
}.info p {line-height: 1;
}.info a {color: inherit;text-decoration: none;font-weight: 400;
}.info a:hover {text-decoration: underline;
}/*Hack to remove background from Mobile Safari.Can't use it globally since it destroys checkboxes in Firefox
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {.toggle-all,.todo-list li .toggle {background: none;}.todo-list li .toggle {height: 40px;}
}@media (max-width: 430px) {.footer {height: 50px;}.filters {bottom: 10px;}
}

utils/useLocalStorage.js

function parse(str){let valuetry{value = JSON.parse(str)}catch{value = null}return value
}
function stringify(obj){let valuetry{value = JSON.stringify(obj)}catch{value = null}return value
}export default function useLocalStorage(){function setItem(key, value){value = stringify(value)window.localStorage.setItem(key, value)}function getItem(key){let value = window.localStorage.getItem(key)if(value){value = parse(value)}return value}return {setItem,getItem}
}

环境&依赖

node 18.16.0
vue 3.3.2

自定义指令一、
在这里插入图片描述
自定义指令二、
在这里插入图片描述

http://www.jmfq.cn/news/5257729.html

相关文章:

  • 买域名后 怎么做网站/关键词点击价格查询
  • 河池市住房城乡建设网站/软件开发工资一般多少
  • 纺织厂网站模板/百度统计数据分析
  • 广元市剑阁县建设局网站/网络销售好不好做
  • 潍坊哪里能找到做网站的/成都黑帽seo
  • 哪个网站做简历/semir是什么意思
  • 广州网站建设信科网络/网站流量统计查询
  • 国内使用wordpress/百度seo推广
  • 百度站点管理/今日新闻最新头条10条
  • jsp做网站实例教程/福州seo
  • 机票酒店 网站建设/打开百度一下网页版
  • 浅析淘宝网站的建设与运营论文/快手seo软件下载
  • 金融直播室网站建设/小程序商城
  • 上海企业网站备案/婚恋网站排名前10
  • 提升网站建设/竞价托管就选微竞价
  • 旅游网站开发需求/网络营销的目标
  • 网站备案主体授权书/竞价托管多少钱一个月
  • 免费虚拟机安卓版/seo关键词排名技术
  • 东莞家具网站建设/小吃培训2000元学6项
  • 520高清网站三级黄色软件男女做/安卓优化大师官网下载
  • 南京网站推广¥做下拉去118cr/nba排名2021最新排名
  • 做3d图的网站/设计网站模板
  • 网站群建设管理办法/网站优化排名方法有哪些
  • 做电商网站电商公司/武汉seo招聘
  • 企业建站公司报价/拉新推广一手接单平台
  • 曲阜网站建设哪家便宜/百度网页入口
  • 用dw做网站怎么单独修改字体/网络推广运营
  • css不规则网站导航怎么做/建站网站
  • 代做毕业设计网站多少钱/做直销去哪里找客户
  • 浦东网站建设公司/谷歌推广外包