# typescript **Repository Path**: destiny001/typescript ## Basic Information - **Project Name**: typescript - **Description**: TypeScript-正在完善中... - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2021-04-11 - **Last Updated**: 2022-05-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vue3.0 ## 01 vue3现状 [vue-next](https://github.com/vuejs/vue-next/) 2020年09月18日,正式发布vue3.0版本。但是由于刚发布周边生态不支持,大多数开发者处于观望。 Vue3优点: - 最火框架,它是国内最火的前端框架之一,[官方文档](https://v3.vuejs.org/) [中文文档](https://v3.cn.vuejs.org/) - 性能提升,运行速度事vue2.x的1.5倍左右 - 体积更小,按需编译体积比vue2.x要更小 - 类型推断,更好的支持Ts(typescript)这个也是趋势 - **★组合API (composition api)** ,能够更好的组织逻辑,封装逻辑,复用逻辑 现在公司90%还是vue2.0,新的项目可能会采用3.0 ## 02 vite ### vite介绍 vite是什么:[官方文档](https://cn.vitejs.dev/) - 它是一个更加轻量(热更新速度快,打包构建速度快)的vue项目脚手架工具。 - 相对于vue-cli它默认安装的插件非常少,随着开发过程依赖增多,需要自己额外配置。 - **所以:** 在学习vue3语法或者做小型项目会使用它,做大型项目的时候我们还是使用vue-cli vite基本使用: - 创建项目 `npm init vite-app 项目名称` 或者 `yarn create vite-app 项目名称` - 安装依赖 `npm i` 或者 `yarn ` - 启动项目 `npm run dev` 或者 `yarn dev` ### vite和webpack的区别 #### webpack打包过程 - 识别入口文件 - 通过逐层识别模块依赖 - webpack做的就是分析代码。转换代码,编译代码,输出代码 - 最终形成打包后的代码 #### vite原理 - 当声明一个 script 标签类型为 module 时 ```go //浏览器就会像服务器发起一个GET http://localhost:3000/src/main.js请求main.js文件: ``` ```go // /src/main.js: import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ``` - 浏览器请求到了main.js文件,检测到内部含有import引入的包,又会对其内部的 import 引用发起 HTTP 请求获取模块的内容文件 - 如:`GET http://localhost:3000/@modules/vue.js` - 如:`GET http://localhost:3000/src/App.vue` - `Vite` 的主要功能就是通过劫持浏览器的这些请求,并在后端进行相应的处理将项目中使用的文件通过简单的分解与整合,然后再返回给浏览器,vite整个过程中没有对文件进行打包编译,所以其运行速度比原始的`webpack`开发编译速度快出许多! ## 03 项目创建 1. 全局安装yarn ```js npm init vite-app vue3-demo(项目名) ``` 2. 进入到项目 ```js cd vue3-demo ``` 3. 装包 ```js npm i/ yarn ``` 4. 运行 ```js npm run dev ``` 5. main.js 入口代码 ```js import { createApp } from 'vue' import App from './App.vue' import './index.css' // 创建vue应用并渲染App组件,挂载到#app容器中 createApp(App).mount('#app') ``` ## 04 vue3.0 组合式api vue2.0采用的叫做选项式api: 例如我们想实现某一个功能,关于这个功能的数据我们会定义在data中,事件函数定义在methods中,计算属性定义在computed中... ```js new Vue({ data () { return { a: 213, b: 2, c: 5, d: 6 } }, methods: { add () {}, remove () {} }, computed: { totalPrice () {} } }) ``` 实际上我们想实现一个功能会把我们代码拆分写到不同的模块中,这样我们很难区分,哪个数据和哪个逻辑是一一对应的,而且想实现这个功能也要在data、methods、computed中跳来跳去。 Vue3.0的组合式(composition-api)api: 我们会把同一功能的逻辑写在一起 ```js ``` ## 05 setup ### 基本使用 1. setup是composition-api的入口函数 2. 在生命周期beforeCreate之前被调用 3. setup内部不能使用this获取到组件实例 4. setup内部可以返回数据和方法供模版使用 ```js ``` ⚠️:setup内部直接定义的数据不是响应式的 ### 定义响应式数据 #### reactive 可以将一个复杂数据类型代理为响应式数据 1. 引入reactive ```js import { reactive } from 'vue' ``` 2. 通过reactive定义响应式数据 ```js setup() { // 定义响应式数据 const data = reactive({ count: 10 }) const clickHandle = () => { // 修改数据 data.count++ } return { data, clickHandle } } ``` 3. 模版中使用响应式数据 ```js {{ data.count }} ``` #### toRef 将响应式对象中某一个属性结构成响应式数据 直接结构无法达成响应式 ```html ``` ```js setup() { const state = reactive({ name: '张三', age: 19 }) let { name } = state const clickHandle = () => { name = '李四' } return { name, clickHandle } } ``` 利用toRef进行处理 ```js setup() { const state = reactive({ name: '张三', age: 19 }) let name = toRef(state, 'name') const clickHandle = () => { // 需要通过value访问到具体数据 name.value = '李四' } return { name, clickHandle } } ``` #### toRefs 将响应对象内所有属性处理为响应式属性 ```html ``` ```js setup() { const state = reactive({ name: '张三', age: 19 }) const clickHandle = () => { console.log(123) state.name = '李四' } return { ...toRefs(state), clickHandle } } ``` #### ref 常用语将普通数据处理为响应式数据 1. 引入ref ```js import { ref } from 'vue' ``` 2. 通过ref定义响应式数据 ```js setup() { // ref函数可传递数据的默认值 const count = ref(10) return { count } } ``` 3. 使用数据 ```html ``` 4. 修改数据(需要通过数据.value进行修改) ```js setup() { const count = ref(10) const clickHandle = () => { count.value++ } return { count, clickHandle } } ``` ## 06 生命周期函数 可以直接导入 `onXXX` 一族的函数来注册生命周期钩子: ```js import { onUpdated, onUnmounted } from 'vue' ``` ```js export default { name: 'App', setup() { onBeforeMount(() => { console.log(document.querySelector('#custom-h1')) // null }) onMounted(() => { console.log(document.querySelector('#custom-h1')) //

