20240126收获

  1. el-table比较常见的需要跳转column的场景,目前遇到三种,一种是前面列变成序号,用的是type=index:index来设置索引,第二种是变成多选,用的是type=select和在table上加上select-change事件,第三种是折叠,用的是type=expand和在table上加上expand-change事件。
  2. el-table的数据有时候从后台返回来的和我们希望渲染的样子不同,此时我们需要加工,然后我一开始有疑惑,为什么选择用:formatter这个column上的属性而不是用computed,经过我思考后,我觉得渲染的时候通过formatter属性已经足够在函数中写好我们要的逻辑了,而且computed更倾向于是我们自定义的一些值。(目前对于computed了解的还不够)
  3. this.$route.query是自带的,所以可以直接写,如果query里面没有其他值会取到undefined,所以要判断是否有id传入,是可以写成this.$route.query?.id的.
  4. ??这种语法,是专门用来寻找非null或者非undefined的,比如null??1会返回1,1??undefined会返回1,&&和||是一类的,他们都根据左边的来返回结果。&&这种语法是左边为true,就拿右边的,左边为false,则拿左边的,||这种语法则是左边为true则拿左边的,左边为false则拿右边的。即&&理解起来应该是如果前面的条件满足,那么我们取后面的值,所以如果不在if的判断中时,通常&&右边的是一些可执行的逻辑,而||理解起来像是兜底的操作,所以不在if的判断中时,常见用来兜底。if的特点是,其中的条件为true则执行代码块里的内容,不为true则不执行。所以&&的机制导致了&&必须左右都为true,才满足,而||则是允许左边的为false,右边为true,或者左边的为true就直接满足if的判断了。所以||被称为都是false才是false,&&被称为都是true,才是true。
  5. vuex的getters的写法我现在还是感觉别扭,也许是为了和某种语言写法类似吧,

this.$store.state.模块名.属性名

this.$store.getters['模块名/属性名']

this.$store.commit('模块名/方法名',参数)

this.$store.dispatch('模块名/方法名',参数)

20240126收获_第1张图片

我还以为getters或者state可以怎么找到共同写法呢,结果发现根本不行。

还有要注意的是getters要写成

  getters:{
    test(){return '测试数据'}
  },

里面的数据要写成有返回值的函数。这就是和state的写法区别。

        6.find函数是要有返回值的。

        7.数组和对象很明显的一个区别在于[{name:'aa'}]这样的数组,想拿到name需要数组[0].name需要多加一个索引。

        8.之所以el-table接受的数据是数组类型的,因为el-table会自动进行遍历,所以我们写的代码实际上是数组的每一层的对象的渲染规则。

        9.之所以要在el-table中使用template,是因为存在我们需要对每一行的数据进行处理的情况,但是如果不通过作用域插槽,我们是无法拿到每一行的数据的。

        10.之所以我们能在el-table-column的标签内部使用插槽,是因为饿了么团队对于这个标签进行了处理,我们写的插槽会被替换到该列的数据渲染上去,同时,之所以scope.row能拿到该行的数据,那是因为饿了么团队将该数据给到了el-table-column这个组件,el-table这个组件能拿到数据,是因为我们在自己的组件页面中,通过我们自己的组件作用域使用了:data将数据给到了el-table的props里面。剩下的操作我就不知道他们具体咋做的了,反正他们实现了我们通过在表格列组件底下添加模板,我们就能拿到表格列组件传给我们组件的该行的数据。

        11.再次重申,html中一般不需要加this. 包括html标签上的诸如:attr="xx"或者是写在html的标签内部的诸如xxx,这些都是不需要加this.的。

        12.插槽首先要区分两个点,一个是传参,一个是内容,所谓传参,就是通过v-slot或者是#xx="{}"写在标签身上的,内容则是写在标签内部或者标签身上的。

原文来自作用域插槽看这一篇就够了-CSDN博客

20240126收获_第2张图片

这里红色框的,就是属于子组件传给父组件的内容,因为父组件只能用父组件的数据,子组件只能用子组件的数据,想要使用到对方的,只能通过交互。而这个v-slot就是专门给插槽做交互的,且方向是让父能够用到子的。然后之所以能接收到子组件传的值是因为子组件用了标签,这上面v-bind的属性,不知道vue团队用了什么方法,竟然将其弄到了#defaulte=xx右边的这个xx里面,从而父能够使用。

然后蓝色框的,都属于是父组件自己本身的数据,黄色的则属于父传子的数据,其源头也在父组件身上,只不过为了做交互给到子组件。这里黄色的,挺需要注意的,一旦形成了这种思维,再去看elementUI组件身上的各种属性,就能够慢慢去思考设计者的设计过程和思路。一举多得。

然后插槽还有一个要注意的,就是标签,还有一个作用是子组件身上用来作为出口的,让父组件写的内容在这里面显示,其实挺像router-view标签的。

然后慢慢深入的理解,就能明白这种组件作用域分隔的好处所在了,父用父的,子用子的,同名也不会影响,且写代码的时候逻辑清晰,渲染的时候都交给他们去忙就行,再可以深入思考的点就是如果让我们写这种组件之间的通信,我们怎么设计源码。

