写在前面的碎碎念
呐。。。由于种种原因,作为前端开发,写了一段时间react后,又写了一段时间vue,然后又写了一段时间react,现在又写回vue了,来回折腾,两个框架都用了,但是又都用的挺烂
反观出现这样的情况,一部分是外部原因,公司业务需要,但是最主要的原因还是自己没有多进行系统学习,业务开发后也很少静心总结。用用好像都会,但是又不是很会。所以,作为程序猴的自觉,我计算进行一波系统学习。如果有跟我一样情况的朋友,可以一起督促学习。
参考文档先来一遍知识点查漏补缺。 文档地址:www.javascriptc.com/vue3js/guid…
模板语法
- v-once
执行一次性的插值,再次修改不会改变
这个指令用的很少,一般数据都是需要双向绑定,一次性绑定直接赋值data数据也可以
了解知道就好,有需要可以用上
Class样式
class用的不要太多,个人用的比较多的是数组跟对象语法,查阅文档后发现自己经常忽略了对象与数组的结合写法
-
对象与数组组合
当我们条件切换class类名时,可以在class里面进行三目运算,比如:
<span :class="[isActive? 'activeClass' :'','story']">深海鱼子酱</span>但是如果需要三目运算的class多了,会显得很臃肿,这时采用对象和数组结合
<span :class="[{activeClass:isSuccess},{errorClass:isError},'story']">深海鱼子酱</span>当然如果class丰富到上面这种形式也不适合,我们可以采用强大的计算属性的方式
<span :class="computClass" >深海鱼子酱</span> const isSuccess = ref(false) const isError = ref(true) const computClass = computed(()=>{ return { successClass:isSuccess.value, errorClass:isError.value ... } })
事件修饰符
vue提供了一系列的事件修饰符 .self与.stop都可以用来阻断事件传播
比如一个卡片可点击查看详情,卡片里面有个按钮可以点击,有单独的点击行为:
<div class="box" @click="test">
<span @click="test2">点击子标签</span>
</div>
const test = ()=>{
console.log('click parent')
}
const test2 = ()=>{
console.log('click span')
}
如果不加任何处理,当我们点击子标签时,click事件会冒泡到父标签,触发test,执行结果如下:
click span
click parent
当我们加上.stop修饰符或者.self时,可以阻止传播
-
.stop
<div class="box" @click="test"> <span @click.stop="test2">点击子标签</span> </div> -
.self
<div class="box" @click.self="test"> <span @click="test2">点击子标签</span> </div>此时点击子标签,click不会传递到父标签,执行结果如下
click span
两者在上述功能实现上的区别在于:
- .stop作用于“子标签”,隔断事件向外冒泡传递
- .self作用于”父标签“,只在event.target是当前元素自身时触发处理函数, 即事件不是从内部元素触发的
表单输入修饰符
v-model.trim
自动过滤用户输入的首尾空白字符,灵活运用,很方便
自定义修饰符
表单输入有内置修饰符:.trim、.number、.lazy
但实际开发中,我们可能会需要有自定义的修饰符来更方便的处理业务,可以通过 modelModifiers prop来实现
比如将输入内容全改为大写字母
<!--letter组件 以el-input为例-->
<el-input v-model="inputValue" @change="toUpper"/>
const props = defineProps({
modelValue:'',
modelModifiers:{
default:()=>{}
}
})
const inputValue = computed({
get:()=>props.modelValue,
set:value=>emits('update:modelValue',value)
})
const toUpper = (e)=>{
//父组件中自定义的修饰符
if(props.modelModifiers.upper){
const value = e.toUpperCase()
inputValue.value = value
}
}
<letter v-model.upper="letterValue"/>
这样就实现了,输入框中的字母全大写,如果父组件中的model指明了参数如upletter:
<letter v-model:upletter.upper="letterValue"/>
那我们在子组件中定义modelModifiers时需要根据参数进行修改:参数+“modifiers”
const props = defineProps({
modelValue:'',
upletterModifiers:{
default:()=>{}
}
})
父子标签之间非prop的attribute
vue3解除了组件必须单一根节点的限制,非prop的attribute在单个根节点跟多个根节点的情况下处理略有不同
- 单个根节点
<!--weather组件-->
<div>我说:今天不下雨</div>
<weather data-result="bingo"/>
<!--渲染的weather组件-->
<div data-result="bingo">我说:今天不下雨</div>
一般class、style等属性这种用法比较常见,如果传入的属性比较多,那么组件内部在处理的时候可以用useAttr方便处理
<weather data-result="bingo" name="qiqi" color="purple"/>
<!--weather组件-->
import {useAttrs} from "vue"
const attrs = useAttrs()
console.log(attrs.name)//qiqi
- 多个根节点
<!--weather组件-->
<div>我说:今天不下雨</div>
<div>他说:今天会下雨</div>
<weather data-result="bingo"/>
控制台会警告:
Extraneous non-props attributes (name, sex) were passed to component but could not be automatically inherited because component renders fragment or text root nodes
这时需要显示绑定attrs,然后可以正常使用
<!--weather组件-->
<div>我说:今天不下雨</div>
<div v-bind="attrs">他说:今天会下雨</div>
import {useAttrs} from "vue"
const attrs = useAttrs()
未完继续