Vuejs 于2020年9月19日凌晨发布了代号为One Piece的 3.0 版本,简称Vue3。体验一下新版本的魅力。
                 爱校码
主要面向具有Vue 2以前经验的用户,想了解Vue 3的新功能和更改。
① 通过CDN:
CDN(Content Delivery Network)是指内容分发网络,也称为内容传送网络。由于CDN是为加快网络访问速度而被优化的网络覆盖层,因此被形象地称为“网络加速器”。出于原型制作或学习目的,可以这样使用最新版本:
<script src="https://unpkg.com/vue@next"></script>
创建Vue实例,并连接到<div id="app"></div>组件:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>CDN案例</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>  
        <div id="app">
        </div>
        <script>
            //使用Vue创建一个实例连接到app组件,注入内容
            Vue.createApp({
                template: '<div>Hello World! </div>'
            }).mount('#app');
        </script>
</body>
</html>
对于生产环境,推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏。
② 下载JavaScript文件并自己托管:
如果想避免使用构建工具,但又无法在生产环境使用 CDN,那么可以下载相关 .js 文件并自行托管在项目的服务器上。然后通过 <script> 标签引入,与使用 CDN 的方法类似。
这些文件可以在 unpkg 或者 jsDelivr 这些 CDN 上浏览和下载。通常需要同时下载开发环境构建版本以及生产环境构建版本。
在 */dist/ 目录将会找到很多不同的 Vue.js 构建版本。根据不同的使用情况,应该使用哪个 dist 文件:
没有构建工具的使用:
vue(.runtime).global(.prod).js
<script src="..."> 直接使用,则暴露 Vue 全局。选择不同的js文件
vue.global.js          # 是包含编译器和运行时的“完整”构建,因此它支持动态编译模板。
vue.runtime.global.js  # 只包含运行时,并且需要在构建步骤期间预编译模板。
prod/dev分支,并且prod构建是预先压缩为最小化的版本, 使用* .prod.js文件用于生产环境。全局打包不是 UMD(通用模块定义) 构建的,它们被打包成 IIFE(立即调用函数表达式),并且仅用于通过 <script src="..."> 直接使用。
使用构建工具:
vue(.runtime).esm-bundler.js
webpack,rollup 和 parcel等构建工具。process.env.NODE_ENV 守卫语句 (必须由构建工具替换)。例如:@vue/runtime-core,@vue/runtime-compiler
// 导入的依赖项也是 esm bundler 构建,并将依次导入其依赖项 (例如:@vue/runtime-core imports @vue/reactivity)。
// 这意味着可以单独安装/导入这些依赖,而不会导致这些依赖项的不同实例,但必须确保它们都为同一版本。
情况如下:
// vue.runtime.esm-bundler.js (默认) 仅运行时,并要求所有模板都要预先编译。这是构建工具的默认入口 (通过 package.json 中的 module 字段),因为在使用构建工具时,模板通常是预先编译的 (例如:在 *.vue 文件中)。
// vue.esm-bundler.js 包含运行时编译器。如果使用了一个构建工具,但仍然想要运行时的模板编译 (例如,DOM 内模板或通过内联 JavaScript 字符串的模板),请使用这个文件。需要配置构建工具,将 vue 设置为这个文件。
对于服务端渲染:
vue.cjs(.prod).js
③ 使用 npm 进行安装:
在用 Vue 构建大型应用时推荐使用 npm 安装,NPM 能很好地和诸如 Webpack 或 Rollup 模块打包器配合使用。Vue 还提供了编写单文件组件的配套工具。
npm install vue@next
④ 使用官方的 CLI 来构建一个项目,它为现代前端工作流程提供了功能齐备的构建设置:
Vue 提供了一个官方的 CLI,为单页面应用 (SPA) 快速搭建繁杂的脚手架。它为现代前端工作流提供了功能齐备的构建设置。只需要几分钟的时间就可以运行起来并带有热重载、保存时 lint 校验,以及生产环境可用的构建版本。
CLI 工具假定用户对 Node.js 和相关构建工具有一定程度的了解。如果你是新手,建议在熟悉 Vue 本身之后再使用 CLI。
对于 Vue 3,应该使用 npm 上可用的 Vue CLI v4.5以上版本作为 @vue/cli。要升级,应该需要全局重新安装最新版本的 @vue/cli:
npm install -g @vue/cli
通过脚手架 vue-cli创建项目,从 v4.5.0 开始,vue-cli 现在提供了内置选项,可在创建新项目时选择 Vue 3。可以升级 vue-cli 并运行 vue create 来创建 Vue 3 项目:
vue create my-vue3
在 Vue 项目中进行升级运行:
vue upgrade --next
Vite为下一代前端工具,具有即时服务器启动、快如闪电的HMR(Hot Module Replacement,  热模块更换)、丰富的功能、优化构建、通用插件接口、完全类型化的 API等特点。Vite(法语中“快速”的意思,读作 /vit/)是一种新型的前端构建工具,可显着改善前端开发体验。 它由两个主要部分组成:一个是通过原生 ES 模块为您的源文件提供服务的开发服务器,具有丰富的内置功能和惊人的热模块替换 (HMR)。另一个是将您的代码与 Rollup 捆绑在一起的构建命令,预配置为输出高度优化的静态资产以进行生产。
此外,Vite 通过Plugin API 和 JavaScript API 的完整类型支持,具有高度可扩展性。
npm init @vitejs/app my-vue3
① 创建Vue实例并使用:
通过Vue.createApp()创建Vue实例,并通过实例的 .mount()方法指定在某个标记元素组件上使用Vue,没有被mount()指定的组件是不会生效的。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>创建Vue实例并使用</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>  
    <div id="app">
    </div>
    <script>
        Vue.createApp({
            data(){
                 return{
                      content: '我是张三!'
                 }
            },
            template: '<div>{{ content }}</div>'
        }).mount('#app');
    </script>
