Vue3.0系列——「vue3.0学习手册」第一期

Jacquelyn38
• 阅读 1560

Vue3.0系列——「vue3.0学习手册」第一期

Vue3.0

一、项目搭建

vite是尤大大开发的一款意图取代webpack的工具。其实现原理是利用ES6的import发送请求加载文件的特性。拦截这些请求,做一些编译,省去webpack冗长的打包时间。并将其与Rollup捆绑在一起用于生产。在开发过程中没有捆绑。源代码中的ES Import语法直接提供给浏览器,浏览器通过本机<script module>支持对其进行解析,从而为每次导入发出HTTP请求。开发服务器拦截请求,并在必要时执行代码转换。例如,对*.vue文件的导入会在发送回浏览器之前即时进行编译。

1、全局安装vite脚手架

npm install -g create-vite-app  

2、使用脚手架创建项目

create-vite-app projectName  

3、进入项目文件夹

cd projectName  

4、安装依赖

npm install  

5、启动vue3.0项目

npm run dev  

二、vue2.x存在的问题

2.x中的一点问题是当业务不断增多时,数据跟逻辑分散,会很难维护。

<template>  
  <div>  
    <div>  
      <input type="text" v-model="obj.id">  
      <input type="text" v-model="obj.con">  
      <button @click="submit">提 交</button>  
    </div>  
    <ul>  
      <li v-for="(item,index) in list" :key="item.id" @click="cli(index)">  
        {{item.id}}-{{item.con}}  
      </li>  
    </ul>  
  </div>  
</template>  

<script>  
export default {  
  name:"filterBox",  
  data(){  
    return {  
      list:[  
        {  
          id:1,  
          con:"a"  
        },  
        {  
          id:2,  
          con:"b"  
        }  
      ],  
      obj:{  
        id:"",  
        con:""  
      }  
      // 代码数据1  
      // 代码数据2  
      // ...  
    }  
  },  
  methods:{  
    cli(index){  
      this.list = this.list.filter((item,idx)=>idx!==index);  
      console.log(this.list);  
    },  
    submit(){  
      // const obj = Object.assign({},this.obj);  
      this.list.push(this.obj);  
      this.obj.id = "";  
      this.obj.con = "";  
    },  
    // 执行代码代码逻辑3  
    // ...  
  },  
  computed:{  
   // 执行代码代码逻辑1  
  },  
  watch:{  
   // 执行代码逻辑2  
  }  
}  
</script>  

<style>  

</style>  

三、组合API

ref

<template>  
  <div>  
    <p>{{count}}</p>  
    <button @click="add">add</button>  
  </div>  
</template>  

<script>  
import {ref} from "vue"  
export default {  
  name: 'App',  
  setup(){  
    // 定义一个名称叫做count变量,这个变量的初始值是0  
    // 这个变量发生该改变之后,vue会自动更新页面。  
    const count  = ref(0);  
 // 在组合API中,如果想定义方法,不用定义到methods中,直接在setup函数中定义即可。  
    const add = () => {  
      count.value+=1;  
    }  
 // 在组合API中定义的变量/方法,要想在外界使用,必须return出去。  
    return {  
      count,  
      add  
    }  
  }  
}  
</script>  

