精华内容
下载资源
问答
  • 【码牛云课堂】Vue3.0正式版他来了!他来了!Vue3.0 One Piece(海贼王本王) Vue3.0的发布,其背后的辛酸曲折只有真爱粉才知道,前前后后2000多次的提交,600余次的项目评审,各种各样的beta测试版本。终于,我们的...

    【码牛云课堂】Vue3.0正式版他来了!他来了!Vue3.0 One Piece(海贼王本王)

    Vue3.0的发布,其背后的辛酸曲折只有真爱粉才知道,前前后后2000多次的提交,600余次的项目评审,各种各样的beta测试版本。终于,我们的尤神(Vue.js作者尤雨溪)和社区大神坚持不懈,带来了船新版本——Vue.js 3.0 OnePiece(路飞冲冲冲!)。

    Vue3.0(图片来自网络,如有侵权,请联系作者!)

    来看看更新的重磅内容吧?

    Vue组件 Teleport

    Vue Treeshaking的全新API

    Vue 3.0官方文档

    “渐进式框架”用起来真香!

    Vue的诞生源自一个思想:任何人都可以快速入门,成为一个全行业都能学习并使用的框架,通过一些简单的操作,实现复杂的功能。随着使用人数的激增,Vue在逐渐适应不同业务需求时,发展成为“渐进式”的框架,那么什么是“渐进式框架”呢?其实可以在不断更新中按步骤学习和使用的,不用等框架成为完全体的就是渐进式框架。

    在用户激增的情况下,Vue在各种场景中使用越来越频繁,所以Vue3.0正式版进一步提高了运用组件的功能完善页面应用程序的灵活性;

    新式API解决各种疑难杂症

    ​ Vue2.x的版本中API主要基于对象,这在Vue3.0的版本中完整的延续了下来,此外,Vue3.0还引入了一些全新的API—Composition API。

    ​ Composition API目的是为了解决在大型项目中的使用难处,它建立在反应性API之上,与Vue 2.x版本相比较,可以实现React挂钩的逻辑组成和重用,更灵活的代码组织模式和更靠谱的类型推断。

    ​ 通过Vuejs-composition-api插件,给Vue 2.x版本也提供了使用它的权力,而且已经拥有适用于Vue 2.x和Vue 3.0版本的composition API 的实用库,如vue-composable等。

    顺便看看尤神在19号凌晨发布的视频介绍吧(整个过程我小码牛看的心潮澎湃)

    直播中尤神讲述了整个Vue3.0的历程,介绍了新的特性,相信一直接触Vue的你一定十分期待吧?

    (图片来自网络,如有侵权,请联系作者!)
    尤神亲自介绍1
    (图片来自网络,如有侵权,请联系作者!)
    尤神亲自介绍2

    此外,所有的官方工具都支持了Vue3.0版本,包括但不限于:vue-cli、vue-router、vuex、vue-devtools、Vue-Test-utils、IDE的Vue插件,但是大多数非官方工具仍然处于beta状态,所以敬请期待吧!

    具体的新功能分析,由于本人能力有限,尚处于钻研阶段,欢迎大家热情讨论,给予指导!

    最后感谢大家抽出时间阅读,我们下次更新再见咯~

    展开全文
  • vue3.0正式版-语法

    2021-02-22 21:50:58
    vue3.0正式版-语法 一.vue3.0版本中elementui-plus的安装和使用 引入地址 1.安装: npm i element-plus 扩展: vue3.0和antdesign一起使用,ant-design-vue需要v2的版本,否则当行这样的样式就会出现问题。 import...

    vue3.0正式版-语法

    一.vue3.0版本中elementui-plus的安装和使用

    引入地址

    1.安装:

    npm i element-plus 
    

    扩展:
    vue3.0和antdesign一起使用,ant-design-vue需要v2的版本,否则当行这样的样式就会出现问题。

    import Antd from "ant-design-vue";
    import "ant-design-vue/dist/antd.css";
    const app = createApp(App);
    
    app
      .use(Antd)
      .mount("#app");
    

    2.main.js里面

    import App from './App.vue'
    import { createApp } from 'vue'
    import ElementPlus from 'element-plus'
    import 'element-plus/lib/theme-chalk/index.css'
    
    const app = createApp(App)
    app.use(ElementPlus).mount('#app')
    

    3.页面的使用

    在新版的vue3.x版本中还保留了原有的生命周期函数

    created(){
      this.$message("message")
    },
    

    4.但在vue3.0 setup中使用

    import { setup } from 'vue-class-component'
    import { getCurrentInstance } from 'vue'
    export default {
      name: 'App',
      components: {
    
      },
      setup(e){
        const {ctx} = getCurrentInstance()
        ctx.$message("mesage")
      }
    }
    

    更新:ctx 打包之后无法调用$message,可以使用proxy

    import { getCurrentInstance } from 'vue'
    export default {
      name: 'App',
      components: {
    
      },
      setup(){
        const {proxy} = getCurrentInstance()
        proxy.$message("mesage")
      }
    }
    

    二.中英文切换

    网址:https://vue-i18n-next.intlify.dev/

    下面网上有这个网址,但不支持vue3.0
    http://kazupon.github.io/vue-i18n/zh/introduction.html

    三.vue.config.js

    const path = require("path");
    // vue.config.js
    module.exports = {
        publicPath: process.env.NODE_ENV === 'production' ? '' : './',
        // 构建项目生成的目录
        outputDir: process.env.NODE_ENV === 'production' ? 'dist' : 'devDist',
        // 关闭语法的自动检测
        lintOnSave: false,
        chainWebpack: config => {
            config.module.rules.delete('svg'); //重点:删除默认配置中处理svg,
            config.module
                .rule('svg-sprite-loader')
                .test(/\.svg$/)
                .include.add(path.resolve('src/assets/svg')) //处理svg目录
                .end()
                .use('svg-sprite-loader')
                .loader('svg-sprite-loader')
                .options({
                    symbolId: 'icon-[name]',
                });
        },
        css: {
            loaderOptions: {
                scss: {
                    prependData: `@import "./src/styles/main.scss";`
                }
            }
        },
        devServer: {
            open: false,    // 运行项目后是否自动打开
            host: "0.0.0.0",   // 可以让外部访问
            port: 8000,
            proxy: {
                [process.env.VUE_APP_FLAG]: {
                    target: process.env.VUE_APP_APIURL,
                    ws: false,            // webstock
                    changeOrigin: true,    // 是否开启跨域
                    pathRewrite: {
                        [`^${process.env.VUE_APP_FLAG}`]: ''        // 查找开头为/api的字符替换成“空字符串”   /api/getCode
                    } 
                }
            }
        }
    }
    

    四.侧边栏引入svg

    1,安装svg-sprite-loader

    npm install svg-sprite-loader -D

    2.vue.config.js里面添加chainWebpack的配置

    vue.config.js具体哪些配置可以直接百度搜索vue(vue -> 开发-> webpck相关)

     chainWebpack: config => {
            config.module.rules.delete('svg'); //重点:删除默认配置中处理svg,
            config.module
                .rule('svg-sprite-loader')
                .test(/\.svg$/)
                .include.add(path.resolve('src/assets/svg')) //处理svg目录
                .end()
                .use('svg-sprite-loader')
                .loader('svg-sprite-loader')
                .options({
                    symbolId: 'icon-[name]',
                });
        },
    

    3)单独的svg组件,引入以后,传入svg文件按的名字即可显示

    svg的组件的路径

    <template>
        <svg class="svg-class" :class="className">
            <use :href="'#icon-' + iconName"></use>
        </svg>
    </template>
    <script>
    export default {
        name: "SvgIcon",
        props: {
            iconName: {
                type: String,
                default: ""
            },
            className: {
                type: String,
                default: ""
            }
        }
    }
    </script>
    

    4)svg从局部组件改为全局组件

    svg图片的路径

    main.js:

    import { createApp } from "vue";
    import App from "./App.vue";
    // svg全局组件
    import SvgIcon from "@/components/Svgicon";
    // svg文件解析
    import "./js/svg";
    
    const app = createApp(App);
    app
      .component("svg-icon", SvgIcon)
      .mount("#app");
    

    5)组件内直接使用:

    <svg-icon iconName="collapsed" class="collapsed-svg" />
    

    五.vue3.0的router的使用

    官方文档:百度搜索vue-router-next,如果每日有官方文档,找github也可以,官网在右边about里面的next.router.vue.js.org/。
    1)获取路由

    <template v-for="item in rotuers"></template>
    
    import { useRoute, useRouter } from "vue-router";
    
    setup(){
            const { options } = useRouter();
            // 路由
            const rotuers = options.routes;
            return {
                data,
                rotuers,
                selectMenu,
                openMenu,
                hasOnlyChildren
            }
        }
    

    六.子级传值给父级

    import {getCurrentInstance } from "vue";
    setup(props){
        const { ctx } = getCurrentInstance();
        ctx.$axios.post("getSms")
    

    更新:ctx 打包之后无法调用$message,可以使用proxy

    import { getCurrentInstance } from 'vue'
    export default {
      name: 'App',
      components: {
    
      },
      setup(){
        const {proxy} = getCurrentInstance()
        proxy.$message("mesage")
      }
    }
    

    七.变量挂载在全局

    (vue3.0官网 -> api参考 -> 应用配置 -> globalProperties)

    import Axios from "axios";
    const app = createApp(App);
    app.config.globalProperties.$axios = Axios;
    
    app
      .mount("#app");
    

    在页面通过getCurrentInstance()获取

    import {getCurrentInstance } from "vue";
    setup(props){
        const { ctx } = getCurrentInstance();
        ctx.$axios.post("getSms")
        }
    

    但一般建议使用proxy作为上下文的引用。

    八.跨域

    官网的配置参考-> devServe.proxy
    baseUrl设为"/api"->axios就会自动八baseUrl和后面的其他请求路径凭借起来->请求的路径就是:本地的ip+baseUrl+请求接口。
    设置跨域以后,’/api’的target指向另外一个地址,你们请求的地址的ip就不是本地的了,就是这个新地址+/api+请求的接口。然后通过正则匹配/api,把/api转为空字符串.
    但这一段代码只有开发环境才会运行,线上环境是不会运行的。

    九.环境变量

    百度搜索:vue cli

    一个vue脚手架有三种模式:
    development:开发模式
    test:测试模式
    production:生产模式

    1.定义三个环境变量的文件

    开发环境 .env.development 运行npm run dev
    生产环境 .env.production 运行npm run build
    测试环境 .env.test 没有对应的命令,但可以在package.json里面自定义

    "scripts": {
        "serve": "vue-cli-service serve",
        "build": "vue-cli-service build",
        "build-test": "vue-cli-service build --mode test",
        "lint": "vue-cli-service lint"
      },
    

    2.三个环境变量分别定义内容

    .env.development:

    # 本地环境联调接口的标记匹配
    VUE_APP_FLAG = '/devApi'
    
    #跨域地址
    VUE_APP_APIURL = 'http://www.web-jshtml.cn/api/vue3'
    
    #帐户体系
    VUE_APP_ACCOUNT_APIURL = ''
    
    #用户体系
    VUE_APP_USER_APIURL = ''
    

    .env.production:

    VUE_APP_FLAG = ''
    
    #帐户体系
    VUE_APP_ACCOUNT_APIURL = 'http://account.web-jshtml.cn'
    
    #用户体系
    VUE_APP_USER_APIURL = 'http://user.web-jshtml.cn'
    

    .env.test

    VUE_APP_FLAG = ''
    
    #帐户体系
    VUE_APP_ACCOUNT_APIURL = 'http://account-test.web-jshtml.cn'
    
    #用户体系
    VUE_APP_USER_APIURL = 'http://user-test.web-jshtml.cn'
    

    3.在request.js里面封装axios的baseUrl里面只需要是process.env.变量名称

    import axios from "axios";
    import { message } from "ant-design-vue";
    const service = axios.create({
        baseURL: process.env.VUE_APP_FLAG,
        timeout: 5000
    });
    

    4.在vue.config.js里面

    const path = require("path");
    // vue.config.js
    module.exports = {
        publicPath: process.env.NODE_ENV === 'production' ? '' : './',
        // 构建项目生成的目录
        outputDir: process.env.NODE_ENV === 'production' ? 'dist' : 'devDist',
        // 关闭语法的自动检测
        lintOnSave: false,
        devServer: {
            open: false,    // 运行项目后是否自动打开
            host: "0.0.0.0",   // 可以让外部访问
            port: 8000,
            proxy: {
                [process.env.VUE_APP_FLAG]: {
                    target: process.env.VUE_APP_APIURL,
                    ws: false,            // webstock
                    changeOrigin: true,    // 是否开启跨域
                    pathRewrite: {
                        [`^${process.env.VUE_APP_FLAG}`]: ''        // 查找开头为/api的字符替换成“空字符串”   /api/getCode
                    } 
                }
            }
        }
    }
    

    4.接口的调用

    import service from "@/utils/request.js";
    
    
    export function GetCode(data){
        return service.request({
            url: '/error/',
            method: 'post',
            data,
        })
    }
    
    /**
     * 帐户体系 - 登录
     */
    export function AccountLogin(data){
        return service.request({
            url: process.env.VUE_APP_ACCOUNT_APIURL + 'http://account-test.web-jshtml.cn/login/',
            method: 'post',
            data,
        })
    }
    
    /**
     * 用户体系 - 登录
     */
    export function UserList(data){
        return service.request({
            url: process.env.VUE_APP_USER_APIURL + '/list/',
            method: 'post',
            data,
        })
    }
    
    
    
    
    
    展开全文
  • vue3.0正式版2 记录的原因:vue3.0的安装和只用跟之前尝鲜版的语法和脚手架的部分东西不一样,这边就重新记录了一下。 一.安装vue-cli3.0脚手架(在npm黑窗口,而不是git) 1.先安装Nodejs 2.安装完以后如果之前安装...

    vue3.0正式版-搭建脚手架

    记录的原因:vue3.0的安装和只用跟之前尝鲜版的语法和脚手架的部分东西不一样,这边就重新记录了一下。

    一.安装vue-cli3.0脚手架(在npm黑窗口,而不是git)

    1.先安装Nodejs
    2.安装完以后如果之前安装过Vue2.0的版本,需要把2.0相关的卸载掉

    npm uni -g vue-cli或者cnpm uni -g vue-cli
    

    如果没有安装或vue的2.0版本的话,直接在全局的命令窗口,输入

    cnpm i -g @vue/cli
    

    检查版本号

    vue -V
    

    在这里插入图片描述

    3.打开cmd命令
    在确认的文件夹路径的地址上输入cmd,打开路径
    在这里插入图片描述
    第一步:输入搭建脚手架的命令

    vue create 项目名称
    

    第二步:
    选择手动安装:(manually)
    在这里插入图片描述
    选择配置:(Babel,router,vuex,css,linter等)
    在这里插入图片描述
    选择vue的项目版本(3.0)
    在这里插入图片描述
    选择路由模式:hash模式和history模式(没有特殊情况就暂时选N)
    在这里插入图片描述
    选择css预处理器(node_sass)
    在这里插入图片描述
    代码类型的检查规范(EsLint+printtier)
    在这里插入图片描述
    在什么情况下会进行代码检测(save保存的时候)
    在这里插入图片描述
    配置文件会放在哪个位置(config file)
    在这里插入图片描述
    是否保存之前选择的选项,保存后面的项目就不需要一步一步的选择配置了(y)
    在这里插入图片描述
    然后回车输入保存配置的名字。

    展开全文
  • vue3.0正式版-2.x和3.x的对比

    千次阅读 2020-11-29 13:35:50
    vue3.0正式版 一.vue3.0的亮点 性能比vue2.x快1.2~2倍 ①diff方法优化 ②静态提升 ③事件侦听器缓存 ④ssr渲染 支持按需编译,按需导入,体积比vue2.x更小 支持组合API,类似React Hooks 更好的支持ts,因为...

    vue3.0正式版-2.x和3.x的对比

    1)部分命令发生了变化:
    下载安装 npm install -g vue@cli
    删除了vue list
    创建项目 vue create 文件名(2.0: vue init webpack 文件名)
    启动项目 npm run serve(2.0:npm run dev)

    2)默认项目目录结构也发生了变化:
    移除了配置文件目录,config 和,build和static 文件夹
    新增 public 文件夹,并且 index.html 移动到 public 中
    在 src 文件夹中新增了 views 文件夹,用于分类 视图组件 和 公共组件
    3.0的安装项目时自动下载node-model
    而且需要在根目录下创建一个vue.config.js

    3)3.0 新加入了 TypeScript 以及 PWA 的支持

    4)Vue2.0和Vue3.0的响应式原理的不同

    Vue2.0:

    • 基于Object.defineProperty,不具备监听数组的能力,需要重新定义数组的原型来达到响应式。
    • Object.defineProperty 无法检测到对象属性的添加和删除 。
    • 由于Vue会在初始化实例时对属性执行getter/setter转化,所有属性必须在data对象上存在才能让Vue将它转换为响应式。
    • 深度监听需要一次性递归,对性能影响比较大。

    Vue3.0:

    • 基于Proxy和Reflect,可以原生监听数组,可以监听对象属性的添加和删除
    • 不需要一次性遍历data的属性,可以显著提高性能。
    • 因为Proxy是ES6新增的属性,有些浏览器还不支持,只能兼容到IE11 。

    一.vue3.0的亮点

    1.性能比vue2.x快1.2~2倍

    ①diff方法优化
    ②静态提升
    ③事件侦听器缓存
    ④ssr渲染
    

    2.支持按需编译,按需导入,体积比vue2.x更小

    3.支持组合API,类似React Hooks

    4.更好的支持ts,因为他是ts写的

    5.暴露了自定义渲染的API

    6.提供过了更先进的组件

    二.vue3.0是如何变快的

    1. diff方法优化

    • vue2.0中的虚拟dom是进行全量的对比
    • vue3.0新增了静态标记(PatchFlag),在于上次虚拟节点进行对比的时候,只对比带有patch flag的节点。并且可以通过flag的信息得知当前节点要对比的具体内容。
    • 在这里插入图片描述
      验证:是否添加静态标记
      vue3.0转换代码的网址:https://https://vue-next-template-explorer.netlify.app/
      在这里插入图片描述
      静态标记枚举类:
      在这里插入图片描述

    2.静态提升

    • vue2.0无论元素是否参与更新,每次都会重新创建,然后再渲染
    • vue3.0对于不参与更新的元素,会做静态提升,只会被新创建一次,在渲染时直接复用即可

    验证:
    默认情况下,每次都会重新创建createNode节点,这里我们选择hoisStatic。
    会发现这些节点从render里面提取出来了,成为了全局变量。后面每次render的时候就可以复用
    在这里插入图片描述

    3.事件侦听器缓存

    • 默认情况下,onClick会被视为动态绑定,所以每次都会去追踪它的变化。但是因为事件绑定的函数是同一个函数(同一个方法),所以没有追踪变化,直接缓存起来复用即可。
      验证:
      【注意】转换之后的代码,大家可能还看不懂,但是不要紧。因为只需要观察有没有静态标记即可,因为在Vue3的diff算法中,只有有静态标记的才会进行比较,才会进行追踪。
    //事件监听缓存
    <button @click="onClick">按钮</button>
    //开启事件监听缓存之前(把静态提升关闭了也是这样)
    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock("div", null, [
        _createVNode("button", { onClick: _ctx.onClick }, "按钮", 8 /* PROPS */, ["onClick"])
      ]))
    }
    //开启事件监听缓存之后(把options选择为cacheHandlers)
    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock("div", null, [
        _createVNode("button", {
          onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args)))
        }, "按钮")
      ]))
    }
    

    4.ssr渲染

    • 当有大量静态的内容时候,这些内容会被当做纯字符串推进一个buffer里面,即使存在动态绑定,会通过模板插值嵌入进去,这样会比通过虚拟dom来渲染的快很多很多。
    • 当静态内容达到一定量级时候,会用_createStaticVNode方法在客户端去生成一个static node,这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染。

    三.创建vue3.0的三种方式

    1.Vue-CLI

    • git clone https://github.com/vue.js/vue-next-webpack-preview.git ProjectName
    • cd ProjectName
    • npm install
    • npm run dev

    2.Webpack

    • npm install -g @vue/cli
    • vue create ProjectName
    • cd ProjectName
    • vue add vue-next
    • npm run serve

    3.Vite

    1)安装Vite
    npm install -g create-vite-app

    2)利用Vite创建Vue3.0项目
    create-vite-app projectName

    【注意】我在在使用该命令的时候报错,当然不是所有人都遇到这个情况。不报错就不需要解决。
    当时我就查了很多资料,有人说nodejs版本过低,需要升级。开始我升级了还是没有效果。
    解决的办法:配置nodejs的环境变量
    ①在c\Program File\nodejs文件夹下创建node_cache和node_global这两个文件夹
    在这里插入图片描述
    ②创建完两个空文件夹之后,打开cmd命令窗口,输入
    npm config set prefix “C:\Program Files\nodejs\node_global”
    npm config set cache “C:\Program Files\nodejs\node_cache”

    ③接下来设置环境变量,关闭cmd窗口,“我的电脑”-右键-“属性”-“高级系统设置”-“高级”-“环境变量”
    ④ 进入环境变量对话框,在【系统变量】下新建【NODE_PATH】,输入【C:\Program Files\nodejs\node_global\node_modules】,将【用户变量】下的【Path】修改为【C:\Program Files\nodejs\node_global】
    在这里插入图片描述
    最后,关掉黑窗口重启一下,再试一下create-vite-app programName的命令看下是否报错。

    3)安装依赖运行项目
    cd projectName
    npm install
    npm run dev

    四.什么是Vite

    • vite是vue作者开发的一款取代webpack的工具
    • 其实现原理是利用es6的import会发送请求去加载文件的特性,拦截这些请求,做一些预编译,省去webpack冗长的打包时间

    1.安装vite

    npm install -g create-vite-app

    2.利用vite创建vue3.0项目

    create -vite -app projectName

    3.安装依赖运行项目

    cd projectName
    npm install

    五.组合API

    vue2.x存在的问题:
    vue3.x的组合API:
    setup函数是组合API的入口函数

    1.ref()

    1)什么是ref ?
    ref和reactive一样,也是用来实现响应式数据的方法。由于reactive必须传递一个对象,所以导致在企业开发中,如果我们只想让某个变量实现响应式的时候会非常麻烦,所以vue3就给我们提供了ref方法,实现对简单值的监听。

    2)ref的本质
    ref底层的本质其实还是reactive。当我们给ref函数传递一个值之后,ref函数底层会自动将ref转换成eactive,如ref(10)—>reactive({value:18})。
    注意:
    ①如果是通过tref创建的数据,那么在template中使用的时候不用通过.value来获取,因为vue会自动给我们添加.value。
    ②但在js中使用ref函数必须通过value获取。

    3)ref的功能和使用方法
    功能:只能监听简单类型的变化
    使用方法:import 引入{ref},return 暴露出去。获取ref的变量需要.value

    <script>
    import {ref} from 'vue'
    export default {
      name: 'App',
      setup(){
        let count=ref(0);
    
        function changeBtn(){
          count.value++;
        }
        return {count,changeBtn}
      }
    }
    </script>
    

    2.reactive()函数

    1)什么是reactive?
    ①reactive是vue3中提供的实现响应式数据的方法;
    ②在vue2中响应式数据是通过defineProperty来实现的,而在vue3中响应式数据是通过es6的Proxy来实现的。

    2)reactive注意点:
    ①reactive参数必须是对象(obj/json/arr)
    ②如果给reactive传递了其他对象(比如:日期对象),默认情况下修改该对象,界面不会更新;如果想更新,可以通过重新赋值的方式

    3)功能和使用方法
    功能:监听对象和数组的变化
    使用方法:import 引入{reactive},return 暴露出去方法名称。

    <script>
    import {ref} from 'vue'
    import {reactive} from 'vue'
    export default {
      name: 'App',
      setup(){
        let {state,remStu}=useRemoveStudent()
        return {state,remStu}
      }
    }
    //整个相关的方法和变量都写在一起了
      function useRemoveStudent(){
        let state=reactive({
          stus:[
            {id:1,name:'张三',age:10},
            {id:2,name:'李四',age:20},
            {id:3,name:'王五',age:30},
          ]
        });
        function remStu(index){
          state.stus=state.stus.filter((stu,idx)=>idx!==index);
        }
        return {state,remStu}
      }
    
    </script>
    
    

    组合API的思想:
    整个相关的方法和变量都写在一起了

    demo2:删除和新增用户

    <template>
      <div>
        <form action="">
          <input type="text" v-model="state2.stu.id">
          <input type="text" v-model="state2.stu.name">
          <input type="text" v-model="state2.stu.age">
          <input type="submit" @click="addStu">
        </form>
        <ul>
          <li v-for="(stus,index) in state.stus" :key="stus.id"
          @click="remStu(index)">
            {{stus.name}}--{{stus.age}}
          </li>
        </ul>
      </div>
    </template>
    
    <script>
    import {ref} from 'vue'
    import {reactive} from 'vue'
    export default {
      name: 'App',
      setup(){
        let {state,remStu}=useRemoveStudent()
        let {state2,addStu}=useAddStudent(state)
        return {state,remStu,state2,addStu}
      }
    }
    //删除用户
      function useRemoveStudent(){
        let state=reactive({
          stus:[
            {id:1,name:'张三',age:10},
            {id:2,name:'李四',age:20},
            {id:3,name:'王五',age:30},
          ]
        });
        function remStu(index){
          state.stus=state.stus.filter((stu,idx)=>idx!==index);
        }
        return {state,remStu}
      }
    //增加用户
    function useAddStudent(state){
      let state2=reactive({
        stu:{
          id:'',
          name:'',
          age:''
        }
      });
      function addStu(e){
        e.preventDefault();
        const stu=Object.assign({},state2.stu);
        state.stus.push(stu)
        state2.stu.id=''
        state2.stu.name=''
        state2.stu.age=''
      }
      return {state2,addStu}
    }
    
    </script>
    
    

    【注意】
    ①ref和reactive区别:
    如果在template里使用的是ref类型的数据,那么vue会自动帮我们添加.value,
    如果在template里使用的是reactive类型的数据,那么vue不会自动帮我们添加.value。
    ②vue是如何决定是否需要自动添加.value的?
    vue在解析数据之前,会自动判断这个数据是否是ref类型,
    如果是就自动添加.value,如果不是就不自动添加.value。
    ③vue是如何判断当前的数据是否是ref类型的?
    通过当前数据的__v_ref来判断的。如果有这个私有属性,并且取值为true,那么就代表是一个ref类型的数据。
    ④开发人员如何判断当前的数据类型?
    isRef和isReactive来分别判断是否是普通函数和对象。

    3.composition API和Option API的混合使用

    option API就是之前vue2.x的API
    composition AP是现在vue3.x新增的语法
    composition API和Option API的是可以混合使用

    composition API的本质是什么?
    可以翻译成:组合API(或注入API)
    他的本质就是在运行的时候,将composition API中暴露出去的数据,注入到Option API中,比如说暴露了一个普通变量age,这个age就会被注入到data()方法里面;暴露了一个方法submit(),这个方法就会被注入到methods里面。

    4.setup函数的执行时机和注意点

    1)setup函数的执行时机:
    setup函数是在beforeCreate和created之间执行的。
    beforeCreate:表示组件刚刚被创建出来,组件的data和methods还没初始化号;
    created:表示组件刚刚被创建出来,并且组件的data的methods已经初始化好了。

    2)setup注意点:
    ①由于在执行setup函数的时候,还没执行created生命周期方法,所以在setup函数中,是无法使用data和methods的。
    ②由于我们不能在setup函数中使用data和methods,所以vue为了避免我们错误的使用,他直接将setup函数中的this值修改为了Undefined。
    ③setup函数只能是同步,不能是异步的。

    5.递归监听

    1)递归监听
    默认情况下,无论是通过ref还是reactive都是递归监听

    <template>
      <div>
        <p>{{state.a}}</p>
        <p>{{state.gf.b}}</p>
        <p>{{state.gf.f.c}}</p>
        <p>{{state.gf.f.s.d}}</p>
        <button @click='myFn'>按钮</button>
      </div>
    </template>
    
    <script>
    import {ref} from 'vue'
    import {reactive} from 'vue'
    export default {
      name: 'App',
      setup(){
        let state=reactive({
          a:'a',
          gf:{
            b:'b',
            f:{
              c:'c',
              s:{
                d:'d'
              }
            }
          }
        })
        function myFn(){
          state.a='1';
          state.gf.b='2';
          state.gf.f.c='3';
          state.gf.f.s.d='4';
          console.log(state)
          console.log(state.gf)
          console.log(state.gf.f.s)
        }
        return {state,myFn}
      }
    }
    
    
    </script>
    
    

    2)递归监听存在的问题
    如果数据量比较大,非常消耗性能。因为他把每一层都包裹成了proxy对象。
    在这里插入图片描述

    3)非递归监听
    shadowRef / shallowReactive
    非递归监听就是只能监听第一层,不能监听其他层。
    【使用场景】只有需要监听的数据量比较大的时候,我们才使用。
    ①shallowReactive

    <script>
    import {shallowReactive} from 'vue'
    import {shallowRef} from 'vue'
    export default {
      name: 'App',
      setup(){
        let state=shallowReactive({
          a:'a',
          gf:{
            b:'b',
            f:{
              c:'c',
              s:{
                d:'d'
              }
            }
          }
        })
        function myFn(){
          state.a='1';
          state.gf.b='2';
          state.gf.f.c='3';
          state.gf.f.s.d='4'
          console.log(state)
          console.log(state.gf)
          console.log(state.gf.f.s)
        }
        return {state,myFn}
      }
    }
    
    
    </script>
    

    会发现只有第一层被包装成了proxy

    在这里插入图片描述
    ②shallowRef
    如果是shallowRef创建数据,那么vue监听的是.value的变化,并不是第一层的变化。
    本质:ref(10)->reactive({value:10}),因为底层本质上是第一层。

    <script>
    import {shallowReactive} from 'vue'
    import {shallowRef} from 'vue'
    export default {
      name: 'App',
      setup(){
        let state=shallowRef({
          a:'a',
          gf:{
            b:'b',
            f:{
              c:'c',
              s:{
                d:'d'
              }
            }
          }
        })
        function myFn(){
          state.value.a='1';
          state.value.gf.b='2';
          state.value.gf.f.c='3';
          state.value.gf.f.s.d='4'
          console.log(state)
          console.log(state.value)
          console.log(state.value.gf)
          console.log(state.value.gf.f.s)
        }
        return {state,myFn}
      }
    }
    

    在这里插入图片描述
    所以说上面上的字母没有变成数字。要想把他变成数字,需要把直接把state改掉

    <script>
    import {shallowReactive} from 'vue'
    import {shallowRef} from 'vue'
    export default {
      name: 'App',
      setup(){
        let state=shallowRef({
          a:'a',
          gf:{
            b:'b',
            f:{
              c:'c',
              s:{
                d:'d'
              }
            }
          }
        })
        function myFn(){
          state.value={
              a:'4',
              gf:{
                b:'5',
                f:{
                  c:'6',
                  s:{
                    d:'7'
                  }
                }
              }
          }
          state.value.a='1';
          state.value.gf.b='2';
          state.value.gf.f.c='3';
          state.value.gf.f.s.d='4'
          console.log(state)
          console.log(state.value)
          console.log(state.value.gf)
          console.log(state.value.gf.f.s)
        }
        return {state,myFn}
      }
    }
    
    
    </script>
    

    在这里插入图片描述

    ③shallowRef只想修改第四层的数据,如果第四层改了,自动修改Ui界面。加上triggerRef一起使用。
    【注意】vue3只提供了triggerRef方法,没有提供TriggerReactive方法。所以如果是reactive类型的数据,那么是无法主动触发界面更新的。

    <script>
    import {shallowReactive} from 'vue'
    import {shallowRef,triggerRef} from 'vue'
    export default {
      name: 'App',
      setup(){
        let state=shallowRef({
          a:'a',
          gf:{
            b:'b',
            f:{
              c:'c',
              s:{
                d:'d'
              }
            }
          }
        })
        function myFn(){
          state.value.gf.f.s.d='8';
          triggerRef(state)
          console.log(state)
          console.log(state.value)
          console.log(state.value.gf)
          console.log(state.value.gf.f.s)
        }
        return {state,myFn}
      }
    }
    
    
    </script>
    

    在这里插入图片描述

    6.toRaw()原数据被修改,但不会更新ui

    ref/reactive数据类型的特点:
    每次修改都会被追踪,更新ui界面。但这样其实是非常消耗性能的。如果不需要更新ui界面,就可以通过toRaw方法拿到他的原始数据。此时对原始数据进行修改的时候就不会被追踪,不会更新ui界面。

    <template>
      <div>
        {{state}}
        <button @click='myFn'>按钮</button>
      </div>
    </template>
    
    <script>
    import {reactive,toRaw} from 'vue'
    export default {
      name: 'App',
      setup(){
        let obj={name:'小李',age:16}
        let state=reactive(obj)//注意:如果这里是ref的话,下面toRaw(state.value)
        let obj2=toRaw(state)
        function myFn(){
          // state.name="Angle";//会更新ui界面
          obj2.name="Angle";//数据虽然被改变了,不会更新ui界面。这样会减少性能的消耗
          console.log(obj2)
        }
        return {state,myFn}
      }
    }
    
    
    </script>
    

    在这里插入图片描述

    7.markRaw()确认原数据,且永远不会被追踪

    <template>
      <div>
        {{state}}
        <button @click='myFn'>按钮</button>
      </div>
    </template>
    
    <script>
    import {reactive,markRaw} from 'vue'
    export default {
      name: 'App',
      setup(){
        let obj={name:'小李',age:16}
        obj=markRaw(obj)//永远不会被追踪
        let state=reactive(obj)
        function myFn(){
          state.name="Angle";
          console.log(obj)
        }
        return {state,myFn}
      }
    }
    
    
    </script>
    
    

    在这里插入图片描述

    8.toRef(),toRef和ref,toRef和toRefs

    toRef的应用场景:
    如果想让响应式数据和以前的数据关联起来,并且更新响应式数据之后还不想更新ui时。

    ref和toRef的区别:
    ref:相当于复制,修改响应式数据不会影响以前的数据;toRef:相当于引用,修改响应式数据会影响以前的数据;
    ref:数据改变,界面就更新;toRef:数据改变,界面并不更新;

    ref->相当新复制的一份,没有改原数据。但ref包裹的数据改变了,且改变会更新页面。

    <template>
      <div>
        {{state}}
        <button @click='myFn'>按钮</button>
      </div>
    </template>
    
    <script>
    import {reactive,ref} from 'vue'
    export default {
      name: 'App',
      setup(){
        let obj={name:'小李',age:16}
        let state=ref(obj.name)
        function myFn(){
          state.value="Angle";
          console.log(obj)//没有改变obj
          console.log(state)//state是新的复制出来的一份
        }
        return {state,myFn}
      }
    }
    
    
    </script>
    
    

    在这里插入图片描述
    ->toRef引用,改变了原数据,但界面不更新:

    <template>
      <div>
        {{state}}
        <button @click='myFn'>按钮</button>
      </div>
    </template>
    
    <script>
    import {reactive,toRef} from 'vue'
    export default {
      name: 'App',
      setup(){
        let obj={name:'小李',age:16}
        let state=toRef(obj,'name')
        function myFn(){
          state.value="Angle";
          console.log(obj)//因为引用,所以改变了
          console.log(state)//改变了,但界面没更新
        }
        return {state,myFn}
      }
    }
    
    
    </script>
    
    

    在这里插入图片描述
    toRefs是toRef多个使用的简写:

    <script>
    import {reactive,toRef,toRefs} from 'vue'
    export default {
      name: 'App',
      setup(){
        let obj={name:'小李',age:16}
        let name=toRef(obj,'name');
        let age=toRef(obj,'age');
        // let state=toRef(obj);//简写
        function myFn(){
          name.value="Angle";
          age.value=18;
          // state.name.value='Angle';
          // state.age.value=18;
          console.log(obj)//因为引用,所以改变了
          console.log(state)//改变了,但界面没更新
        }
        return {state,myFn}
      }
    }
    
    
    </script>
    

    9.customRef()自定义ref

    返回一个ref对象,可以显示的控制以来追踪和触发相应。
    get的时候会触发track(),告诉vue这个数据是需要追踪变化的;
    set的时候会触发trigger()。告诉vue触发界面更新。

    <template>
      <div>
        {{age}}
        <button @click='myFn'>按钮</button>
      </div>
    </template>
    
    <script>
    import {ref,customRef} from 'vue'
    function myRef(value){
      return customRef((track,trigger)=>{
        return{
          get(){
            track();//告诉vue这个数据是需要追踪变化的
            console.log('get',value)
            return value;
          },
          set(newValue){
            console.log('set',newValue)
            value=newValue;
            trigger();//告诉vue触发界面更新
          }
        }
      })
    }
    export default {
      name: 'App',
      setup(){
       let age=myRef(18);
       function myFn(){
         age.value+=1;
       }
        return {age,myFn}
      }
    }
    
    
    </script>
    
    

    使用场景:在自定义方便异步请求,看起来不像异步。

    <template>
      <div>
        <ul>
          <li v-for="item in state" :key="item.id">{{item.name}}</li>
        </ul>
      </div>
    </template>
    
    <script>
    import {ref,customRef} from 'vue'
    function myRef(value){
      return customRef((track,trigger)=>{
          //异步
          fetch(value)
          .then((res)=>{
            return res.json()
          })
          .then((data)=>{
            console.log(data);
            value=data;
            trigger();
          })
          .then((err)=>{
            console.log(err)
          })
        return{
          get(){//不能在get中发送异步请求,否则会死循环
            track();//告诉vue这个数据是需要追踪变化的
            console.log('get',value)
            return value;
          },
          set(newValue){
            console.log('set',newValue)
            value=newValue;
            trigger();//告诉vue触发界面更新
          }
        }
      })
    }
    export default {
      name: 'App',
      setup(){
       let state=myRef('./assets/data.json')
        return {state}
      }
    }
    
    
    </script>
    
    

    25

    展开全文
  • Vue3.0正式版发布已一个月有余!很多公司企业都已逐渐过渡到Vue3上来。这意味着,我们将要逐渐抛弃Vue2,彻底的拥抱Vue3的到来,抢先一步掌握Vue3正式版及TypeScript...
  • 本文为通过观看B站vue3.0正式版教程所做笔记,从六大亮点逐一展开介绍新特性与使用注意点等 vue3六大亮点Perfomance性能提升(变快)diff算法优化hoistStatic静态提升cacheHandlers事件侦听器缓存ssr渲染Tree ...
  • Vuejs 3.0 在北京时间2020年9月19日凌晨,终于发布了 3.0 版本,代号:One ...Vue3.0发布链接​github.comVue 是当前非常流行的框架,Vue3.0更是酝酿了2年多的时间,经过2600多次commit,600多次PR,中间也发布了...
  • Vue.js 3.0正式版发布的内容为英文版本,原文见:https://github.com/vuejs/vue-next/releases。本文内容为 QC-L 翻译,经授权后发布。今天,我们非常自豪地宣布 Vue.js 3.0 "One Piece" 发布。本次主...
  • vue3.0 正式版体验

    2020-10-14 15:54:01
    Vue3 正式版本已经更新,再次入坑。 Vue3新特性 首先是向下兼容,Vue3 支持大多数 Vue2 的特性。 性能的提升,框架更快,更轻。 新推出的Composition API。 更好TypeScript支持 安装 vue3 # 全局安装 cnpm i -g ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 381
精华内容 152
关键字:

vue3.0正式版

vue 订阅