</body>
</html>
以上所涉及的知识点:template的含义是在mount()指定的组件中,展示 template的内容;变量的使用,用双花括号{{}}表示,如<div>{{content}}</div>的用法;data(){ return{ 属性变量:属性值 } }函数的使用,可以配合template完成数据与视图UI的双向绑定。data()完成数据配置,template指定视图UI,两者配合完成双向绑定;mount()实例函数指定渲染的目标HTML元素标记组件,各司其职!
② mounted()方法应用:
mounted()方法,它就是一个 Vue生命周期钩子的函数,当页面加载完成的时候就会调用。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>mounted()钩子函数使用</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>  
    <div id="app">
    </div>
    <script>
        Vue.createApp({
            data(){
                 return{
                      num: 15
                 }
            },
            mounted(){
                setInterval(() => {
                    this.num += 1;
                    console.log('this.num = ' + this.num)
                }, 1000);            
            },
            template: '<div>{{ num }}</div>'
        }).mount('#app');
    </script>
</body>
</html>
当在浏览器中运行时,视图页面显示数字每隔一秒加一,而在控制台的日志中每隔一秒显示 this.num=加一后的数字。
③ Vue事件绑定:
通过v-on:click表示要绑定点击事件,简写为 @click:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件绑定</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>  
    <div id="app">
    </div>
    <script>
        Vue.createApp({
            data(){
                 return {
                      show : true,
                      msg:"",
                      btn:""
                 }
            },
            methods:{
                onBtnClick(){
                     if (this.show) {
                         this.close();
                     }else{
                         this.open();
                     }       
                },
                close(){
                         this.show= false ;
                     this.btn = '点击显示';
                },
                open(){
                         this.show= true ;
                     this.btn = '点击隐藏';
                },
                init(text,bv){
                         this.msg = text;
                     this.btn = bv;
                }
            },
            mounted(){
                this.init('前端框架技术','点击隐藏');
            },
            template: 
             `
                 <p v-if="show" >{{msg}}</p>
                 <button @click="onBtnClick">{{btn}}</button>
             `
        }).mount('#app');
    </script>
