v-text和v-html,条件显示v-show实现折叠面板和v-if和v-else和v-else-if搭配,,v-for的的key和更新概念,条件控制样式

415 阅读2分钟

内容大类还有过滤器,计算属性,案例练习--品牌管理

1.v-text和v-html

1.v-text 把内容作为文本直接显示

2.v-html 解析html显示 (就是以前js的字符串拼接的innerText和innerHTML的作用)

代码演示如下

<template>
  <div>
    <!-- v-text: 作用,设置标签内容 -->
    <!-- 语法: v-text="变量" -->
    <!-- 变量声明在data方法返回对象里 -->
    <!-- v-text把内容作为文本直接显示,不解析内容 -->
    <h1 v-text="hello"></h1>
    <h1 v-text="helloHTML"></h1>
    <!-- v-html:作用,设置标签内容为HTML -->
    <!-- 语法:v-html="变量" -->
    <!-- 变量声明在data方法返回对象里 -->
    <!-- v-html会解析内容中的html标签 -->
    <h1 v-html="helloHTML"></h1>
    <h1 v-html="hello"></h1>
  </div>
</template>
<script>
export default {
  data() {
    return {
      hello: "hello world",
      helloHTML: "<button>点我</button>"
    }
  }
}
</script>

<style>

</style>

2.条件显示v-show和v-if

1.v-show 原理:控制display: none属性

2.v-if 原理:是否删除元素

代码演示如下

<template>
  <div>
    <!-- v-show -->
    <!-- 作用:控制标签显示和隐藏 -->
    <!-- v-show语法,v-show="表达式" -->
    <!-- v-show通过控制display: none属性来控制显示隐藏 -->
    <h1 v-show="age >= 18">成年人的快乐</h1>
    <h1 v-show="age < 18">给你一瓶营养快线</h1>
    <h1>v-if</h1>
    <!-- v-if -->
    <!-- 作用:控制标签显示和隐藏 -->
    <!-- v-if语法:v-if="表达式" -->
    <!-- v-if通过控制是否插入标签来显示隐藏 -->
    <h2 v-if="age < 18">给你甜甜圈</h2>
    <h2 v-if="age >= 18">快乐水</h2>
  </div>
</template>
<script>
export default {
  data() {
    return {
      age: 27,
    };
  },
};
</script>

<style>
</style>

2-1. v-if可以和v-else和v-else-if搭配使用

还是跟以前的判断语句一样 if 或者else if 再或者 else

代码演示如下

<template>
  <div>
    <!-- v-if和v-else可以搭配使用 -->
    <!-- v-if和v-else必须是相邻节点 -->
    <h2 v-if="age < 18">给你甜甜圈</h2>
    <h2 v-else>快乐水</h2>
    <!-- v-if可以和多个v-else-if搭配使用,实现多个条件控制 -->
    <!-- 多个条件控制可以使用v-else结尾 -->
    <!-- v-else是可选的 -->
    <input type="text" v-model.number="age">
    <h2 v-if="age < 18">甜甜圈</h2>
    <h2 v-else-if="age < 60">快乐水</h2>
    <h2 v-else-if="age < 100">脑白金</h2>
    <h2 v-else>冬虫夏草</h2>
  </div>
</template>

<script>
export default {
  data() {
    return {
      age: 8,
    };
  },
};
</script>

<style>
</style>

3.案例练习---折叠面板

用v-show实现

代码演示如下

<template>
  <div>
    <!-- 第一步,先静后动,先实现静态的效果,把诗的标题、按钮、内容显示出来 -->
    <h1 class="text-center">案例:折叠面板</h1>
    <h2>
      静夜思
      <!-- 第二步,处理动态逻辑,给按钮绑定事件 -->
      <!-- 第五步,设置按钮文案 -->
      <button @click="toggle">{{ show ? "收起" : "展开" }}</button>
    </h2>
    <!-- 第三步,控制内容显示,使用v-show或者v-if -->
    <div v-show="show">
      <p>床前明月光</p>
      <p>疑是地上霜</p>
      <p>举头望明月</p>
      <p>低头思故乡</p>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      show: true,
    };
  },
  methods: {
    toggle() {
      // 第四步 在事件内部控制内容显示
      // 使用了取反运算
      this.show = !this.show;
    },
  },
};
</script>
<style>
.text-center {
  text-align: center;
}
</style>

4.v-for的一些更新概念

会让v-for触发更新的两类型数组方法

1.不会修改原始数组的方法不会导致v-for更新

