Vue 2 与 Vue 3 的区别

一 安装及版本切换
查看当前版本,如果是2开头说明当前使用的是vue-cli2,3开头的话就是vue-cli4

vue --version
如果无法识别vue命令说明没有安装vue-cli,使用以下说明进行安装
安装3.0版本:

npm install -g vue-cli
安装3.0版本:

npm install -g @vue/cli
版本切换,即卸载当前版本,安装另外的版本
从2.0升级到3.0:

npm uninstall -g vue-cli
npm install -g @vue/cli
从3.0降到2.0:

npm uninstall -g @vue/cli
npm install -g vue-cli
二 项目初始化
2.0初始化,vue init <模板名称(webpack比较常用)> [项目名称]

vue init webpack cli2-test
2.0项目初始化参数介绍

//项目名称
 Project name ...
 //作者的信息,会默认从git中读取信息
 Project description ...
 Author ...
 //vue build的选项 1.runtime-compiler   2.runtime-only (一般选第一个就好)
 vue build ...
 //是否安装vue-router,一般选用YES,省去手动创建路由
 Install vue-router? ..
 //是否使用ESLint检测代码规范,规范可根据选项选择不同的规范库或者自己添加规范
 use ESLint to link your code
 //是否写单元测试 (一般不使用)
 Set up unit tests
 //是否使用Nightwatch来进行e2e测试 (2代表to  e to e 点对点)
 Setup e2e test with Nightwatch?
 //使用npm或者yarn包管理工具
 use npm
 use yarn

3.0初始化,vue create [项目名称]

vue create cli3-test
4.0项目初始化参数介绍

//选择一个配置方式
 please pick a perset  (一般选最后一个Manually select features(手动选择特性) )
 //选择对于你的工程所需要的特性 (用空格选择)
 check the features needed for your project
( ) Babel //转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。 
( ) TypeScript// TypeScript是一个JavaScript(后缀.js)的超集(后缀.ts)包含并扩展了 JavaScript 的语法,需要被编译输出为 JavaScript在浏览器运行,目前较少人再用
( ) Progressive Web App (PWA) Support// 渐进式Web应用程序
( ) Router // vue-router(vue路由)
( ) Vuex // vuex(vue的状态管理模式)
( ) CSS Pre-processors // CSS 预处理器(如:less、sass)
( ) Linter / Formatter // 代码风格检查和格式化(如:ESlint)
( ) Unit Testing // 单元测试(unit tests)
( ) E2E Testing // e2e(end to end) 测试
 //对应的配置文件单独生成还是放在package.json里
 where do you prefer placing config for babel
 //要不要把刚才自己选择的配置保存下来
 save this as a preset for future projects?

三 目录结构对比
2.0目录结构

3.0目录结构

对比一下两种方式初始化出来的项目结构,下面说一些对我们开发影响比较大的主要的变化

3.0版本中项目环境变量配置文件没有了(dev.env.js / prod.env.js)
我们可以通过在项目根目录下手动创建不同环境的配置文件,具体的环境变量名称由package.json中运行参数决定,下面举个例子添加development、production和uat版本的环境变量:


//  .env.delelopment
NODE_ENV=development
VUE_APP_MODE=development
BASE_URL=/develop
 
// .env.production
NODE_ENV=production
VUE_APP_MODE=production
BASE_URL=/api
 
// .env.uat
NODE_ENV=production
VUE_APP_MODE=uat
BASE_URL=/uat
// package.json
----
"scripts": {
   "serve": "vue-cli-service serve",
   "build:uat": "vue-cli-service build --mode uat", // 通过 --mode来运行不同的环境,自动识别到.env.uat配置文件
   "build:production": "vue-cli-service build --mode production",
   "lint": "vue-cli-service lint"
 },
 ----
3.0版本中不同环境的webpack配置文件也没有了(webpack.base.conf.js / webpack.dev.conf.js / webpack.prod.conf.js)
同样,我们也可以再根目录中创建vue.config.js文件来进行webpack和vue的一些配置