</body>
</html>
涉及的知识点有:v-on是Vue的一个指令,表示要绑定事件;methods对象中可以用来编写Vue架构中使用到的自定义方法;template的冒号之后,可以用反引号“ ` ”来囊括表述更多的标记元素组件;mounted()为Vue生命周期的钩子函数,当页面加载完成时调用;data()是返回组件实例的 data 对象的函数,在实例化组件的时候只是调用了这个函数生成的数据副本。
④ 属性绑定:
class 与 style 是 HTML 元素的属性,可以用 v-bind 来设置属性,如v-bind:class, 简写为 :class:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>绑定属性</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
        .static {
          width: 100px;
          height:auto;
          color:#ffffff
        }
        .active {
          background: blue;
        }
        .error{
          background: red;
        }
    </style>
</head>
<body>
   <div id="app"></div>
   <script>
     const app = {
        data() {
            return {
                isActive: true,
                hasError: false
            }
        },
        template: 
           `
            <div class="static" :class="{ 'active': isActive, 'error': hasError }"> Hello World</div>
           `
      }
      Vue.createApp(app).mount('#app')
    </script>
</body>
</html>
⑤ 计算属性:
尽量避免在同一个元素上面同时使用 v-if 和 v-for,建议使用计算属性实现方式:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>计算属性</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
     <div id="app">
    </div>
    <script>
        const todoList = [
               {
                   id: 0,
                   task: "吃饭",
                   done: true,
                },
                {
                     id: 1,
                     task: "睡觉",
                     done: false,
                 },
                 {
                      id: 2,
                      task: "洗澡",
                      done: true,
                 },
        ];
        Vue.createApp({
                data(){
                 return {
                      show : true,
                      msg:"My List",
                      list: todoList
                 }
            },
            computed:{
                finished() {
                    return todoList.filter(t => t.done);
                },
               todos() {
                    return todoList.filter(t => !t.done);
               }
            },
            template: 
             `
                     <ul>
                           <li v-for="item in todos"  :key="item.id" style="color:blue">
                                  <span>{{item.task}}</span>
                           </li>
                      </ul>
                      <ul v-if="show">
                            <li v-for="item in finished" :key="item.id" style="color:green">
                                <span>{{item.task}}</span>
                            </li>
                       </ul>
                     <p>
                         是否显示已完成部分?
                         <input type="checkbox" v-model="show" />
                              {{show? "是" : "否"}}
                     </p>
             `
        }).mount('#app');
    </script>
</body>
</html>
涉及的知识点有:
v-if是Vue的条件判断指令,指令的表达式返回 true 时才会显示。相应的条件指令还有v-else-if、v-else、v-show;
v-for是Vue的循环语句指令,指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名。
v-model是Vue的表单应用指令,用于在表单<input>、<textarea> 及 <select> 等元素上创建双向数据绑定。该指令会根据控件类型自动选取正确的方法来更新元素。并且会忽略所有表单元素的 value、checked、selected 属性的初始值,使用的是 data 选项中声明的初始值。
computed是Vue的计算属性关键词,用于处理一些复杂逻辑。computed 是基于它的依赖数据,只有相关依赖发生改变时才会重新计算取值。
通过 Vue.createApp() 创建的应用,可以使用 component 方法创建自定义组件:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>组件</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app">
         <my-component></my-component>
    </div>
    <script>
        const vm = Vue.createApp({});
        vm.component('my-component', {
            data() {
                  return {
                      name: '张三'
                  }
            },
            template: `<div>hello {{name}}</div>`,
       });
       vm.mount('#app');
    </script>
</body>
</html>
Vue3支持碎片(Fragments),组件可以拥有多个根节点,此特性可以减少组件之间的div包裹元素。Vue实例是通过createApp 函数创建的,传递给 createApp 的参数选项用于配置根组件,该组件被当作挂载实例时渲染的起点。一个Vue实例需要被挂载到一个类似<div id="app"></div>的DOM 标记元素中。
const RootComponent = {}           # {}内可以添加选项属性及函数 
const vm = Vue.createApp(RootComponent)
vm.mount('#app')
全局组件:
通过Vue实例的component函数注册的组件称为全局组件。这样的组件可以在根实例模板中使用,也包括实例组件树中的所有子组件的模板中。
<div id="app">
    <my-component></my-component>
</div>
局部组件:
通过定义多个普通的 JavaScript 对象,然后在 Vue.createApp({})的参数对象的components 选项中定义想要使用的组件,称为局部组件。这样的组件只能用在该实例中。
const component1 = {
  ... 
}
const component2 = {
  ... 
}
const component3 = {
  ... 
}
const vm = Vue.createApp({
    components: {
       'component_1': component1,
       'component_2': component2 ,
       'component_3': component3 ,
    }
})
props:
在定义组件时,有一个props选项属性,用来接受父组件传递的数值,子组件需要自定义prop显式属性。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>组件传值</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app">
        <name-info
            v-for="item in names"
                 :id="item.id"
                 :name="item.name"
         ></name-info>
     </div>
     <script>
        const vm = Vue.createApp({
            data() {
                return {
                    names: [
                        { id: 1, name: '张三' },
                        { id: 2, name: '李四' },
                        { id: 3, name: '王麻子' }
                    ]
                }
            }
        });
        vm.component('name-info', {
            props: ['id','name'],
            template: `<h5>{{ id }} - {{ name }}</h5>`
        });
        vm.mount('#app');
     </script>
</body>
</html>
Vue3与Vue2的重要的区别在于:Vue2使用选项类型API(Options API), 而Vue3使用合成类型API(Composition API)。选项型API在代码中使用了不同的属性data、computed、methods等。合成型API使用方法函数进行分离,这样使得代码会更加紧簇。
在Vue3.0内,需要使用一个setup()方法,此方法在组件初始化构造的时候触发。
import { reactive } from 'vue'
export default {
    props: {
        title: String
    },
    setup () {
        const state = reactive({
            username: '',
            password: ''
        })
        return { state }
     }
}
           
       
   博文最后更新时间: