必须掌握vue_基础API

103 阅读4分钟

vue基础-动态class

用v-bind给标签设置动态的值

语法:

  • 格式1:<标签 :class="变量" />
  • 格式2:<标签 :class="{类名1: 布尔值, 类名2: 布尔值}" />
    • 如果布尔值为true,就添加对应的类名

说明:可以和静态class共存

<template>
  <div id="app">
    <h3>15-动态绑定class.vue</h3>
    <p :class="type"> p的内容 class="变量"</p>
    <p :class="['red', 'f40']"> p的内容 class="数组"</p>
    <p class="abc" :class="{red:true, blue:true, f40:true}"> p的内容 class="数组"</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
     type: 'blue'
    }
  }
}
</script>

<style>
.abc {background-color: #ccc;}
.f40 {font-size: 40px;}
.blue {color:blue}
.red {color:red}

 body {
  background-color: #ccc;
 }
  #app {
    width: 400px;
    margin: 20px auto;
    background-color: #fff;
    border: 4px solid blueviolet;
    border-radius: 1em;
    box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
    padding: 1em 2em 2em;
  }
</style>

vue基础-动态style

给标签动态设置style的值

语法

<标签 :style="{css属性名: 值}" />

  1. 可以和静态style共存
  2. 样式中带-属性写成小驼峰
<template>
  <div id="app">
    <h3>16-动态绑定style.vue</h3>
    <p style="border: 1px solid red" :style="obj"> p的内容 :style="对象"</p>
    <button @click="fn">设置随机设置字体大小</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
     obj:{
       backgroundColor: '#ccc',
       color: "red",
       fontSize: '40px'
     }
    }
  },
  methods: {
    fn(){
      const fs = Math.random() * 100
      this.obj.fontSize = fs + 'px'
    }
  }
}
</script>

<style>
.abc {background-color: #ccc;}
.f40 {font-size: 40px;}
.blue {color:blue}
.red {color:red}

 body {
  background-color: #ccc;
 }
  #app {
    width: 400px;
    margin: 20px auto;
    background-color: #fff;
    border: 4px solid blueviolet;
    border-radius: 1em;
    box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
    padding: 1em 2em 2em;
  }
</style>

计算属性

使用场景 如果一个结果需要依赖data中的数据,但是需要经过一些逻辑处理,才能得到你想要的数据。此时就可以使用计算属性。 例如:要对给定的字符串做翻转处理之后再来显示

定义格式 在vue实例中,补充computed配置项。

{
    data(){},
    methods: {}
    // 声明计算属性
    computed: {
        //属性名字(计算属性名称)
        //属性的值(计算属性处理函数)
        计算属性名1 () {
            // 对依赖的数据进行处理,且进行return
            return 
        },
        计算属性名2 () {
            // 对依赖的数据进行处理,且进行return
            return 
        }
    }
}

computed 是vue的配置选项,它的值是一个对象,其中可定义多个计算属性,每个计算属性就是一个函数。

  • 属性名称: 计算属性的名称
  • 属性的值:计算属性的素材函数
    • 对需要依赖的数据,进行逻辑上的处理

    • 处理完毕后,需要return出去,返回的值就是计算属性的值

    使用格式

在两个地方使用:

  • 模板
    • 用插值表达式 {{计算属性名}}
    • 用其它指令
  • 在实例内
    • this.计算属性名
  <div id="app">
    <!-- 逻辑复杂 -->
    <h3>{{msg.split('').reverse().join('')}}</h3>
    <!-- 计算属性 和data类似-->
    <h3>{{reverseMsg}}</h3>
  </div>
  <script src="./vue.js"></script>
  <script>
     {
      data () {
        return { msg: 'hi vue' }
      },
      // 声明计算属性
      computed: {
        //属性名字(计算属性名称)
        //属性的值(计算属性处理函数)
        reverseMsg () {
          // 对依赖的数据进行处理,且进行return
          return this.msg.split('').reverse().join('')
        }
      }
    })
  </script>
  • 在模板中使用计算属性,和使用data的方式是一样的。
    • 虽然在计算属性中声明的是函数,但是在模板中使用,当中数据来使用,不需要加括号。

