
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本质
compositionAPI与optionAPI可以混合使用。其本质是注入。
<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钩子之前完成的。所以无法使用data跟methods。另外要注意的是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的金豆之路
微信公众号:前端历劫之路
本文转转自微信公众号前端历劫之路原创https://mp.weixin.qq.com/s/woDgv-1wAN--mEkd2QgJfQ,如有侵权,请联系删除。


 
 
 
 
 