ref只能监听简单类型的变化,不能监听复杂类型的变化(对象/数组)。它的本质是reactive,当我们给ref函数传递一个值时,ref函数会自动将ref转换成reactive`。

ref(0) -->  reactive({  
value:0  
})  

另外,需要注意的是,如果是通过ref创建出来的数据,那么在template中使用的时候不用通过.value来获取。因为Vue会自动给我们添加.value

那么vue是如何决定是否需要自动添加.value的。vue在解析数据之前,会自动判断这个数据是否是ref类型的,如果是就自动添加.value,如果不是就不自动添加.value

vue是如何判断当前的数据是否是ref类型的?通过当前数据的__v_ref来判断的,如果有这个私有的属性,并且取值为true,那么就代表是一个ref类型的数据。

那么我们开发者也有自己api来判断。isRef(数据),返回true或者是false

import {isRef} from 'vue'  

reactive

reactive 可以监听复杂类型的变化,如对象或者数组。

let state = reactive({  
 name:"maomin"  
});  
// 或  
let arr = reactive([1,2,3]);  
<template>  
  <div>  
    <ul>  
      <li v-for="(item,index) in state.list" :key="item.id" @click="removeItem(index)">{{item.id}}--{{item.con}}</li>  
    </ul>  
  </div>  
</template>  

<script>  
import {reactive} from "vue"  
export default {  
  name: 'App',  
  setup(){  
    const state  = reactive({  
      list:[  
        {  
          id:1,  
          con:"A"  
        },  
        {  
          id:2,  
          con:"B"  
        },  
        {  
          id:3,  
          con:"C"  
        }  
      ]  
    });  

    const removeItem = (index) => {  
      state.list = state.list.filter((item,i)=>i!==index)  
    }  

    return {  
      state,  
      removeItem  
    }  
  }  
}  
</script>  

我们可以改变下,把数据跟逻辑放在一块,这样就解决了vue2.x的数据跟逻辑分散的问题。

<template>  
  <div>  
    <ul>  
      <li  
        v-for="(item, index) in state.list"  
        :key="item.id"  
        @click="removeItem(index)"  
      >  
        {{ item.id }}--{{ item.con }}  
      </li>  
    </ul>  
  </div>  
</template>  

<script>  
import { reactive } from "vue";  
export default {  
  name: "App",  
  setup() {  
    let {state,removeItem} = userReturn();  
    return {  
      state,  
      removeItem,  
    };  
  },  
};  

function userReturn(params) {  
  const state = reactive({  
    list: [  
      {  
        id: 1,  
        con: "A",  
      },  
      {  
        id: 2,  
        con: "B",  
      },  
      {  
        id: 3,  
        con: "C",  
      },  
    ],  
  });  

  const removeItem = (index) => {  
    state.list = state.list.filter((item, i) => i !== index);  
  };  

  return {state,removeItem}  
}  
</script>  

我们实现了上面的删除功能,那我们在实现一个添加的功能。

<template>  
  <div>  
    <input type="text" v-model="state2.items.id">  
    <input type="text" v-model="state2.items.con">  
    <button @click="addItem">添加</button>  
    <ul>  
      <li  
        v-for="(item, index) in state.list"  
        :key="item.id"  
        @click="removeItem(index)"  
      >  
        {{ item.id }}--{{ item.con }}  
      </li>  
    </ul>  
  </div>  
</template>  

<script>  
import { reactive } from "vue";  
export default {  
  name: "App",  
  setup() {  
    let {state,removeItem} = userRemove();  
    let {state2,addItem} = userAdd(state);  
    return {  
      state,  
      removeItem,  
      state2,  
      addItem  
    };  
  },  
};  
// 添加  
function userAdd(state) {  
   const state2 = reactive({  
    items:{  
      id:"",  
      con:""  
    }  
  });  

  const addItem = () => {  
    const items = Object.assign({},state2.items);  
    state.list.push(items);  
    state2.items.id = "";  
    state2.items.con = "";  
  };  

  return {state,state2,addItem}  
}  
// 删除  
function userRemove(params) {  
  const state = reactive({  
    list: [  
      {  
        id: 1,  
        con: "A",  
      },  
      {  
        id: 2,  
        con: "B",  
      },  
      {  
        id: 3,  
        con: "C",  
      },  
    ],  
  });  

  const removeItem = (index) => {  
    state.list = state.list.filter((item, i) => i !== index);  
  };  

  return {state,removeItem}  
}  
</script>  

如果是其他对象,默认情况下修改对象,界面不会更新。

<template>  
  <div>  
    <p>{{state.time}}</p>  
    <button @click="add">加一天</button>  
  </div>  
</template>  

<script>  
import {reactive} from 'vue'  
export default {  
  name:"Demo4",  
  setup(){  
    const state = reactive(  
      {  
        time:new Date()  
      }  
    );  
    function add () {  
      state.time.setDate(state.time.getDate()+1);  
      console.log(state);  
    }  
    return {  
      state,  
      add  
    }  
  }  
}  
</script>  

<style>  

</style>  

如果想更新,可以通过重新赋值的方法。

<template>  
  <div>  
    <p>{{ state.time }}</p>  
    <button @click="add">加一天</button>  
  </div>  
</template>  

<script>  
import { reactive } from "vue";  
export default {  
  name: "Demo4",  
  setup() {  
    const state = reactive({  
      time: new Date(),  
    });  
    function add() {  
      const newTime = new Date(state.time.getTime());  
      newTime.setDate(state.time.getDate() + 1);  
      state.time = newTime;  
      console.log(state);  
    }  
    return {  
      state,  
      add,  
    };  
  },  
};  
</script>  

<style>  
</style>  

同样,我们开发者如果要是检测一个数据是否是reactive类型的。可以用isReactive(数据),返回true或者false

import {isReactive} from 'vue'  

四、组合API本质

compositionAPIoptionAPI可以混合使用。其本质是注入。

<template>  
  <div>  
    <p>Vue2.x</p>  
    <button @click="cli1">点击</button>  
    <p>Vue3.0</p>  
    <button @click="cli2">点击</button>  
  </div>  
</template>  

<script>  
import {ref} from "vue"  
export default {  
  name:"Demo2",  
  data(){  
    return {  
      msg:"Vue2.x"  
    }  
  },  
  methods:{  
    cli1(){  
      alert(this.msg);  
    }  
  },  
  setup(){  
    let txt = ref("Vue3.0"); // 注入到data函数内  
    function cli2() { // 注入到methods属性内  
      alert(txt.value);   
    }  
    return {  
      txt,  
      cli2  
    }  
  }  
}  
</script>  

<style>  

</style>  

五、setup执行时机与注意事项

setup函数,是在beforecreate钩子之前完成的。所以无法使用datamethods。另外要注意的是setup是同步的,不是异步的。

<template>  
  <div>  
    <button @click="name">打开</button>  
  </div>  
</template>  

<script>  
export default {  
  name:"Demo3",  
  data(){  
    return {  
      msg:"hello"  
    }  
  },  
  setup(){  
    function name() {  
      console.log(this.msg); // undefined  
    }  
    return {  
      name  
    }  
  }  
}  
</script>  

<style>  

</style>  

下一期继续

  • 欢迎关注我的公众号前端历劫之路

  • 回复关键词电子书,即可获取12本前端热门电子书。

  • 回复关键词红宝书第4版,即可获取最新《JavaScript高级程序设计》(第四版)电子书。

  • 关注公众号后,点击下方菜单即可加我微信,我拉拢了很多IT大佬,创建了一个技术交流、文章分享群,期待你的加入。

  • 作者:Vam的金豆之路

  • 微信公众号:前端历劫之路

Vue3.0系列——「vue3.0学习手册」第一期

本文转转自微信公众号前端历劫之路原创https://mp.weixin.qq.com/s/woDgv-1wAN--mEkd2QgJfQ,如有侵权,请联系删除。

点赞
收藏
评论区
推荐文章
Jacquelyn38 Jacquelyn38
3年前
Vue3.0系列——「vue3.0性能是如何变快的?」
前言1.先学习vue2.x,很多2.x内容依然保留;2.先学习TypeScript,vue3.0是用TS重写的,想知其然知其所以然必须学习TS。为什么学习vue3.0?性能比vue2.x快1.2~2倍按需编译,体积比vue2.x更小组合API(类似ReactHook)更好的TS支持
Easter79 Easter79
3年前
Vue 3.0 公开源码后,有人说这也能算 TypeScript ?
点上方蓝字关注公众号「前端从进阶到入院」精选原创好文、进阶交流群助你进入大厂本文转自公众号「工业聚」前言在2019年10月5日,尤小右公开了Vue3.0的源代码。vue 3.0 源代码仓库https://github.com/vuejs/vuenext想了解vue3.0源码的同学,可以访
Souleigh ✨ Souleigh ✨
3年前
🎉无人维护?官方打脸:Element UI for Vue 3.0 来了!🎊
Element开发团队宣布正式发布ElementPlus的首个beta版本,ElementPlus是Element对Vue3.0的升级适配。此前网上有传言称Element无人维护,ElementUI也不会支持Vue3.0,这次官方出来打脸了。image(https://imghelloworld.ossc
可莉 可莉
3年前
10分钟了解一下最近很火的Vite
!(https://oscimg.oschina.net/oscnet/155d0d0cb90746aba172a8cb686c6ead.png)关注公众号前端人,回复“加群”添加无广告学习群Vite是vue的作者尤雨溪开发的打包工具,目前亮点是本地开发时热加载编译极快,在大型项目中体验较
Wesley13 Wesley13
3年前
KO
KOKO是一个基于Webpack开发的快速开始Web开发的脚手架工具,具有以下特性:可以当做一个Webpack配置种子来使用,无需二次配置、开箱即用自动支持多页应用(可选)Vue单文件组件的开发方式资源分块加载,内联和异步加载方式管理,低成本实现首屏优化支
可莉 可莉
3年前
10个前端8个用Vue的,怎么才能在面试中出彩?
现在但凡出去面试,面试官几乎必问Vue3.0。不仅会问一些核心特性,还会问原理层面的问题。比如:▶框架层面问题:Vue3.0新特性CompositionAPI与React.js中Hooks的异同点?▶源码、原理层面问题: Vue3.0编译做了哪些优化?Vue3.0是如何变得更快的?
Easter79 Easter79
3年前
The way of Webpack learning (VI.)
使用commonChunkPlugin的都是基于webpack3.10.0,在webpack4中直接配置optimization就可以了。一:什么是长缓存?浏览器在用户访问页面的时候,为了加快加载速度,对用户请求的静态资源都会进行存储,但是每次代码更新或者升级的时候,我们都需要浏览器去加载新的代码。最方便的方法就是引入新的文件名称,只下载新的
手把手带你初探Vue 3.0 | 京东物流技术团队
距离Vue3.0正式发布已经过去一段时间了,2月7日Vue团队正式宣布Vue3正式成为新的默认版本。最近接触的新项目也使用Vue3.0来开发,因此有必要对它进行一波总结和学习。