这里还可以加上的理解就是父子组件的生命周期,容我粗糙的模拟一下渲染过程,先执行父组件的beforeMount钩子,然后执行子组件的bm钩子,如果一开始把这些组件的值都分好层,或者做个什么隔离处理,子组件就能执行自己的程序,然后子组件挂载完毕,执行mounted钩子,里面代码走完,子组件暂时的生命周期完成,接下来跑到父组件的代码逻辑,父组件整整好,挂载好,此时子组件已经挂载在父组件里了,所以挂载好父组件后就可以执行mounted钩子了。

写着写着,我想到一个点额,之前看很多人都说请求放在created和mounted里面没什么大区别,我看这个父子组件的生命周期,是不是存在可能性,如果有父子组件,请求放在父组件的mounted中和created中是有可能出现不同的代码执行结果的。假如父要获取值,然后将值通过:属性传给子,如果写在mounted里面,会不会子拿不到值?目前我感觉有可能,等以后实际遇到了,可以回过头来再续写。

关于插槽,还有个细节,我看官网的内容,我发现如果子组件只有一个出口,那么v-slot:xx可以写在父组件的子标签身上,如果子组件有多个出口,官网是用的子组件内嵌了多个template实现的。其实想想也是,不用template分割开,怎么去对应各个出口。

20240126收获_第3张图片

        13.写的文字太多了,不得不另起一行了,总之收获挺多的,我发现饿了么团队这种设计挺秒的,在我们自己定义的vue组件中竟然能够很方便的使用el-table-column里面的组件,相当于爷爷组件用孙子组件,只需要我们使用template #default="scope"来接收他们传给我们的scope即可,如果我没理解错的话。再就是,他们写的孙子组件里面不知道是怎么做的,能够把我们给的数组拆分成对应行,然后将对应行的数据通过他们定义的scope给到我们。挺神奇的。

        14.20240126收获_第4张图片

这里父组件拿到的是一个对象,对象里面就是子组件的内容,即包装子组件内容这一步操作由vue帮我们做了,所以上面那篇文章里面是通过解构的方式来取的,原来如此。

        15.我现在就是还不清楚vue是怎么做到红框框这一步的

20240126收获_第5张图片

        16.20240126收获_第6张图片

这里就解释了,好像就是像函数传值一样传的,首先这里的红框框对我来说很重要,虽然说是说在标签内使用,但是实际上任何数据只要被我们拿到手了,只要有经过我们的手的这一步,数据想怎么用都随便我们,只不过这个变量只能标签内部使用。

然后这个我们调用A函数,然后传参数给A,结果这个参数里面有个B函数,相当于在写A函数的函数体的时候就要考虑给B函数传参,初看有一些怪怪的,仔细看,然后想一想,好像又能接受了。

其实MyComponent函数的定义就像子组件,该函数的使用就像父组件,值是从子组件传过去的,父组件使用。换成我们和饿了么UI就是他们来做MyComponent函数的定义,然后写文档告诉我们他们传了啥值,然后我们用的时候就取对应的值就好了。换过来,假如我们自己写组件,那就是我们想把什么数据分享,我们就传给default什么数据就好,写个文档,让用的人接收就好。

其实default这个函数从始至终都在MyComponent函数内部,感觉怪怪的原因在于d函数是在MC函数使用的时候创建,在MC函数创建的时候使用,感觉得需要点默契。

啊,好像明白了,这个MC函数的写法,我看了半天,总感觉和闭包的概念很相似,然后去查了下,果然就是闭包的写法,然后我之所以看着怪的原因在于我没看懂这段示例代码在抓子,看了半天,我好像明白这段代码的含金量了。

MyComponent({
  // 类比默认插槽,将其想成一个函数
  default: (slotProps) => {
    //假如在这个d函数体地方进行一些别的操作
    //比如准备将MC放在父组件中调用,因为实参是我们来设置的,
    //所以我们可以传入任意我们想传的父组件数据
    //比如将父组件作用域的变量丢进来进行模板字符串拼接。
    //然后等到函数真正执行的时候会将实参丢到MC函数体执行,从而将父组件中写在子组件内的内容带到
    //子组件里,从而通过vue的代码进行对应的操作,比如显示。
    //含金量太高了,对我来说。
    return `${slotProps.text} ${slotProps.count}`
  }
})

function MyComponent(slots) {
  const greetingMessage = 'hello'
  return `
${ // 在插槽函数调用时传入 props slots.default({ text: greetingMessage, count: 1 }) }
` }

这里面秒就妙在能够把子组件的内容greetingMessage给到d函数,然后用户在d函数里对于gM进行用户的操作,然后MC执行的时候能将d函数里面的操作带回来,然后根据vue团队最开始定义MC时候写的代码执行d函数以及vue团队自己的操作。有点儿像钓鱼的味道哈,鱼饵就是子给到父的数据,等我们执行MC函数的时候就是咬钩了,然后就回到钓鱼佬的回合了。这里面比较不那么好理解的点在于要分析的话我是从MC的定义开始的,后面又回到MC,就感觉有点怪怪的。如果先从MC的执行开始,经过d的定义,然后到MC的定义,又回到d的执行,也很怪。也就是说分析的路径会让我一下子反应不过来。

你可能感兴趣的:(vue.js,javascript,前端)