VUE小细节杂项整理
此文档主要整理一些不常用的,且常被遗忘掉的知识点
一、${}方法的使用:用于在字符串内绑定数据
常规字符串内绑定数据方法:
<div :id="'a' + count"></div>
利用${}方法:
// 注意:`号不是单引号
// ${变量}
<div :id="`a${count}`"></div>
二、事件函数默认自带$event参数:
<template>
<input type="text" v-model="count" @input="test"/>
</template>
<script setup>
import {
ref
} from 'vue'
const count = ref(123)
const test = $event=>{
console.log($event.detail.value);
}
</script>
三、绑定动态属性、动态事件:
<!-- 动态属性 --> <a :[attributeName]="url"> ... </a>
// attributeName 返回值应用: null 或 string,且字符串为小写(因为浏览器会强制将大写转小写)。 <!-- 动态事件 --> <a @[eventName]="doSomething">
// eventName 返回值应用: null 或 string,且字符串为小写(因为浏览器会强制将大写转小写)。
警告:复杂的动态参数建议采用计算属性,比如以下方式不建议采用:
<!-- 这会触发一个编译器警告 -->
<a :['foo' + bar]="value"> ... </a>
四、DOM更新机制:nextTick()
响应式数据更新之后,DOM并不是同步更新。DOM是在下一个更新周期才同步更新。由于这个更新周期比较快,我们以为他们是同步的。
我们可以使用nextTick()解决这个问题,详见:https://www.cnblogs.com/wm218/p/16702291.html
五、v-show 不支持在 <template> 元素上使用
六、当 v-if 和 v-for 同时存在于一个元素上的时候,v-if 会首先被执行。但是我们不推荐同时使用这二个。
七、v-for内的解勾操作方法:
<template>
<!-- 不解勾,要调用属性访问 item.name -->
<div v-for="(item, index) in lists">第 {{index + 1}}个学生:{{item.name}}</div>
<!-- 解勾直接使用 name -->
<div v-for="({name, age}, index) in lists">第 {{index + 1}}个学生:{{name}}</div>
</template>
<script setup>
import {
ref
} from 'vue'
const lists = ref([
{
id: 1,
name: '张三',
age: 15
},{
id: 2,
name: '李四',
age: 14
}
])
</script>
八、v-for中也可以使用 of 代替 in
<div v-for="item of items"></div>
九、v-for遍历对象
<template>
<div v-for="(key, value, index) in obj">第{{index+1}}个属性:{{key}} : {{value}} </div>
</template>
<script setup>
import {
ref
} from 'vue'
const obj = {
id: 1,
name: '张三',
age: 15
}
</script>
十、<textarea>不支持插件语法,所以必需采用v-model来替代。
<!-- 错误 --> <textarea>{{ text }}</textarea> <!-- 正确 --> <textarea v-model="text"></textarea>
十一、v-model修饰符
.lazy 默认情况下,v-model 会在每次 input 事件后更新数据 (IME 拼字阶段的状态例外)。你可以添加 lazy 修饰符来改为在每次 change 事件后更新数据:
.number 让用户输入自动转换为数字。
1、如果该值无法被 parseFloat() 处理,那么将返回原始值。
2、number 修饰符会在输入框有 type="number" 时自动启用。
.trim 自动去除用户输入内容中两端的空格
十二、ref 操作Dom实例
访问单个实例
<script setup> import { ref, onMounted } from 'vue' // 声明一个 ref 来存放该元素的引用 // 必须和模板里的 ref 同名 const input = ref(null) onMounted(() => { input.value.focus() // 注意,只能在挂载之后获取DOM。而且采用的是.value方式获取实例 }) </script> <template> <input ref="input" /> </template>
访问多个动态实例
<script setup> import { ref, onMounted } from 'vue' const list = ref([ /* ... */ ])
// 由于不确定实例,所以这里采用数组 const itemRefs = ref([]) onMounted(() => console.log(itemRefs.value)) </script> <template> <ul> <li v-for="item in list" ref="itemRefs"> <!-- 注意这里写法 --》 {{ item }} </li> </ul> </template>
十三、组件命名:在单文件中(SFC),建议组件命名采用 PascalCase 形式,以此区分HTML标签。虽然HTML标签不区分大小写,但Vue单文件在编译中区分大小写。
十四、事件、属性名建议采用 kebab-case 全小写形式。在定义prpos或emits时,采用驼峰 camelCase 写法。
十五、建议采用 <my-component></my-component> 这种方式闭合组件,而不是<my-component />。
十六、某些 HTML 元素对于放在其中的元素类型有限制,例如 <ul>,<table> ,相应的,某些元素仅在放置于特定元素中时才会显示,例如 <li>,<tr>。
比如以下输出将会出错:
<table> <blog-post-row></blog-post-row> </table>
解决方案:
<table> <tr is="vue:blog-post-row" v-for="(item,index) in lists" :title="item.title"></tr> </table>
十七、defineProps() 配置中default(){...}或validator(){...} 内不可以访问 <script setup> 中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中。
十八、组件Attributes继承规则:
默认情况下,除props、emits之外的属性会附加到组件根节点上,比如:
<!-- 组件test.vue 内代码 --> <div>我是test组件</div> <!-- 页面调用 test组件代码 --> <test id="a1"></test> <!-- 实际test.vue 渲染结果为 --> <div id="a1">我是test组件</div>
SO,如果组件没有根节点时,我们想把除props、emits之外的属性会附加到指定元素上,可用: v-bind = $attrs 的方式,如下:
<!-- 组件test.vue 内代码 --> <div>我是test组件</div> <div v-bind=$attrs>属性要加在这上面</div> <div>我是test组件</div> <!-- 页面调用 test组件代码 --> <test id="a1"></test> <!-- 实际test.vue 渲染结果为 --> <div>我是test组件</div> <div id="a1">属性要加在这上面</div> <div>我是test组件</div>
十九、访问组件透传 Attributes。
useAttrs()
说明:获有除props、emits内定义的所有属性
返回:[Object]
<script setup> import { useAttrs } from 'vue' const attrs = useAttrs() </script>
二十:书写规范:
一、组件名为多个单词必要 二、Prop 定义应尽量详细 三、始终以 key 配合 v-for。 四、永远不要在一个元素上同时使用 v-if 和 v-for。 五、组件的css样式,尽量使用 scoped、module或者指定class名称的样式。 六、不要将多个组件整合在一个文件内。要把每个组件单独分成文件。 七、组件文件命令建议使用一种方式,要么全是:PascalCase,要么是kebab-case。 不要有的是PascalCase,有的是kebab-case。 八、应用特定样式和约定的基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V。 比如: components/ |- AppButton.vue |- AppTable.vue |- AppIcon.vue 九、只应该拥有单个活跃实例的组件应该以 The 前缀命名,以示其唯一性。 这些组件永远不接受任何 prop ,比如: components/ |- TheHeading.vue |- TheSidebar.vue 十、与父组件紧密耦合的子组件应该以父组件名作为前缀命名。 这样做的好处是:可以把相关联的文件排放在一起。 components/ |- SearchSidebar.vue |- SearchSidebarNavigation.vue 十一、组件名称应该以高阶的 (通常是一般化描述的) 单词开头,并以描述性的修饰词结尾。 这样做的好处是:快速了解该组件的意义 components/ |- SearchButtonClear.vue |- SearchButtonRun.vue |- SearchInputQuery.vue |- SearchInputExcludeGlob.vue |- SettingsCheckboxTerms.vue |- SettingsCheckboxLaunchOnStartup.vue 十二、在单文件组件、字符串模板和 JSX 中,没有内容的组件应该是自闭合的——但在 DOM 模板里永远不要这样做。 十三、对于绝大多数项目来说,在单文件组件和字符串模板中,组件名称应该始终是 PascalCase 的——但是在 DOM 模板中是 kebab-case 的。 十四、组件名称应该倾向于完整的单词,而不是缩写。 十五、在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板和 JSX 中应该始终使用 kebab-case。 十六、多个 attribute 的元素应该分多行撰写,每个 attribute 一行。 十七、指令缩写 (用 : 表示 v-bind:,@ 表示 v-on: 和用 # 表示 v-slot) 应该要么始终使用,要么始终不使用。 十八、单文件组件应始终保持 <script>、<template> 和 <style> 标签的顺序一致。且 <style> 要放在最后,因为另外两个标签至少会有一个。 十九、自定义组件的命名要采用:kebab-case。
二十一、import 同一文件时,export 之外部份只执行一次。且此文件全局数据是共享的。示例:
被引入的文件:t.js
export { t, o } // 这个数据全APP中同步 var ___refreshTime = 30000; // 在首次加载时执行。第二次加载不执行 console.log(333); function t(v) { ___refreshTime = v } function o() { console.log(___refreshTime); }
主页面
<template>
<button @click="to">子页面看修改的后值</button>
</template>
<script setup>
import {
ref,
readonly
} from 'vue'
import {t, o} from '@/common/js/t.js'
t(123) // 修改了值
o() // 显示修改后值
function to(){
uni.navigateTo({
url: '/pages/test/test',
});
}
</script>
去子页面: test.vue 查看数据是否共享:
<script setup> import {t, o} from '@/common/js/t.js' o() // 打印结果,是上一个页面修改后的值 </script>
二十三、为兼容nvue,我们对所有js的路径引入,统一采用 @开头。即 import $array from ‘@/common/js/array.js’ 同时js内部也是采用这一规则。因为 nvue引入时必需使用@
二十四、defineProps 除了可以给子组件传递数组外,单页面还可以通过它获取GET形参,如下:
主页代码:
uni.navigateTo({ url: '/pages/test/test?uid=12', // 打开test页面,并传递 uid形参 });
test.vue 中接收形参代码:
<script setup> const { uid } = defineProps({ uid: { type: String } }) console.log(uid); // 成功接收形参值 </script>
也可以通过onLoad事件接收GET参数:
import { onResize, onLoad } from '@dcloudio/uni-app' onLoad((e)=>{ console.log(e.uid); })

浙公网安备 33010602011771号