const path = require('path')
 
module.exports = {
 publicPath: './', // 基本路径,打包时加上.
 outputDir: process.env.outputDir, // 输出文件目录
 lintOnSave: false, // eslint-loader 是否在保存的时候检查
 // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
 // webpack配置
 chainWebpack: (config) => {
   config.resolve.symlinks(true)
 },
 configureWebpack: (config) => {
   if (process.env.VUE_APP_MODE === 'production') {
     // 为生产环境修改配置...
     config.mode = 'production'
   } else {
       // 为开发环境修改配置...
       config.mode = 'development'
   }
   Object.assign(config, {
     // 开发生产共同配置
     resolve: {
       alias: {
         '@': path.resolve(__dirname, './src'),
         '@c': path.resolve(__dirname, './src/components'),
         '@p': path.resolve(__dirname, './src/views')
       } // 别名配置
     }
   })
 },
 productionSourceMap: false, // 生产环境是否生成 sourceMap 文件
 // css相关配置
 css: {
   // extract: true, // 是否使用css分离插件 ExtractTextPlugin
   sourceMap: false, // 开启 CSS source maps?
   loaderOptions: {
     css: {}, // 这里的选项会传递给 css-loader
     less: {
       modifyVars: {
         // less vars,customize ant design theme
 
         // 'primary-color': '#F5222D',
         // 'link-color': '#F5222D',
         // 'border-radius-base': '4px'
       },
       // DO NOT REMOVE THIS LINE
       javascriptEnabled: true
     },
     postcss: {
       plugins: [
         // 把px单位换算成rem单位
         require('postcss-pxtorem')({
           rootValue: 75, // 换算的基数(设计图750的根字体为32)
           selectorBlackList: ['.van-'], // 要忽略的选择器并保留为px。
           propList: ['*'], // 可以从px更改为rem的属性。
           minPixelValue: 2 // 设置要替换的最小像素值。
         }),
         require('autoprefixer')
       ]
       // plugins: [
       //   require('autoprefixer')
       // ]
     } // 这里的选项会传递给 postcss-loader
   }, // css预设器配置项 详见https://cli.vuejs.org/zh/config/#css-loaderoptions
   // modules: false, // 启用 CSS modules for all css / pre-processor files.
   requireModuleExtension: true
 },
 parallel: require('os').cpus().length > 1, // 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
 pwa: {}, // PWA 插件相关配置 see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
 // webpack-dev-server 相关配置
 devServer: {
   open: false, // 自动打开浏览器
   host: '0.0.0.0', // 允许外部ip访问
   port: 8000, // 端口
   https: false, // 启用https
   overlay: {
     warnings: true,
     errors: true
   }, // 错误、警告在页面弹出
   // proxy: 'http://localhost:4000' // 配置跨域处理,只有一个代理
   proxy: {
       '/api': {
           target: '<url>',
           ws: true,
           changeOrigin: true
       },
       '/foo': {
           target: '<other_url>'
       }
   },  // 配置多个代理
 },
 // 第三方插件配置
 pluginOptions: {}
}
四 main.js 文件
import { createApp } from 'vue'
import App from './App.vue'
 
createApp(App).mount('#app')
五 路由router文件
// 可以根据路由模式的不同,后面俩可以只引用一个
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
import Home from '@/views/Home.vue'
 
// 构建我们的页面路由配置,可以看到,这里和原来的写法并无二致。
const routes = [
  {
    path: '/',
    component: Home
  }, {
    path: '/about',
    component: () => import('@/views/About.vue'),
  }
]
 
const router = createRouter({
  // 使用 hash 模式构建路由( url中带 # 号的那种)
  history: createWebHashHistory(),
  // 使用 history 模式构建路由 ( url 中没有 # 号,但生产环境需要特殊配置)
  // history: createWebHistory(),
  routes
})
export default router
得益于 vue3.0 的特性,我们现在不比把组件内容全部包裹在某一个 div 下面了,一个 template 里面可以有多个根节点元素,是没有关系的。