hello

}) } } ``` **与 2.x 版本生命周期相对应的组合式 API** - `beforeCreate` -> 使用 `setup()` - `created` -> 使用 `setup()` - `beforeMount` -> `onBeforeMount` - `mounted` -> `onMounted` - `beforeUpdate` -> `onBeforeUpdate` - `updated` -> `onUpdated` - `beforeDestroy` -> `onBeforeUnmount` - `destroyed` -> `onUnmounted` ## 07 - 案例 ![image-20210724221332768](/Users/liufusong/Desktop/extend/vue3+ts/images/鼠标案例.png) 案例分析: 1. 定义数据并且渲染数据,定义的数据需要为响应式,因为鼠标移动数据会发生变化 2. 鼠标移动修改数据,给文档绑定鼠标移动事件(注意时机,页面一进来并且能操作dom) 3. 通过获取事件对象的信息获取到坐标并赋值给数据 4. 组件销毁卸载事件 ### 1. 定义数据并渲染 ```html ``` ### 2. 绑定鼠标移动事件 ```js import { reactive, toRefs, onMounted } from 'vue' export default { name: 'App', setup() { // 定义数据 const mouse = reactive({ x: 0, y: 0 }) // 鼠标移动修改数据 const setDataOnMove = e => { console.log(e) } // 绑定鼠标事件 onMounted(() => { document.addEventListener('mousemove', setDataOnMove) }) return mouse } } ``` ### 3. 获取数据并修改 ```js // 鼠标移动修改数据 const setDataOnMove = e => { mouse.x = e.x mouse.y = e.y } ``` ### 4. 组件卸载销毁事件 ```js // 1.4 组件消耗,删除事件 onUnmounted(()=>{ document.removeEventListener('mousemove', move) }) ``` ### computed 引入computed 1. 直接在setup内部定义 ```js setup () { const doubleNum = computed(() => { return state.num * 2 }) return { doubleNum } } ``` 2. 在state中定义 ```js const state = reactive({ num: 123, doubleNum: computed(() => { return state.num * 2 }) }) ``` ### watch ```js watch(() => state.num, (newValue, oldValue) => { console.log('num变化了', newValue, oldValue) }) ``` ### 依赖注入 依赖注入并不是vue3.0新增的特性,2.0就开始支持,只不过使用方式有所区别 1. 引入provide进行提供数据 ```js import { provide } from 'vue' ``` ```js setup () { const state = reactive({ msg: 'hello' }) provide('num', state.msg) } ``` 2. 子组建通过inject进行接收 ```js import { inject } from 'vue' export default { setup () { const num = inject('num') console.log(num) } } ``` ### 路由 vue3中的路由使用方式变成了导入方法,进行路由的使用 ```js import { createRouter, createWebHistory } from 'vue-router' const routes = [ ] const router = createRouter({ history: createWebHistory(), routes }) export default router ``` createRouter: 用来创建路由对象 createWebHistory:用来使用history模式的路由 createWebHashHistory:用来使用hash模式的路由 #### useRouter 使用useRouter进行编程式导航 ```js import { useRouter } from 'vue-router' setup () { const router = useRouter() const goHome = () => { router.push('/home') } } ``` #### useRoute 通过useRoute获取当前路由信息,path、query、params ```js import { useRoute } from 'vue-router' setup () { const route = useRoute() console.log(route.path) } ```