• 理理Vue细节


    理理Vue细节

    1. 动态属性名:可使用表达式来设置动态属性名或方法名:

    <!-- 属性name -->
    <a :[name]="url"> ... </a>
    <!-- 计算属性sss和s -->
    <img :[sss]="/img/test.png"/>  
    <!-- 方法change1和change2 -->
    <img :[change1()]="change2()"/>
    
    data: {
        name: 'href',
        sss: 'src'
    }

    注意:要避免空格和引号等,且需要小写,可使用计算属性来应对复杂表达式,都需要使用[]

    2. computed/methods/watch

    • computed可使用get/set
       computed: {
           top() {
               return 'top'
           },
           name: {
               get () {
                   return this.name
               },
               set (val) {
                   this.name = val
               }
           }
       }
     
    • computed可缓存,但不可传参,会根据data中的属性变化而变化,即是根据响应式依赖来变化,而Date不是响应式依赖,即不会变化;method则每次都会进行计算,但可传参。

    • watch用于处理异步或开销较大的操作,如输入搜索时。

    3. style绑定

    • 直接对象或变量对象
    • 计算属性
    • 直接style或style对象
    <!-- 属性名可加引号也可不加,属性小驼峰 -->
    <div :style="{ 'color': 'red', fontSize: fontSize + 'px' }">样式3</div>
    • 数组结合三目/数组结合对象
    data: {
      isActive: true,
      activeClass: 'active'
    }
    <!-- 使用数组时变量和字符串需要通过引号来区分 -->
    <div :class="[isActive ? activeClass : '', 'errorClass']"></div>
    <!-- 使用对象时类名不加引号可表示变量也可表示字符串 -->
    <div :class="[{ active: isActive }, 'errorClass']"></div>

    4. v-if条件渲染

    • 可使用template包裹元素,template会被当成不可见的包裹元素
    <template v-if="ok">
        <h1>Title</h1>
        <p>Paragraph 1</p>
        <p>Paragraph 2</p>
    </template>
    • 多条件判断
    <div v-if="type === 'A'">
      A
    </div>
    <div v-else-if="type === 'B'">
      B
    </div>
    <div v-else-if="type === 'C'">
      C
    </div>
    <div v-else>
      Not A/B/C
    </div>

    5. key

    • 添加key防止vue重复利用不想被重复利用的元素,如下的input如果不添加key,则vue会重复使用key,进而inputvalue值在切换后还会被保留,因为vue仅仅替换了placeholder
    <template v-if="loginType === 'username'">
      <label>Username</label>
      <input placeholder="Enter your username" key="username-input">
    </template>
    <template v-else>
      <label>Email</label>
      <input placeholder="Enter your email address" key="email-input">
    </template>

    6. v-if和v-show

    • v-if是组件的销毁和重建,如果初始条件为false,则什么都不做,直到变为真,所以切换开销高,运行条件很少改变时适用
    • v-showdisplay:noneblock之间的CSS切换,基于渲染,不管初始条件如何都会渲染,所以初始渲染开销高,切换频率高时适用

    7. v-for

    • 可使用in或者of
    • 也可遍历对象:v-for="(value, key, index) in obj"
    • 可根据template渲染多个组合元素:
    <ul>
      <template v-for="item in items">
        <li>{{ item.msg }}</li>
        <li class="divider"></li>
      </template>
    </ul>
     

    8. v-for和v-if

    • v-for优先级更高,所以v-if会重复运行于每个v-for循环中,所以尽量不要一起使用,可先使用计算属性对数据进行过滤再遍历。

    9. 更改响应式数据

    • Vue.set(object, key, value)
    • this.$set(object, key, value)
    • this.items.splice(index, 1, newValue)
    • 批量添加属性:
    // 不要直接Object.assign(this.items, {age: 18}
    this.items = Object.assign({}, this.items, {
      age: 18,
      favoriteColor: 'Vue Green'
    })

    10. 事件修饰符

    • .passive:滚动的默认事件会立即出发,即告诉浏览器不想阻止默认事件的触发,可提升移动端性能
    <div :scroll.passive="onScroll">...</div>
     
    • .capture:添加事件监听器时使用事件捕获模式,即元素自身触发的事件先在此处理,然后才交由内部元素进行处理
    • .self:只当在 event.target 是当前元素自身时触发处理函数,即事件不是从内部元素触发的
    • .once:点击事件只会触发一次
    • 键盘修饰符: <input v-on:keyup.enter="submit"> 

    11. v-model

    • 选择框
    <!-- 单选框时,picked为字符串 "a",不是布尔值 -->
    <input type="radio" value="a" v-model="picked">
    
    <!-- 多选框时,toggle默认值设为字符串或布尔值时得到布尔值,设为数组时得到的是value值-->
    <input type="checkbox" value="b" v-model="toggle">
    
    <!-- 当选中第一个选项时,selected为字符串value的值 "abc" -->
    <select v-model="selected">
      <option value="abc">ABC</option>
    </select>
    • 修饰符.lazy:在change时而非input时更新 <input v-model.lazy="msg" >

    注:change事件是在input失去焦点时触发,即用于单选、多选框和选择框,而input事件是在value值变化时触发,但脚本改变value值时不会触发,即用于text和textarea

    • 修饰符.number:输入值转为数值
    • 修饰符.trim:过滤收尾空白字符

    12. Prop

    • 使用v-bind="obj"会将对象的每个属性都作为一个独立的prop传入进去,所以接受时也需要逐个属性接收。
    <test v-bind="obj"></test>
    • props虽然是单向数据流,但对于引用类型,子组件还是可以改变父组件的状态。
    • props会在组件实例创建之前进行验证,所以实例的属性再defaultvalidator中是不可用的。

    13. 自定义事件

    • 自定义事件需要注意事件名为小写或-分隔,因为$emit('BaseEvent')虽然事件名不会变,但在html中该事件名会被转化为小写,不会监听到。

    14. slot

    • 具名插槽
    <base-layout>
      <template v-slot:header>
        <h1>Here might be a page title</h1>
      </template>
    <!-- 默认插槽也可不用加上template和v-slot -->
      <template v-slot:default>
        <p>A paragraph for the main content.</p>
        <p>And another one.</p>
      </template>
      <template v-slot:footer>
        <p>Here's some contact info</p>
      </template>
    </base-layout>
     
    • 作用域插槽
    <!-- current-user组件 -->
    <span>
      <slot :user="user">
        {{ user.lastName }}
      </slot>
    </span>
    
    <!-- 父级组件通过自定义名称访问子级作用域 -->
    <current-user>
      <template v-slot:default="slotProps">
        {{ slotProps.user.firstName }}
      </template>
    </current-user>
    
    <!-- 支持缩写和解构 -->
    <current-user>
      <template #default="{ user = { firstName: Gust } }">
        {{ user.firstName }}
      </template>
    </current-user>
     

    15. 组件通信

    • vuex/eventBus
    • prop/$emit
    • $children/$parent
    • provide/inject
    • $refs
    // 父或祖先级
    provide: function () {
      return {
        getMap: this.getMap
      }
    }
    
    // 后代级
    inject: ['getMap']
     

    16. scope

    • scoped 属性会自动添加一个唯一的属性 (比如 data-v-21e5b78) 为组件内 CSS 指定作用域,编译的时候 .list-container:hover 会被编译成类似 .list-container[data-v-21e5b78]:hover

    17. 路由

    • 区分:this.$router指路由器,this.$route指当前路由

    • 通配符:捕获所有路由或 404 Not found路由

      // 含通配符的路由都要放在最后,因为优先级由定义顺序决定
    {
      // 会匹配所有路径
      path: '*'
    }
    {
      // 会匹配以 `/user-` 开头的任意路径
      path: '/user-*'
    }
     
    • 当使用一个通配符时,$route.params内会自动添加一个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分:
    // 给出一个路由 { path: '/user-*' }
    this.$router.push('/user-admin')
    this.$route.params.pathMatch // 'admin'
    // 给出一个路由 { path: '*' }
    this.$router.push('/non-existing')
    this.$route.params.pathMatch // '/non-existing'
    • 点击 <router-link :to="..."> 等同于调用 router.push(...)方法,因为<router-link>会在内部调用该方法,进而在history栈添加一个新的记录

    • 使用了push时,如果提供的path不完整,则params会被忽略,需要提供路由的 name 或手写完整的带有参数的 path

    const userId = '123'
    router.push({ name: 'user', params: { userId }})  // -> /user/123
    router.push({ path: `/user/${userId}` })          // -> /user/123
    // 这里的 params 不生效
    router.push({ path: '/user', params: { userId }}) // -> /user
     
    • router.push/router.replace/router.go 效仿于 window.history.pushState/window.history.replaceState/window.history.go

    • 命名视图:router-view可设置名字,如果router-view没有设置名字,那么默认为 default

    <router-view></router-view>
    <router-view name="a"></router-view>
    <router-view name="b"></router-view>
    
    const router = new VueRouter({
      routes: [
        {
          path: '/',
          components: {
            default: Foo,
            a: Bar,
            b: Baz
          } 
        }
      ]
    })
     
    • 路由使用props:可将路由参数设置为组件属性
    const User = {
      props: ['id'],
      template: '<div>User {{ id }}</div>'
    }
    // 通过布尔值设置
    const router = new VueRouter({
      routes: [
        { path: '/user/:id', component: User, props: true },
    
        // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
        {
          path: '/user/:id',
          components: { default: User, sidebar: Sidebar },
          props: { default: true, sidebar: false }
        }
      ]
    })
    
    // 通过函数设置query 
    // URL /search?q=vue 会将 {name: 'vue'} 作为属性传递给 SearchUser 组件
    const router = new VueRouter({
      routes: [
        { path: '/search', component: SearchUser, props: (route) => ({ name: route.query.q }) }
      ]
    })
     
    • beforeRouteEnter:可使用beforeRouteEnter来提前获取接口数据,同时需要在next后才能访问到实例:
    beforeRouteEnter(to, from, next) {
      axios('/text.json').then(res => {
        next(vm => {
          vm.datas = res
        })
      })
    }
     
    • 路由设置有参数时,如果跳转页面后再通过返回键返回时,路由会保留有参数,如果通过push跳转返回,则不会保留该参数,这在第三方调用模块传参时需要注意。

    18. loader

    • Vue Loader编译单文件的template块时,会将所有遇到的URL资源转为webpack模块请求:
    // <img src="../image.png">将会被编译成为:
    createElement('img', {
      attrs: {
        src: require('../image.png') // 现在这是一个模块的请求了
      }
    })
    • 资源URL转换规则
    1. 如果是绝对路径,例如 /images/foo.png),则会原样保留。
    2. 如果路径以.开头,将会被看作相对的模块依赖,并按照你的本地文件系统上的目录结构进行解析。
    3. 如果路径以~开头,其后的部分将会被看作模块依赖。
    4. 如果路径以 @ 开头,也会被看作模块依赖。

    后续会持续更新,欢迎关注!



    转载链接:https://juejin.im/post/5cb444605188251ada7e320d
  • 相关阅读:
    方法集锦3_字符串_python
    171. 乱序字符串
    149. 买卖股票的最佳时机(回顾)
    150. 买卖股票的最佳时机 II
    平方根的计算
    平方根的计算
    对话Roadstar投资人:一家自动驾驶公司之死(三) ...
    对话Roadstar投资人:一家自动驾驶公司之死(三) ...
    Axure遮罩 or 灯箱
    Axure遮罩 or 灯箱
  • 原文地址:https://www.cnblogs.com/taohuaya/p/10714827.html
Copyright © 2020-2023  润新知