总结:

  • 什么时间用:需要对数据进行复杂的逻辑加工,产生新的数据时。
  • 定义: 就是一个特殊的配置项computed。其中有多个函数。
  • 使用:计算属性的使用方式与data中的数据项一致;
    • 计算属性-计算:这个值是对原数据进行计算之后得到的新的数据
    • 计算属性-属性:它的使用方法与原数据一样。this.计算属性名,{{计算属性名}}
  • 执行的时机: 如果计算属性中依赖的数据项变化时,它会自动调用。

其实在模板中来显示一份经过对数据项进行复杂计算之后的结果时,我们有两种解决方案:

  1. 计算属性
  2. 函数

函数: methods定义函数,如果在模板中使用,每使用一次,就相当于调用了一次,处理逻辑会重新执行。

计算属性: computed定义计算属性,如果在模板中使用,使用多次,但是如果以来的数据不发生改变,计算属性对应的函数不会重新执行。

计算属性会做缓存,提高渲染的性能

<div id="app">
    <h3>计算属性</h3>
    <p>计算属性:{{ reversedMsg }}</p>
    <p>计算属性:{{ reversedMsg }}</p>
    <p>计算属性:{{ reversedMsg }}</p>
    <hr>
    <p>函数:{{fReversedMsg()}}</p>
    <p>函数:{{fReversedMsg()}}</p>
    <p>函数:{{fReversedMsg()}}</p>
</div>
<script>
    // 计算属性的特点:缓存
    //  - 如果计算属性所依赖的数据项并没有发生变化,则就算使用多个计算函数,其函数也只执行一次
    //    因为它把结果缓存起来了。

    {
        data() {
            return { msg: 'javascript' }
        },
        methods: {
            updateMsg () {
                    this.msg = "abc"
          // 由于计算属性有缓存,虽然在页面上用到三次,但它的函数体只执行一次。
        // 对于普通的函数,在页面上用到了三次,它就会执行三次
            },
            fReversedMsg () {
                console.log( '函数 fReversedMsg' )
                //把msg的翻转一下
                let newMsg = this.msg.split('').reverse().join('')
                return newMsg
            }
        },
        computed: {
            reversedMsg () {
                console.log( 'reversedMsg' )
                //把msg的翻转一下
                let newMsg = this.msg.split('').reverse().join('')
                return newMsg
            }
        }
    })
</script>

总结:

  • 计算属性有缓存,提高渲染性能。
  • 如果在页面上需要用到 对现有的数据进行加工得到新数据,则时要使用计算属性

计算属性的完整写法

Snipaste_2022-05-05_15-39-07.png 计算属性也是变量, 如果想要直接赋值, 需要使用完整写法=>开启读写模式

computed: {
    "属性名": {
        set(){
            
        },
        get() {
            return "值"
        }
    }
}
  • 计算属性给v-model使用
<template>
  <div>
    <div>
      <span>名字:</span>
      <input type="text" v-model="full">
    </div>
  </div>
</template>

<script>
export default {
 data () {
    return {
      msg: 'full'
    }
  },
  computed: {
    full: { 
      get(){ // 获取full的值
        console.log("get方法触发");
        return this.msg
      },
      set(val){ // 要给full赋值
        console.log(val)
        this.msg = val
      }
    }
  }
}
</script>

过滤器filters

作用

{
    data(){},
    computed:{},
    methods:{},
    // 定义过滤器
    filters: {
      // 属性名称(过滤器名称):属性的值(过滤器处理函数)
      myFilter:function(value,其它参数){
           return 过滤后的结果
      }
    }
}

使用格式:

// 不带参数
{{ msg | 过滤器}}
// 带参数
{{ msg | 过滤器(参数)}}