About.vue

<template>
  这里是关于我们的页面
  <router-link to="/">点这里去首页</router-link>
</template>
App.vue

<template>
  <router-view />
</template>
在main.js挂载

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
 
// 将创建的 App 搞个别名
const app = createApp(App)
 
// 使用路由配置
app.use(router)
 
// 挂载运行
app.mount('#app')
六 setUp()函数
①Home.vue

<template>
  <router-link to="/about">点这里去关于我们页面</router-link>
  <div class="home">
    这里是一个计数器 >>> <span class="red">{{count}}</span> <br>
    <button @click="countAdd">{{btnText}}</button>
  </div>
</template>
 
<script>
// ref 是 vue 3.0 的一个重大变化,其作用为创建响应式的值
import { ref } from 'vue'
// 导出依然是个对象,不过对象中只有一个 setup 函数
export default {
  setup () {
    // 定义一个不需要改变的数据
    const btnText = '点这个按钮上面的数字会变'
    // 定义一个 count 的响应式数据,并赋值为 0
    const count = ref(0)
    // 定义一个函数,修改 count 的值。
    const countAdd = () => {
      count.value++
    }
    // 导出一些内容给上面的模板区域使用
    return {
      btnText,
      count,
      countAdd
    }
  }
}
</script>
<style lang="scss">
.home {
  line-height: 2;
  .red {
    color: red;
  }
}
</style>
首先,我们的组件不用写一堆东西了,只需要一个 setup 函数即可。

这样做得好处就是,我们可以把很多零碎的东西拆成公共组件,然后交给其他组件去调用。我写 vue 有一个痛苦的点就是很多的东西我想抽离成组件,但是一拆,就得有 data (), methods 等等一堆。因此,有时候就偷懒,懒得拆了。

现在好了,可以一个函数就是一个组件,多方便啊!

其次,在 setup 函数中 return 出去的东西,可以在模板区域直接使用,也不必理会 this 这个神奇的东西。

然后就是 ref 这个函数,我们可以从 vue 中引入它,它传入一个值作为参数,返回一个基于该值的 响应式 Ref 对象,该对象中的值一旦被改变和访问,都会被跟踪到,通过修改 count.value 的值,可以触发模板的重新渲染,显示最新的值。
 

②about.vue关于reactive

<template>
  <router-link to="/">点这里去首页</router-link>
  <hr>
  <dl>
    <dt>{{state.name}}</dt>
    <dd>性别:{{state.sex}}</dd>
    <dd>地址:{{state.address}}</dd>
  </dl>
  <button @click="addressChange">更新地址</button>
</template>
<script>
// reactive 是 vue 3.0 的一个重大变化,其作用为创建响应式的对象或数组
import { reactive } from 'vue'
// 导出依然是个对象,不过对象中只有一个 setup 函数
export default {
  setup () {
    // 定义一个 state 的响应式对象数据,并赋值
    const state = reactive({
      name: 'FungLeo',
      sex: 'boy',
      address: '上海'
    })
    console.log(state)
    // 定义一个函数,修改 state 的值。
    const addressChange = () => {
      state.address += '浦东'
    }
    // 导出一些内容给上面的模板区域使用
    return {
      state,
      addressChange
    }
  }
}
</script>
reactive 和 ref 的区别就是,reactive 是处理对象或者数组的。

③生命周期函数:

2.0 周期名称    3.0 周期名称    说明
beforeCreate    setup    组件创建之前
created    setup    组件创建完成
beforeMount    onBeforeMount    组件挂载之前
mounted    onMounted    组件挂载完成
beforeUpdate    onBeforeUpdate    数据更新,虚拟 DOM 打补丁之前
updated    onUpdated    数据更新,虚拟 DOM 渲染完成
beforeDestroy    onBeforeUnmount    组件销毁之前
destroyed    onUnmounted    组件销毁后
life.vue