(1.)array.filter:因为它是过滤数组生成一个新的数组,不会修改原始数组,所以不会触发更新
例:arr=[1,2,3,4] arrs=arr.filter(item=>item>2) 此时过滤出一个新数组[3,4]
(2.)array.slice(开始下标位置,结束下标位置)开始是从零开始,结束不会切当前的数组数据:
例:[1,2,3,4].slice(0,3) 会返回一个新的数组[1,2,3],所以不会修改原始数组,所以不会触发更新

2. 修改原始数组的方法会导致v-for更新

(1)array.push(插入的内容):在原始数组末端插入,会改变原始数组
例:arr=[1,2,3,4] arr.push(8) 原数组会变成[1,2,3,4,8] 所以导致v-for更新
(2)array.reverse() 数组倒转,会改变原始数组
例:["h","e","l","l","o"].reverse() 原本数组会变成["o","l","l","e","h"] 所以导致v-for更新

3.array[index] = value 不会触发更新 $set(数组, 索引, 值)会触发更新

4-1.v-for的就地更新

在上一次的列表上逐条修改,就是对比历史的列表,一样的就不变,不一样的就修改

4-2.v-for的key的作用

1.根据key查找元素,定位和更新在

2.key优化性能

5.条件控制样式

1.class

语法::class="{ 类名: 布尔值 }" 如果类名有横线,加引号

代码如下

<template>
  <div>
    <!-- 动态设置class -->
    <!-- :class="{ 类名: 布尔值 }" -->
    <!-- 布尔值为true,标签增加类名,为false的时候删除类名 -->
    <!-- 可以控制多个类 -->
    <button :class="{ on: isOn, off: !isOn }" @click="fn">开关</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      isOn: false,
    }
  },
  methods: {
    fn() {
      this.isOn = !this.isOn;
    },
  }
}
</script>
<style>

.off {
  background-color: grey;
}
.on {
  background-color: red;
}
</style>

2.style

语法::style="{ 样式属性名: 合法的样式值 }" 如果样式名有横线,加引号或者小驼峰

代码如下

<template>
  <div>
    <!-- 动态设置样式 -->
    <!-- :class="{ 类名: 布尔值 }",类名如果包含横线-,采用引号 -->
    <!-- 动态设置style -->
    <!-- :style="{ 样式名: 样式的值 }",样式名如果带横线,改为小驼峰,也可以使用引号 -->
    <button
      @click="fontColor = 'blue'"
      :style="{ color: fontColor, 'font-size': '60px' }"
      :class="{ 'text-center': true, textTop: true }"
    >
      变色
    </button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      fontColor: "red",
    };
  },
};
</script>
<style>
</style>

6.案例练习--品牌管理

实现的功能:用vue实现了新增数据,根据id删除数据,转化年月日格式,同级总价和均价功能等等
实现用到的技术:用到了过滤器实现总价和均价,moment第三方包转化年月日格式,用v-for遍历生成页面,css样式使用第三方bootstrap框架实现的,用v-model双向绑定输入框的value加v-on绑定点击事件实现新增,用v-on绑定点击事件和获取到到id加数组方法实现删除功能,用v-show判断没人内容的时候显示没有数据提示等等

代码如下

<template>
  <div class="container">
    <div class="row">
      <div class="col-12 pt-3">
        <table class="table table-bordered">
          <thead>
            <tr>
              <th scope="col">编号</th>
              <th scope="col">资产名称</th>
              <th scope="col">价格</th>
              <th scope="col">创建时间</th>
              <th scope="col">操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(item, index) in list" :key="item.id">
              <th scope="row">{{ item.id }}</th>
              <td>{{ item.name }}</td>
              <td :class="{ expensive: item.price > 100 }">{{ item.price }}</td>
              <td>{{ item.time }}</td>
              <td>
                <!-- 第一步,找到删除按钮,绑定事件 -->
                <!-- 第二步,绑定事件获取要删除的元素索引 -->
                <button
                  type="button"
                  class="btn btn-link"
                  @click="deleteProduct(index)"
                >
                  删除
                </button>
              </td>
            </tr>
            <tr class="bg-light">
              <th scope="row">统计</th>
              <td colspan="2">总价:0</td>
              <td colspan="2">均价:0</td>
            </tr>
          </tbody>
          <!-- 第四步,控制空状态的显示 -->
          <tfoot v-show="list.length === 0">
            <tr>
              <td class="text-center" colspan="5">暂无数据</td>
            </tr>
          </tfoot>
        </table>
      </div>
    </div>

    <form class="row align-items-center">
      <div class="col-3">
        <input
          type="text"
          class="form-control"
          placeholder="资产名称"
          v-model="productName"
        />
      </div>

      <div class="col-3">
        <input
          type="text"
          class="form-control"
          placeholder="价格"
          v-model.number="productPrice"
        />
      </div>

      <div class="col-3">
        <button
          type="submit"
          class="btn btn-primary"
          @click.prevent="addProperty"
        >
          添加资产
        </button>
      </div>
    </form>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      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"),
        },
      ],
      productName: "",
      productPrice: 0,
    };
  },
  methods: {
    addProperty() {
      if (!this.productName || !this.productPrice) {
        alert("资产名称和价格不能为空");
        return;
      }
      // 第五步,处理空数据情况下的新增逻辑异常
      let id;
      if (this.list.length > 0) {
        id = this.list[this.list.length - 1].id + 1;
      } else {
        id = 100;
      }
      this.list.push({
        id,
        name: this.productName,
        price: this.productPrice,
        time: new Date(),
      });
    },
    deleteProduct(index) {
      // 第三步,删除元素
      console.log(index);
      this.list.splice(index, 1);
    },
  },
};
</script>

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

