当前位置:首页 > 程序开发 > Web > VUE3快速入门(10)——路由的基础使用

VUE3快速入门(10)——路由的基础使用

bnbplayer2周前 (03-18)Web57

扫描二维码推送至手机访问。

版权声明:本文由行者无疆发布,如需转载请注明出处。

本文链接:http://xinz.run/post/14.html

标签: VUE
分享给朋友:

“VUE3快速入门(10)——路由的基础使用” 的相关文章

VUE3快速入门(5)——响应式数据

VUE3快速入门(5)——响应式数据

本节讲述了如何用ref和reactive实现基本数据类型和对象数据类型的响应式更新,同时讲述了在何种情况下会失去响应式功能以及对应的解决办法。 1. 什么是响应式响应式是指当变量的值变化后,<template>的内容同步自动更新。Vue2的选项式API中的data默认为响应式,但Vue3的组合式API为非响应式,即无法自动更新。因此需要用ref和reactive进行处理。 2.基本数据类型的响应式处理基本数据类型是指字符串和数字,这种类型只能用ref处理。 2.1 表单输入的响应式更新本节实现HTML标签实时显示表单内容的功能。 在上一节的基础上增加一个HTML元素,用来实时显示表单的输入值: <h2>input框的内容: {{ input_content }}</h2> <input v-model="input_content"/> 修改<script>代码: import { ref } from 'vue' let input_content = ref(''); 对比上一节代码(2.2小节),input_content此时通过ref进行了定义。执行代码,当在input框内输入数据时,<h2>标签的内容将同步更新,此时的input_content为响应式数据。 2.2 代码操作的响应式更新本节实现按钮单击实时更改HTML标签内容的功能。 新增按钮并绑定事件: <button @click="add()">+1</button> 事件处理方法: function add() { input_content.value += 1;//注意:必须通过“ref的实例名.value.字段”的形式更新 } 单击按钮,页面上的数字加1,即通过代码实现了页面的更新。 3. 对象数据类型的响应式处理对象数据类的响应式处理既可以用ref又可以用reactive。 本节将实现通过输入框更改对象的一个字段,并实时显示的功能。<template>部分代码如下: <h2>电话号码: {{ worker.tel }}</h2><!--注意此处对象实例.字段的写法,不受ref或reactive的影响--> <input v-model="tel"/> <button @click="changeTel(tel)">修改电话</button> 3.1 通过ref处理定义表单绑定的变量、事件方法,并通过ref定义一个对象: import { ref } from 'vue' let worker = ref({ name: "Jesse", age: 12, mail: "3898*******@qq.com", tel: "136****615" }); let tel = ""; function changeTel(content: any): any { worker.value.tel = content;//同样通过“ref的实例名.value.字段”的形式更新 } 输入新的号码并点击按钮,将更新worker对象的tel字段,且在页面同步更新。 3.2 通过reactive处理修改代码如下: import { reactive } from 'vue' let worker = reactive({ name: "Jesse", age: 12, mail: "3898*******@qq.com", tel: "136****615" }); let tel = ""; function changeTel(content: any): any { worker.tel = content;//注意此处与ref的区别,不再需要.value } 4. 丢失响应功能的情况当整体替换对象或解构对象时,可能会丢失响应式功能。 4.1 对象类型的字段批量更新很多时候希望将服务器返回的数据直接赋值给对象,从而更新多个的字段。在JS/TS里,服务器返回的数据被视为一个新的对象,如果采用直接赋值的方式会失去响应式功能。 //之前定义的对象 let worker = reactive({ name: "Jesse", age: 12, mail: "3898*******@qq.com", tel: "136****615" }); function getPost(content: any): any { let ajax_obj = JSON.parse(content);//解码JSON,转换成对象 /* 假设ajax_obj对象如下: { name: "Alice", age: 14, mail: "1234*******@qq.com", tel: "132****777" } */ worker = reactive(ajax_obj)//尝试通过这样的方式更新多个字段的内容将会失去响应式功能。 } 4.1.1 逐字段赋值function getPost(content: any): any { let ajax_obj = JSON.parse(content);//解码JSON,转换成对象 worker.name = ajax_obj.name; wroker.age = ajax_obj.age; //... } 这种方法适合字段较少的情况。 4.1.2 使用Object.assginObject.assgin的主要功能是对象合并,第一个参数是原始对象,后面的参数是要合并的多个对象。但使用Object.assgin在某些情况可能不适用。 function getPost(content: any): any { let ajax_obj = JSON.parse(content);//解码JSON,转换成对象 worker = Object.assgin(worker, ajax_obj); } 4.1.3 使用ref将原始对象的定义改为ref即可。 //之前定义的对象 let worker = ref({ name: "Jesse", //... }); function getPost(content: any): any { let ajax_obj = JSON.parse(content);//解码JSON,转换...

VUE3快速入门(6)——计算属性

VUE3快速入门(6)——计算属性

本节讲述了Vue3的计算属性的用法。 1. 什么是计算属性计算属性用于对一些需要展示到模板上的数据进行处理,虽然用函数也能实现,但计算属性会自动缓存,只有值发生变化时才重新计算,加快运行效率。 2. 基本使用方法本节实现一个功能,将输入的电话号码隐去中间四位。 2.1 引用computedimport { computed } from 'vue'; 2.2 使用computed方法定义一个计算属性let encoded_tel = computed(() => { let part_1 = worker.value.tel.substring(0, 3); let part_2 = worker.value.tel.slice(-4); return part_1 + "****" + part_2; }); 其中worker是由ref定义的响应式数据,通过输入框修改电话号码并实时显示的方法参考上一节:VUE3快速入门(5)——响应式数据。 2.3 在模板中使用将上一节的模板变量改为: <h2>电话号码: {{ encoded_tel }}</h2> 这样,当输入电话号码并点击“修改”后,号码将隐去中间四位。 3. 计算属性的读写性如果要通过代码修改计算属性的值,则: function changeComputed() { encoded_tel.value = "..."; } 3.1 只读第二节定义计算属性的方式属于只读属性,采用上述方法修改计算属性的值会报错。 3.2 可读可写要修改计算属性的值,必须定义getter和setter: let encoded_tel = computed(() => { get(){ let part_1 = worker.value.tel.substring(0, 3); let part_2 = worker.value.tel.slice(-4); return part_1 + "****" + part_2; }, set(val){ //针对val的逻辑处理代码 } }); 4. 总结 计算属性与函数类似,但计算属性有缓存,如多次调用其值不变,则仅计算一次;计算属性如果要通过代码修改值,则必须定义getter和setter;对计算属性的value字段赋值,仅仅触发setter的调用,实际上并没有修改任何值,还需要在setter里面编写逻辑处理代码!...

VUE3快速入门(7)——监视

VUE3快速入门(7)——监视

本文讲述了监视基础数据类、对象数据类的方法。 1. 什么是监视监视是指,当被监视的对象发生变化时,执行某个逻辑,类似于控件的消息事件。从被监视的数据类型分类,可分为监视ref创建的普通类型、ref创建的对象类型、reactive创建的对象类型三类;从被监视数据的完整与否又可分为监视整个对象和监视部分属性。 2. ref类型的监视2.1 基础类型import { ref, watch } from 'vue'//引入watch let input_content = ref(0);//创建一个基础数据类型 //使用watch方法实现监视 watch(input_content, (newVal, oldVal)=>{ console.log("值:", newVal, oldVal) }); 关于watch方法的参数: 参数1: 需要时监视的变量;参数2: 回调函数,其中有两个传入参数,分别为新值和的值;也可以只有一个参数,即为新值;参数3: 配置对象,用于指定一些其他功能,如立即监视、深度监视等。 2.2 监视整个对象监视由ref定义的对象类型,其实是在监控对象类型的地址,因此部分字段的更新不会触发监视,需要手动开启深度监视。在这种情况下,任何一个字段的变化都会触发监视。 例子:监控员工年龄变化,当到达35岁时让其卷铺盖走人。HTML部分: <button @click="add()">+1</button> JS部分: import { ref, watch } from 'vue'//引入watch let worker = ref({ name: "张三", age: 32 }); function add(): any { worker.value.age += 1; } const stop = watch(worker, (newVal, oldVal)=>{ console.log("值:", newVal, oldVal) if(newVal.age > 35) { alert("卷铺盖走人"); stop();//停止监视 } }, {deep: true});//第三个参数开启深度监视 提示: 上述代码中,watch返回了一个函数,调用该函数时会停止当前的监视;watch的第三个参数开启了深度监视选项,这样仅变化对象成员时,也会触发监视调用;控制台打印的newVal, oldVal值均相同,因为对象的地址没有发生变化。 2.3 监视对象的属性(部分监视)很多时候,我们仅需要关注对象的某几个字段是否发生了变化,即部分监视。对象的部分属性又可能是基础类型,也可能是一个嵌套的对象。因此部分监视又分为基础数据类型和对象数据类型两种。 2.3.1 属性为基础数据类型需要将被监视的数据包装为getter函数 import { ref, watch } from 'vue'//引入watch let worker = ref({ name: "张三", age: 32 }); function add(): any { worker.value.age += 1; } const stop = watch(()=>{ return worker.value.age }, (newVal, oldVal)=>{ console.log("值:", newVal, oldVal) if(newVal > 35) { alert("卷铺盖走人"); stop();//停止监视 } }); 注意箭头函数也可以简写成: ()=> worker.value.age 2.3.2 属性为对象类型即嵌套对象,修改worker代码,增加银行存款账户的嵌套对象类属性: let worker = ref({ name: "张三", age: 32, accounts: { icbc: 2000, bc: 1200 } }); 增加存款和清零的功能: <button @click="icbc()">存入工行</button> <button @click="bc()">存入中行</button> <button @click="clear()">清零存款</button> function icbc() { //改变accounts的一个属性 worker.value.accounts.icbc += 1000; } function bc() { //改变accounts的一个属性 worker.value.accounts.bc += 1000; } function clear() { //改变整个accounts worker.value.accounts = {bc: 0, icbc: 0}; } 仅监视存款清零: watch(() => worker.value.accounts, (newVal, oldVal)=>{ console.log("账户变动:", newVal, oldVal) }); 监视存款清零和增加存款: watch(() => worker.value.accounts, (newVal, oldVal)=>{ console.log("存款清零:", newVal, oldVal) },{deep: true});//开启了深度监视 提示: 与整个对象的监视不同,部分监视即使该部分是对象,也必须写成getter函数形式,在这种情况下监视的是部分对象的地址;监视嵌套对象的内部属性,开启深度监视即可;最佳编码方式是,由ref创建的对象,只要是部分监视,则一律写成getter函数。 3. reactive类型的监视将worker修改为由reactive定义的响应式对象,特别注意整体修改accounts属性的写法: function clear() { Object.assign(worker.accounts, {bc: 0, icbc: 0}); } 监视accounts属性: watch(worker.accounts, (newVal, oldVal)=>{ console.log("账户变动:", newVal, oldVal) }); 当accou...

关于“拓源纯净主题”引发的Undefined array key "pro" 的修复

关于“拓源纯净主题”引发的Undefined array key "pro" 的修复

本博客使用的是由拓源 推出的“纯净主题”。目前发现一个由于IP查询接口触发的问题,导致主题需要显示IP归属地的页面(如留言、评论页等)会出现如下错误: 经检查,该主题的 tpure_IP函数使用了一个“https://whois.pconline.com.cn/ipJson.jsp” 接口查询IP归属地,但该接口不稳定,时常返回空,所以触发了上述问题。修改方式如下: 1 定位到函数在该主题的安装目录下(位置:/zblog的安装目录/zb_users/theme/tpure),打开includes.php 在编辑器中按“Ctrl+F”搜索函数:tpure_IP。找到如下代码: function tpure_IP($ip) { $ch = curl_init(); $url = 'https://whois.pconline.com.cn/ipJson.jsp?ip='.$ip; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false ); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $location = curl_exec($ch); curl_close($ch); $location = mb_convert_encoding($location, 'utf-8','GB2312'); $location = substr($location, strlen('({')+strpos($location, '({'),(strlen($location) - strpos($location, '})'))*(-1)); $location = str_replace('"',"",str_replace(":","=",str_replace(",","&",$location))); parse_str($location,$ip_location); return $ip_location['pro']; } 2 更换查询接口,实现自己的解析方式在function tpure_IP($ip)代码前增加函数ip_parser($ip),完整代码如下: function ip_query($ip) { $url = "https://opendata.baidu.com/api.php?query={$ip}&co=&resource_id=6006&oe=utf8";//此处使用百度API $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false ); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $location = curl_exec($ch); curl_close($ch); $ip_obj = json_decode($location, true); if(0 != count($ip_obj['data']) && array_key_exists('location', $ip_obj['data'][0])) return $ip_obj['data'][0]['location']; else return '未知'; } 注意,该代码一定要放在tpure_IP函数的前面。 3 注释原来的代码,调用新的函数将tpure_IP函数体内的代码全部用/**/注释,并在最后添加ip_query的调用代码,如下: function tpure_IP($ip) { /* $ch = curl_init(); $url = 'https://whois.pconline.com.cn/ipJson.jsp?ip='.$ip; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false ); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $location = curl_exec($ch); curl_close($ch); $location = mb_convert_encoding($location, 'utf-8','GB2312'); $location = substr($location, strlen('({')+strpos($location, '({'),(strlen($location) - strpos($location, '})'))*(-1)); $location = str_replace('"',"",str_replace(":","=",str_replace(",","&",$location))); parse_str($location,$ip_location); return $ip_location['pro']; */ return ip_query($ip); } 相当于不再使用原本的实现,而使用自己的实现,但函数名称不变,保存即可。有动手能力的大佬也可以将API换成其他的,但是解析代码也同样要换。 点击下列链接可以下载本人修改好的文件进行替换。请注意备份好源文件!!!include.php...

VUE3快速入门(11)——路由的嵌套与传参

VUE3快速入门(11)——路由的嵌套与传参

1. 嵌套路由1.1 什么是嵌套路由嵌套路由是指一个路由视图中又包含一个路由视图,通常用于多级分类的SPA。比如一个新闻SPA,分为板块与列表二级。单击不同的板块出现不同的文章列表,再点击列表则出现新闻正文。本文基于上一节内容增加新闻列表和新闻详情的展示功能。 1.2 创建显示新闻详情的视图组件在“@/views/”路径下,新增一个Content.vue组件,HTML部分如下: <template> <div id="detail"> <h2>新闻标题</h2> <p>这是新闻的具体内容</p> </div> </template> 1.2 定义新闻数据修改上一节的News.vue代码的ts部分,增加新闻数据: <script lang="ts" name="News" setup> import { ref } from 'vue'; const news_data = ref([ { id: 1, title: '新闻1', content: '新闻内容1' }, { id: 2, title: '新闻2', content: '新闻内容2' }, { id: 3, title: '新闻3', content: '新闻内容3' }, { id: 4, title: '新闻4', content: '新闻内容4' } ]); </script> 1.3 新增子路由定义在路由定义文件的新闻路径下增加一个子路由: import Content from '@/views/Content.vue'//新增引入 const router = createRouter({ history: createWebHashHistory(), routes: [ //... { name: 'news', path: '/news', component: News, //增加children属性,注意为数组 children: [ { name: 'content', path: 'content',//注意:子路由无需再用“/” component: Content, }], }, //... ], }) 1.4 修改新闻列表视图修改News.vue的HTML部分如下: <template> <h1>新闻列表</h1> <div id="warpper"> <!-- 左侧新闻列表 ---> <div id="list"> <ul> <li v-for="item in news_data" :key="item.id"> <p><RouterLink :to='{path: "/news/content"}'>{{ item.title }}</RouterLink></p> </li> </ul> </div> <!-- 右侧新闻内容 --> <div id="content"> <RouterView></RouterView> </div> </div> </template> 注意二级路由的写法。 修改完成后,可以在新闻导航内看到左侧的新闻列表,点击链接在右侧展示的新闻内容。 2. 路由传参上述代码中点击每个新闻链接展示的内容都一样,现在需要根据链接展示不同的新闻,该功能需要用路由传参来实现。 2.1 Query传参路由定义文件见前文。 2.1.1 直接字符串拼接(不推荐)修改New.vue的RouterLink组件调用代码: <p> <RouterLink :to='`/news/content?title=${ item.title }&content=${ item.content }`'>{{ item.title }}</RouterLink> </p> 注意VUE的字符串模板语法:`…${变量名1}…${变量名2}…`。修改Content.vue的代码,取参数:ts部分: import { useRoute } from 'vue-router'//引入useRoute import { toRefs } from 'vue'//响应式 const route = useRoute() const { query } = toRefs(route)//从useRoute中解构query属性,该属性保存了传递的参数。 html部分: <template> <div id="detail"> <!-- 从query属性获取title参数--> <h2>{{ query.title }}</h2> <!-- 从query属性获取content参数--> <p>{{ query.content }}</p> </div> </template> 注意:由于是直接把传递的参数进行动态显示,所以在解构时需要转换为响应式类型。或者不解构,则写法为: <...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。