监听属性 watch

监听复杂类型, 或者立即执行监听函数

watch: {
    "要监听的属性名": {
        immediate: true, // 立即执行
        deep: true, // 深度监听复杂类型内变化
        handler (newVal, oldVal) {
            
        }
    }
}
<template>
  <div id="app">
    <div class="container">
      <!-- 顶部搜索框模块 -->
      <div class="form-group">
        <div class="input-group">
          <h4>品牌管理</h4>
        </div>
      </div>

      <!-- 数据表格 -->
      <table class="table table-bordered table-hover mt-2">
        <thead>
          <tr>
            <th>编号</th>
            <th>资产名称</th>
            <th>价格</th>
            <th>创建时间</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(item, index) in list" :key="item.id">
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>

            <!-- 如果价格超过100,就有red这个类 -->
            <td :class="{ red: item.price > 100 }">{{ item.price }}</td>
            <td>{{ item.time  | fulTime }}</td>
            <td><a href="#" @click="doDel(index)">删除</a></td>
          </tr>
          <tr style="text-align: center">
            共计:{{
              doFoach
            }}
            平均值:{{
              doSum / list.length
            }}
          </tr>
        </tbody>
        <tfoot>
          <tr>
            <td colspan="5" style="text-align: center" v-show="!list[0]">
              暂无数据
            </td>
          </tr>
        </tfoot>
      </table>

      <!-- 添加资产 -->
      <form class="form-inline">
        <div class="form-group">
          <div class="input-group">
            <input
              v-model.trim="good.name"
              type="text"
              class="form-control"
              placeholder="资产名称"
            />
          </div>
        </div>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <div class="form-group">
          <div class="input-group">
            <input
              v-model.number="good.price"
              type="text"
              class="form-control"
              placeholder="价格"
            />
          </div>
        </div>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <!-- 阻止表单提交 -->
        <button class="btn btn-primary" @click.prevent="doAdd">添加资产</button>
      </form>
    </div>
  </div>
</template>

<script>
import "bootstrap/dist/css/bootstrap.css";
import moment from "moment";
export default {
  data() {
    return {
      good: {
        name: "", // 名称
        price: 0, // 价格
      },
      list: JSON.parse(localStorage.getItem('list')) || [
        { id: 100, name: "外套", price: 199, time: new Date('2010-08-12')},
        { id: 101, name: "裤子", price: 34, time: new Date('2013-09-01') },
        { id: 102, name: "鞋", price: 25.4, time: new Date('2018-11-22') },
        { id: 103, name: "头发", price: 19900, time: new Date('2020-12-12') }
      ]
    };
  },
  methods: {
    //删除数组里面的对象
    doDel(index) {
      this.list.splice(index, 1);
    },
    // 添加对象
    doAdd() {
      // 解构
      const { good, list } = this;
      if (good.name == "") return;
      // 1.声明id
      let id = list.length ? list[list.length - 1].id + 1 : 1;
      //2.创建一个对象
      let obj = {
        id,
        name: good.name,
        price: good.price,
        time: new Date(),
      };
      // 3.将这个对象添加到数组当中
      list.push(obj);

      good.name = "";
      good.price = "";
    },

  },
  computed: {
    doFoach() {
      let sum = 0;
      this.list.forEach((item) => {
        sum += item.price;
      });
      return sum;
    },
    doSum() {
      return this.list.reduce((sum, item) => sum + item.price, 0);
    },
    avg() {
      return this.doSum / this.list.length;
    },
  },
  filters:{
    fulTime(value){
      return moment(value).format('YYYY-MM-DD')
    }
  },
  // 侦听器
  watch:{
    list:{
      deep:true,
      handler(newVal,oldVal){
        localStorage.setItem('list',JSON.stringify(newVal))
      }
    }
  }
};
</script>

<style >
.red {
  color: red;
}
</style>

immediate立即监听, deep深度监听, handler固定方法触发