7.过滤器

作用:转换格式

语法:{{ 表达式 | 过滤器1 | 过滤器2(参数1) }}

过滤器声明:(1)Vue文件data同级的filters属性里

(2)main.js,Vue.filter('过滤器名', 方法)

方法注意点:1.记得返回数据

2.方法第一个参数:表达式内容

3.传给方法的参数从第二个开始

4. 要注意main.js文件和vue文件的方法名冲突

代码演示如下

<template>
  <div>
    <!-- 过滤器作用:转换数据格式 -->
    商品价格:{{ price | priceFilter }}
    <h2>{{ "hello" | toUpperCase }}</h2>
    <!-- 过滤器能使用在插值表达式和v-bind属性里 -->
    <!-- title跟hove效果差不多 -->
    <p :title="'hello vue' | toUpperCase">hello vue</p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      price: 9,
    };
  },
  // 声明在data同级下的filters对象里
  // 声明在filters内的过滤器只能在当前vue文件使用
  filters: {
    // 过滤器要声明为方法
    // 表达式的值是过滤器的第一个参数
    priceFilter(num) {
      return `${num < 10 ? "0" + num : num}¥`;
    },
    toUpperCase(value) {
      return value.toUpperCase();
    },
  },
};
</script>
<style>
</style>
在main.js文件的代码如下
// 过滤器第一个参数是传入的值,一般是表达式的值,我们传给过滤器的参数从第二个开始
Vue.filter("moneyFilter", function (value, unit, unit2) {
  return `${value} ${unit}${unit2 || ''}`;
});

8.计算属性

ta是什么:根据一些变量运算出来的属性

ta的好处:缓存计算结果,只有依赖项变化才会重新运算

语法:{{ 变量 }}

声明在: data同级的computed对象内

计算属性方法要返回值 就是要return

完整写法:计算属性: { get() {}, set(value) { } }

普通写法如下

<template>
  <div>
    <!-- 计算属性,作用:根据一些数据计算出来一个属性 -->
    <!-- 当计算属性依赖的数据变化的时候,计算属性会重新运算 -->
    <!-- 计算属性是作为变量使用的,不要使用括号的语法 -->
    <!-- 计算属性不能和data里的变量重名 -->
    <h1>{{sum}} = {{a}} + {{b}}</h1>
    a: <input type="text" v-model.number="a">
  </div>
</template>
<script>
export default {
  data() {
    return {
      a: 10,
      b: 20,
    };
  },
  // 计算属性声明在data同级的computed对象里
  computed: {
    // 计算属性声明为方法
    sum() {
      return this.a + this.b;
    }
  },
}
</script>
<style>
</style>

9.单选控制全选,全选关联单选案例

就用到了计算属性的完整写法: { get() {}, set(value) { } }

单选全选中的时候,全选的选择也会被勾上,反正全选勾上,单选也要全部勾上,代码如下

<template>
  <div>
    <p>全选:<input type="checkbox" v-model="isAll" /></p>
    <ul>
      <li v-for="item in list" :key="item.id">
        <input type="checkbox" v-model="item.checked" />
        {{ item.name }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: [
        {
          id: 1,
          name: "猪八戒",
          checked:false,
        },
        {
          id: 2,
          name: "孙悟空",
           checked:false,
        },
        {
          id: 3,
          name: "唐僧",
           checked:false,
        },
        {
          id: 4,
          name: "沙僧",
           checked:false,
        },
      ],
    };
  },
  computed: {
    isAll: {
      set(index) {
        this.list.forEach((item) => {
          item.checked = index;
        });
      },
      get() {
        let all=true;
        this.list.forEach((item) => {
        if(item.checked===false){
            all = false
        }
        });
        return all;
      },
    },
  },
  created() {},
  mounted(){},
  methods: {},
};
</script>

<style scoped lang="less"></style>