<template>
  <router-link to="/">点这里去首页</router-link>
  <hr>
  <div class="home">
    这里是一个计数器 >>> <span class="red">{{count}}</span> <br>
    <button @click="countAdd">点击加数字</button>
  </div>
</template>
<script>
// 你需要使用到什么生命周期,就引出来什么生命周期
import {
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  ref
} from 'vue'
 
export default {
  // setup 函数,就相当于 vue 2.0 中的 created
  setup () {
    const count = ref(0)
    // 其他的生命周期都写在这里
    onBeforeMount (() => {
      count.value++
      console.log('onBeforeMount', count.value)
    })
    onMounted (() => {
      count.value++
      console.log('onMounted', count.value)
    })
    // 注意,onBeforeUpdate 和 onUpdated 里面不要修改值,会死循环的哦!
    onBeforeUpdate (() => {
      console.log('onBeforeUpdate', count.value)
    })
    onUpdated (() => {
      console.log('onUpdated', count.value)
    })
    onBeforeUnmount (() => {
      count.value++
      console.log('onBeforeUnmount', count.value)
    })
    onUnmounted (() => {
      count.value++
      console.log('onUnmounted', count.value)
    })
    // 定义一个函数,修改 count 的值。
    const countAdd = () => {
      count.value++
    }
    return {
      count,
      countAdd
    }
  }
}
</script>
首先,在 vue 3.0 中,生命周期是从 vue 中导出的,我们需要用到哪些,就导出哪些。

可能不少看官会认为多次一举,但实则不然。vue 提供这么多的生命周期,有几个是我们常用的?在大多数的组件中,我们用不到生命周期。即便是页面级别的应用,可能用到最多的是 onMounted 即可。

当然,那些绑定时间的操作会用到解绑,因此会用到 onUnmounted。其它的生命周期,正常情况下是基本用不到的。所以,通过引入使用的这种设定,可以减少我们的最终编译的项目的体积。而且,这样的引入使用,更加的逻辑清晰。

其次,除 setup 之外,其他的生命周期函数,都是在 setup 里面直接书写函数即可。
 

④计算属性

computed.vue

<template>
  <router-link to="/">点这里去首页</router-link>
  <hr>
  <div class="home">
    这里是一个计数器 >>> <span class="red">{{count}}</span> <br>
    右边的数字是上面的数字的十倍 >>> <span class="red">{{bigCount}}</span> <br>
    右边的数字是上面的数字的一百倍 >>> <span class="red">{{computeCount['100x']}}</span> <br>
    右边的数字是上面的数字的一千倍 >>> <span class="red">{{computeCount['1000x']}}</span> <br>
    <button @click="countAdd">点这个按钮上面的数字会变</button>
  </div>
</template>
 
<script>
// 需要使用计算属性,也需要从 vue 中导出引入
import { ref, computed } from 'vue'
// 导出依然是个对象,不过对象中只有一个 setup 函数
export default {
  setup () {
    // 定义一个 count 的响应式数据,并赋值为 0
    const count = ref(0)
    // 定义一个函数,修改 count 的值。
    const countAdd = () => {
      count.value++
    }
    // 计算属性,使用计算函数并命名,然后在 return 中导出即可
    const bigCount = computed(() => {
      return count.value * 10
    })
    // 计算多个属性,可以通过返回一个对象的方式来实现
    const computeCount = computed(() => {
      return {
        '100x': count.value * 100,
        '1000x': count.value * 1000,
      }
    })
    // 导出一些内容给上面的模板区域使用
    return {
      count,
      countAdd,
      bigCount,
      computeCount
    }
  }
}
</script>
计算属性和生命周期一样,都是从 vue 中导出引入的。我们把计算属性当成一个函数来使用,直接 return 计算结果即可。
————————————————
版权声明:本文为CSDN博主「水蜜桃那么甜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Lemontree_fu/article/details/106282633

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值