
Vue3 技术精简要点
Vue3 技术精简要点
在线接口
https://dog.ceo/api/breed/pembroke/images/random
http://geek.itheima.net/v1_0/channels
https://api.uomg.com/api/rand.qinghua?format=json
环境安装
到官网下载 nodejs 并安装。版本要求 18.0+。
官方镜像:npm config set registry https://registry.npmjs.org/
官方国内镜像:npm config set registry https://r.cnpmjs.org/
淘宝镜像:npm config set registry https://registry.npmmirror.com/
华为云镜像:npm config set registry https://mirrors.huaweicloud.com/repository/npm/
腾讯云镜像:npm config set registry https://mirrors.cloud.tencent.com/npm/
中国科学技术大学:npm config set registry https://npmreg.proxy.ustclug.org/
网易镜像:npm config set registry https://mirrors.163.com/npm/
阿里云镜像:npm config set registry https://npm.aliyun.com/
创建项目
npm create vite@latest
setup
精要
setup
是Vue3
中的一个函数,组件中所用到的数据、方法、计算属性、监视......等等,均配置在setup
中。setup
函数return
对象中的内容,可直接在模板中使用。setup
函数return
一个函数,则可以自定义渲染内容。setup(){ return ()=> '<h2>Hello!</h2>' }
vue3
中setup
执行时机比vue2 beforeCreate
钩子还靠前。setup
中不存在this
对象。setup
和vue2
中的data 、 methods
是并列同级关系。- 不建议和
vue2
混写。
写法一
<script lang="ts">
export default {
name: "Demo",
setup(props, ctx) {
return{}
},
}
</script>
写法二
<script setup lang="ts" name="Demo"></script>
- 安装插件
npm i vite-plugin-vue-setup-extend -D
。- 修改
vite.config.ts
配置文件。import VueSetupExtend from "vite-plugin-vue-setup-extend"; export default defineConfig({ plugins: [vue(), VueSetupExtend()], });
ref
精要
- 既可定义基本类型的数据又可定义对象类型数据。
- 变量赋值需要加
.value
。ref
包装基本类型数据后变成了RefImpl
类型。ref
包装对象类型数据后RefImpl
中的value
值变成了Proxy(Object)
类型。- 当服务器返回的数据替换原始数据时,对于
ref
包装的对象类型,需要用原始对象.value=服务器对象
,更新数据。- 标签的
ref
属性,用在普通DOM
标签上,获取的是DOM
节点。<template> <div class="demo"> <h1>Demo Component</h1> <p ref="myRef">我是标签p的内嵌文本值</p> </div> </template> <script lang="ts"> import { onMounted, reactive, ref, toRefs } from "vue"; export default { name: "Demo", setup(props, ctx) { let myRef = ref<HTMLParagraphElement | null>(null); // 添加类型标注(可选) onMounted(() => { console.log(myRef.value?.innerText); // 输出:"我是标签p的内嵌文本值" }); return { myRef, }; }, }; </script>
- 标签的
ref
属性,用在组件标签上,获取的是组件实例对象。<script setup lang="ts"> import Demo from "./components/Demo.vue"; import { onMounted, ref } from "vue"; const demo = ref<InstanceType<typeof Demo> | null>(null); onMounted(() => { if (demo.value) { console.log("Demo component is mounted:", demo.value); } else { console.error("Demo component is not mounted."); } }); </script> <template> <Demo ref="demo" /> </template>
提示
通过
ref
父组件获取到子组件的实例后,可以访问子组件中defineExpose
中暴露数据和方法。
路由
精要
- 路由是一组
key-value
的对应关系,多个路由需要经过路由器来管理。- 路由组件通常存放在
pages
或views
文件夹,一般组件通常存放在components
文件夹。- 路由组件消失默认是被卸载掉了,路由组件显示默认是被重新挂载了。
- 路由有
query
和params
两种参数。- 路由
query
、params
和 props 属性配合使用可以简化代码。详见例子。- 路由历史记录默认是
push
模式,另一种是replace
模式。replace
直接添加到RouterLink
上即可。
路由配置
router/index.ts
代码如下:
import { createRouter, createWebHistory, createWebHasHistory, } from "vue-router"; import Component1 from "@/pages/Component1.vue"; import Component2 from "@/pages/Component2.vue"; import Component3 from "@/pages/Component3.vue"; import Component11 from "@/pages/Component1/Component11.vue"; const router = createRouter({ history: createWebHistory(), // hash模式,url带#,兼容性好 // hitstory: createWebHasHistory(), routes: [ { path: "/", redirect: "/route1", }, { name: "组件1", path: "/route1", component: Component1, children: [ { name: "组件11", path: "route11", component: Component11, }, ], }, { name: "组件2", path: "/route2", component: Component2, }, { name: "组件3", path: "/route3", component: Component3, }, ], }); export default router;
hitstory 的两种模式
模式一 hitstory: createWebHasHistory() 带#,
SEO
优化方面相对较差,但兼容性好。写后台管理程序。
模式二 history: createWebHistory() 不带#,接近传统的网站URL
,需要后端处理路径。写前台美观程序。
main.ts
代码如下:
import router from "./router/index";
app.use(router);
app.mount("#app");
App.vue
代码如下:
<template> <div class="app"> <h2 class="title">Router Demo</h2> <!-- 导航区 --> <div class="navigate"> <RouterLink to="/path1" active-class="active">页面一</RouterLink> <RouterLink to="/path2" active-class="active">页面二</RouterLink> <RouterLink to="/path3" active-class="active">页面三</RouterLink> </div> <!-- 展示区 --> <div class="main-content"> <RouterView></RouterView> </div> </div> </template> <script lang="ts" setup name="App"> import { RouterLink, RouterView } from "vue-router"; </script>
路由 to 的三种写法
写法一 to="/path1" 需要写完整路径。
写法二 :to="{path:'/path1'}" 需要写完整路径。
写法三 :to="{name:'组件 1'}" 只需要写名称即可。
路由传参
query
传参第一种写法,这里的id、title、content
均是数组对象中的属性。:to="`/route1/route11?id=${obj.id}&title=${obj.title}&content=${obj.content}`"
注意
to 等号后面字符串里包的是一个模板字符串。这样才能将属性值按照变量传递进去。
query
传参第二种写法:to="{ path:'/route1/route11', query:{ id:obj.id, title:obj.title, content:obj.content } }"
query
传参第三种写法:to="{ name:'组件11', query:{ id:obj.id, title:obj.title, content:obj.content } }"
接收参数
import { useRoute } from "vue-router"; import { toRefs } from "vue"; const route = useRoute(); let { query } = toRefs(route); console.log(query.id);
params
传参
... const router = createRouter({ history: createWebHistory(), routes: [ { name: "组件1", path: "/route1", component: Component1, children: [ { name: "组件11", path: "route11/:id/:title/:content?", //加?的参数可传可不传 component: Component11, }, ], }, ], }); ...
params 传参第一种写法
:to="`/route1/route11/${obj.id}/${obj.title}/${obj.content}`"
params 传参第二种写法
:to="{ name:'组件11', params:{ id:obj.id, title:obj.title, content:obj.content } }"
接收参数
import { useRoute } from "vue-router"; import { toRefs } from "vue"; const route = useRoute(); let { params } = toRefs(route); console.log(params.id);
props
传参第一种写法
... const router = createRouter({ history: createWebHistory(), routes: [ { name: "组件1", path: "/route1", component: Component1, children: [ { name: "组件11", path: "route11/:id/:title/:content?", component: Component11, props:true // 将路由收到的所有params参数作为props传递给路由组件 }, ], }, ], }); ...
props
传参第二种写法... const router = createRouter({ history: createWebHistory(), routes: [ { name: "组件1", path: "/route1", component: Component1, children: [ { name: "组件11", path: "route11", component: Component11, props(route){ return route.query } }, ], }, ], }); ...
接收参数
const props = defineProps(["id", "title", "content"]); console.log(props.id);
编程式路由导航
import { useRouter } from "vue-router"; const router = useRouter(); router.push("/route");
import { useRouter } from "vue-router"; const router = useRouter(); function show(obj) { router.push({ name: "组件11", query: { id: obj.id, title: obj.title, content: obj.content, }, }); }