vue使用小技巧

2018-06-06  本文已影响0人  路耀广的前端微博

如何解决子组件属性设置在根元素上

应用场景:
当我们去调用组件时,会有一个需求是将一些属性传入子组件。当我们定义了props时,子组件可以接收这些属性并进行使用。但组件库的作者并不总能预见组件会被用于怎样的场景。组件可以接受任意的特性,而这些没有被定义当特性就会被添加到这个组件的根元素上。
例如:

 //父组件
  <template>
    <child test="呵呵哒" placeholder="呵呵呵" ></child>
  </template>
  <script>
   import child from "./child";
   export default {
    name: "App",
    components:{child}
   };
  </script>
    //子组件
  <template>
    <div class="child">
       <input type="text" :value="test" />
    </div>
  </template>
  <script>
    export default {
      name: "child",
      props: ["test"],
    };
</script>
上述代码执行后的结果为:

我们发现placeholder被加在了根元素上,如果我们想把placeholder加在input上该怎么做呢?
Vue有一个inheritAttrs的属性,可以在子组件上进行设置,配合$attrs的属性。我们就可以随心所欲的将自定义属性在任何元素上添加。

//子组件改造
<template>
    <div class="child">
        <input type="text" :value="test" v-bind="$attrs"/> <!--用v-bind来继承$attrs-->
    </div>
</template>
<script>
export default {
  name: "child",
  inheritAttrs:false,//禁用特性继承
  props: ["test"],
  data() {
    return {};
  }
};
</script>
改造过后我们就可以将placeholder放在input上,而不是根元素div上了。

class的绑定

应用场景:
当我们想指定某个class根据状态进行渲染,其余的class是默认直接渲染的时候,可以使用以下方法

<template>
  <div class="app">
    <p :class="[{red:isRed},'font32','bgBlue']">这是一段测试文本</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data(){
    return{
      isRed:true
    }
  }
};
</script>
<style>
  .red{
    color:red;
  }
  .font32{
    font-size: 32px;
  }
  .bgBlue{
    background: blue;
  }
</style>

对于未提前定义data变量的新增

应用场景:
Vue中data的变量是响应式的,即我们对变量进行了修改会触发对应视图的重新渲染。但是他有一个前提条件就是,我们需要提前在data中定义好这个变量才能在以后修改这个变量时触发相应。
但在开发时,我们有时候无法预见我们需要提前定义多少变量。当后端返回的某个数据我们需要在data中进行保存使用时,就无法实现响应式。
Vue为我们提供了一些API以对应这种场景的需要,但是需要注意的是,他只能对引用类型的变量进行使用,例如data{obj:{a:123}},而对于data{a:123}这种根属性是无法使用的。

<template>
  <div class="app">
    <p>{{foo.a}}</p>
    <p v-if="foo.b">{{foo.b}}</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data(){
    return{
      foo:{
        a:'这是a'
      }
    }
  },
  mounted(){
    setTimeout(()=>{
      //错误写法 无法被页面响应
      this.foo.b='这是b';
      //正确写法
      this.$set(this.foo,'b','这是b');
    },2000)
  }
};
</script>

这样的话,在2秒后,页面会渲染"这是b"这句话。

data数组的修改

应用场景:
当我们想对data里的数组进行修改时,可以借助Vue的变异方法
push(),pop(),shift(),unshift(),splice(),sort(),reverse()。或者非变异方法filter(), concat() 和 slice() 。
变异方法与非变异方法的区别在于,变异方法直接修改数组,而非变异方法返回新数组。
但是由于js的限制,vue无法修改以下数组:

 var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的

为了解决第一类问题,以下三种方式都可以实现和


Vue.set(vm.items, indexOfItem, newValue)

vm.items.splice(indexOfItem, 1, newValue)

vm.$set(vm.items, indexOfItem, newValue)

如果想要改变数组长度的话 可以

vm.items.splice(newLength)

v-model的使用

v-model只是vue的一个语法糖,v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。
v-model的使用有点类似于React的受控组件
当v-model作用在input或者textarea元素时,vue只是将input元素的value设置为绑定变量,并通过input元素的input事件将绑定变量的值修改为input元素的值。当我们添加了.lazy修饰符时,也只是将input事件改为了change事件

 <input type="text" v-model="foo"/>
  //其实就是
 <input  type="text" value="foo" @input="foo=this.value">

 <input type="text" v-model.lazy="foo"/>
  //其实就是
 <input  type="text" value="foo" @change="foo=this.value">

当v-model作用在radio元素时,vue会将value与绑定变量一致的radio设置为checked,触发change事件时,改变绑定变量的值为checked元素的value。

  <input type="radio" value="test1" v-model="foo"/>
  <input type="radio" value="test2" v-model="foo"/>
  //其实就是
  <input type="radio" value="test1" checked="this.value==foo" @change="foo=this.value">
  <input type="radio" value="test2" checked="this.value==foo" @change="foo=this.value">
上一篇下一篇

猜你喜欢

热点阅读