Vue常用命令(基础语法词典)

在这里插入图片描述
自己用来查阅的,实在是记不住,只能回头翻翻(学到新的就会更新)

vue基础-插值表达式

声明式渲染/文本插值

语法:{{ 表达式 }}

<template>
  <div>
    <h1>{{ msg }}</h1>
    <h2>{{ obj.name }}</h2>
    <h3>{{ obj.age>=18 ? '成年了':'未成年'}}</h3>
  </div>
</template>

<script>
export default {
  data() {
    return{
      msg:"hello,world",
      obj : {
        name:"zs",
        age:18
      }
    }
  }
}


</script>

<style>

</style>

vue指令-v-bind

目标:

给标签属性设置vue变量的值

vue指令, 实质上就是特殊的 html 标签属性, 特点: v- 开头

每个指令,都有独立的作用

语法:

v-bind:属性名=“vue变量”

简写:

:属性名=“vue变量”

<!-- vue指令 v-bind属性动态赋值 -->
    <a v-bind:href="url">我是a标签</a>
    <img src="imgsrc" alt="">

总结:

把vue变量的值,赋予给dom属性上,影响标签显示效果

vue指令-v-on

目标:

给标签绑定事件

语法:

v-on:事件名=“要执行的少量代码

v-on:事件名=“methods中的函数”

v-on:事件名=“methods中的函数(实参)”

简写:

@事件名=“methods中的函数”

<template>
  <div>
    <p>你要买商品的数量:{{count}}</p>
    <button v-on:click="count=count+1">增加1</button>
    <button v-on:click="addFn">增加1个</button>
    <button v-on:click="addcountFn(5)">增加5个</button>
    <button @click="subFn">减少</button>
  </div>
</template>

<script>
export default {
  data(){
    return{
      count:1,
    }
  },
  methods:{
    addFn(){
      this.count++
    },
    addcountFn(num){
      this.count += num
    },
    subFn(){
      this.count--
    }

  }
}
</script>

<style>

</style>

总结:

常用@事件名,给dom标签绑定事件,以及=右侧事件处理函数

vue指令-v-on事件对象

目标:

vue事件处理函数中,拿到事件对象

语法:

无参数,通过形参直接接收

有参数,通过 $event 指代事件对象传给事件处理函数

<template>
  <div>
    <a @click="one" href="http://www.baidu.com">阻止百度</a>
    <a @click="two(10,$event)" href="http://www.baidu.com">阻止去百度</a>
  </div>
</template>

<script>
export default {
  methods:{
    one(e){
      e.preventDefault();
    },
    two(num,e){
      e.preventDefault();
    }
  }

}
</script>

<style>

</style>

vue指令-v-on修饰符

目标:

在事件后面.修饰符名 - 给事件带来更强大的功能

语法:

@事件名.修饰符=“methods里的函数”

.stop - 阻止事件冒泡

.prevent - 阻止默认行为

.once - 程序运行期间,只触发一次事件处理函数

<template>
  <div @click="fatherFn">
    <button @click.stop="btn">.syop阻止事件冒泡</button>
    <a href="https://www.baidu.com" @click.prevent="btn">.prevent阻止默认行为</a>
    <button @click.once="btn">.once程序运行期间,只触发一次事件处理函数</button>
  </div>
</template>

<script>
export default {
  methods:{
    fatherFn(){
      console.log("father被触发了");
    },
    btn(){
      console.log(1);
    }
  }

}
</script>

<style>

</style>

总结:

修饰符给事件扩展额外功能

vue指令-v-on按键修饰符

目标:

给键盘事件,添加修饰符,增强能力

语法:

@keyup.enter - 监测回车按键

@keyup.esc - 监测返回按键

<template>
  <div>
    <input type="text" @keydown.enter="enterFn">
    <hr>
    <input type="text" @keydown.esc="escFn">
  </div>
</template>

<script>
export default {
  methods:{
    enterFn(){
      console.log("enter回车按键了");
    },
    escFn(){
      console.log("esc按键了");
    }
  }

}
</script>

<style>

</style>

总结:

多使用事件修饰符,可以提高开发效率,少去自己判断过程

vue指令 v-model

目标:

把value属性和vue数据变量,双向绑定到一起;

语法:

v-model=“vue数据变量”

双向数据绑定:

数据变化 —> 视图自动同步

视图变化 —> 数据自动同步

<template>
  <div>
      <!-- v-model:是实现vuejs变量和表单标签value属性,双向绑定的指令 -->
      <div>
          <span>用户</span>
      <input type="text" v-model="username">
      </div>
      
      <div>
          <span>密码</span>
      <input type="text" v-model="pass">
      </div>

      <div>
          <span>来自于:</span>
          <!-- 下拉菜单要绑定在select上 -->
          <select v-model="from">
     <option value="北京市">北京</option>
     <option value="南京市">南京</option>
     <option value="天津市">天津</option>
          </select>
      </div>

      <div>
           <!-- (重要)
      遇到复选框, v-model的变量值
      非数组 - 关联的是复选框的checked属性
      数组   - 关联的是复选框的value属性
       -->
          <span>爱好: </span>
          <input type="checkbox" v-model="hobby" value="画画">画画
          <input type="checkbox" v-model="hobby" value="听歌">听歌
          <input type="checkbox" v-model="hobby" value="看动漫">看动漫
      </div>

      <div>
          <span>性别:</span>
          <input type="radio" value="男" name="sex" v-model="gender">男
          <input type="radio" value="女" name="sex" v-model="gender">女
      </div>
      
      <div>
          <span>自我介绍</span>
          <textarea v-model="intro"></textarea>
      </div>
  </div>
</template>

<script>
export default {
    data(){
        return{
            username:"",
            pass:"",
            from: "",
            hobby: [], 
            sex: "",
            intro: "",
        };
        // 总结:
    // 特别注意: v-model, 在input[checkbox]的多选框状态
    // 变量为非数组, 则绑定的是checked的属性(true/false) - 常用于: 单个绑定使用
    // 变量为数组, 则绑定的是他们的value属性里的值 - 常用于: 收集勾选了哪些值
    }

}
</script>

<style>

</style>

总结:

本阶段 v-model 只能用在表单元素上,以后学组件后讲 v-model 高级用法

vue指令 v-model修饰符

目标:

让 v-model 拥有更强大的功能;

语法:

v-model.修饰符=“vue数据变量”

.number 以parseFloat转成数字类型

.trim 去除首尾空白字符

.lazy 在change时触发而非input时

<template>
   <div>
    <div>
      <span>年龄:</span>
      <!-- .number修饰符 -把值parseFloat转载数值再赋予给v-model对应的变量 -->
      <input type="text" v-model.number="age">
    </div>
    <div>
      <span>人生格言:</span>
      <!-- .trim修饰 -去除首尾两边空格 -->
      <input type="text" v-model.trim="motto">
    </div>
    <div>
      <span>自我介绍:</span>
      <!-- .lazy修饰符 -失去焦点内容改变时(onchange事件),把内容同步给v-model的变量 -->
      <textarea v-model.lazy="intro"></textarea>
    </div>
  </div>
</template>

<script>
export default {
     data() {
    return {
      age: "",
      motto: "",
      intro: ""
    }
  }
}
</script>

<style>

</style>

总结:

v-model修饰符,可以对值进行预处理,非常高效好用

vue指令 v-text和v-html

目标:

更新DOM对象的innerText / innerHTML

语法:

v-text=“vue数据变量”

v-html=“vue数据变量”

注意:

会覆盖插值表达式

<template>
   <div>
       <!-- v-text把值当成普通字符串显示 -->
    <p v-text="str"></p>
    <!--  v-html把值当做html解析 -->
    <p v-html="str"></p>
  </div>
</template>

<script>
export default {
    data(){
        return{
            str:"<span>我是一个span标签</span>"
        }
    }

}
</script>

<style>

</style>

总结:

v-text把值当成普通字符串显示,v-html把值当做html解析

vue指令 v-show和v-if

目标:

控制标签的隐藏或出现

语法:

v-show=“vue变量”

v-if=“vue变量”

原理:

v-show用的display:none隐藏 (频繁切换使用)

v-if 直接从DOM树上移除

高级:

v-else使用

<template>
  <div>
      <!-- 
          v-show或者v-if
          v-show="vue变量"
          v-if="vue变量"
          -->
      <h1 v-show="isOk">v-show的盒子</h1>
      <h1 v-if="isOk">v-if的盒子</h1>
      <!-- 
          v-show隐藏: 采用display:none //频繁切换
          v-if隐藏: 采用从DOM树直接移除 //移除
       -->

      <div>
          <p v-if="age">我成年了</p>
          <p v-else>还得多吃饭</p>
      </div>
  </div>
</template>

<script>
export default {
    data(){
        return{
            isOk:true,
            age:20
        }
    }
}
</script>

<style>

</style>

总结:

使用v-show和v-if以及v-else指令,方便通过变量控制一套标签出现/隐藏

vue指令-v-for

目标:

列表渲染,所在标签结构,按照数据数量,循环生成

语法:

v-for="(值,索引) in 目标结构"

v-for=“值 in 目标结构”

目标结构:

可以遍历数组/对象/数字/字符串(可遍历结构)

注意:

v-for的临时变量名不能用到v-for范围外

<template>
  <div id="app">
      <div id="app">
          <!-- v-for 把一组数据, 渲染成一组DOM -->
          <!-- 口诀: 让谁循环生成, v-for就写谁身上 -->
          <p>学生姓名</p>
          <ul>
              <li v-for="(item,index) in arr" :key="item">
                  {{index}}---{{item}}
              </li>
          </ul>

          <p>学生详细信息</p>
      <ul>
        <li v-for="obj in stuArr" :key="obj.id">
          <span>{{ obj.name }}</span>
          <span>{{ obj.sex }}</span>
          <span>{{ obj.hobby }}</span>
        </li>
      </ul>

      <!-- v-for遍历对象(了解) -->
      <p>老师信息</p>
      <div v-for="(value, key) in tObj" :key="value">
        {{ key }} -- {{ value }}
      </div>

      <!-- v-for遍历整数(了解) - 从1开始 -->
      <p>序号</p>
      <div v-for="i in count" :key="i">{{ i }}</div>
    </div>

  </div>
</template>

<script>
export default {
 data() {
    return {
      arr: ["小明", "小欢欢", "大黄"],
      stuArr: [
        {
          id: 1001,
          name: "孙悟空",
          sex: "男",
          hobby: "吃桃子",
        },
        {
          id: 1002,
          name: "猪八戒",
          sex: "男",
          hobby: "背媳妇",
        },
      ],
      tObj: {
        name: "小黑",
        age: 18,
        class: "1期",
      },
      count: 10,
    };
  },
}
</script>

<style>

</style>

总结:

vue最常用指令,铺设页面利器,快速把数据赋予到相同的dom结构上循环生成

vue基础 v-for更新监测

目标:

当v-for遍历的目标结构改变,Vue触发v-for的更新

情况1:数组翻转

情况2:数组截取

情况3:更新值

口诀:

数组变更方法,就会导致v-for更新,页面更新

数组非变更方法,返回新数组,就不会导致v-for更新,可采用覆盖数组或this.$set()

<template>
  <div>
    <ul>
        <li v-for="(val,index) in arr" :key="index
        ">
        {{val}}</li>
    </ul>
    <button @click="revBtn">数组翻转</button>
    <button @click="sliceBtn">截取前3个</button>
    <button @click="updateBtn">更新第一个元素值</button>
  </div>
</template>

<script>
export default {
    data(){
        return{
            arr:[5,3,9,2,1]
        }
    },
    methods:{
        revBtn(){
      // 1. 数组翻转可以让v-for更新
            this.arr.reverse()
        },
        sliceBtn(){
      // 2. 数组slice方法不会造成v-for更新
      // slice不会改变原始数组
      // this.arr.slice(0, 3)

      // 解决v-for更新 - 覆盖原始数组
            let newArr = this.arr.slice(0,3)
            this.arr = newArr
        },
        updateBtn(){
      // 3. 更新某个值的时候, v-for是监测不到的
      // this.arr[0] = 1000;

      // 解决-this.$set()
      // 参数1: 更新目标结构
      // 参数2: 更新位置
      // 参数3: 更新值
            this.$set(this.arr,0,1000)
        }
    }

}
</script>

<style>

</style>

这些方法会触发数组改变,v-for会监测到并更新页面:

push()

pop()

shift()

unshift()

splice()

sort()

reverse()

这些方法不会触发v-for更新:

slice()

filter()

concat()

注意:

vue不能监测到数组里赋值的动作而更新,如果需要请使用Vue.set() 或者this.$set(), 或者覆盖整个数组

总结:

改变原数组的方法才能让v-for更新

vue基础 动态class

目标:

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

语法:

:class="{类名:布尔值}"

<template>
  <div>
      <!-- 
          语法:
      :class="{类名: 布尔值}"
      使用场景: vue变量控制标签是否应该有类名
       -->
      <p :class="{red_str:bool}">动态class</p>
  </div>
</template>

<script>
export default {
    data(){
        return{
            bool:true
        }
    }

}
</script>

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

总结:

就是把类名保存在vue变量中赋予给标签

vue基础-动态style

目标:

给标签动态设置style的值

语法:

:style="{css属性: 值}"

<template>
  <div>
    <!-- 动态style语法
      :style="{css属性名: 值}"
     -->
    <p :style="{backgroundColor : colorStr}">动态style</p>
  </div>
</template>

<script>
export default {
  data(){
    return{
      colorStr:'red'
    }
  }

}
</script>

<style>

</style>

总结:

动态style的key都是css属性名

vue过滤器-定义使用

目标:

转换格式,过滤器就是一个函数,传入值返回处理后的值

过滤器只能用在, 插值表达式和v-bind表达式

Vue中的过滤器场景:

字母转大写,输入"hello",输出"HELLO"

字符串翻转,“输入hello,world”,输出"dlrow,olleh"

语法:

Vue.filter(“过滤器名”,(值) => {return"返回处理后的值"})

filters: {过滤器名字: (值) => {return “返回处理后的值”}

例子:

全局定义字母都大写的过滤器

局部定义字符串翻转的过滤器

<template>
  <div>
      <p >原来的样子:{{ msg }}</p>
      <!-- 2. 过滤器使用
      语法: {{ 值 | 过滤器名字 }}
     -->
      <p>使用翻转过滤器:{{ msg | reverse}}</p>
      <p :title="msg | toUp">鼠标长停</p>
  </div>
</template>

<script>
export default {
    data(){
        return{
            msg:'Hello,vue'
        }
    },
    // 方式2: 局部 - 过滤器
  // 只能在当前vue文件内使用
  /*
     语法: 
     filters: {
       过滤器名字 (val) {
         return 处理后的值
       }
     }
  */
    filters:{
        toUp(val){
            return val.toUpperCase()

        }
    }

}
</script>

<style>

</style>

总结:

把值转成另一种形式,使用过滤器,Vue3用函数替代了过滤器;

全局注册最好在main.js中注册,一处注册到处使用;

vue过滤器-传参和多过滤器

目标:

可同时使用多个过滤器,或者给过滤器传参

语法:

过滤器传参: vue变量 | 过滤器(实参)

多个过滤器: vue变量 | 过滤器1 | 过滤器2

<template>
  <div>
      <p >原来的样子:{{ msg }}</p>
      <!-- 1.
      给过滤器传值
      语法: vue变量 | 过滤器名(值)
     -->
      <p>使用翻转过滤器:{{ msg | reverse('|')}}</p>
       <!-- 2.
      多个过滤利使用
      语法: vue变量 | 过滤器1 | 过滤器2
     -->
      <p :title="msg | toUp | reverse('|')">鼠标长停</p>
  </div>
</template>

<script>
export default {
    data(){
        return{
            msg:'Hello,vue'
        }
    },
    // 方式2: 局部 - 过滤器
  // 只能在当前vue文件内使用
  /*
     语法: 
     filters: {
       过滤器名字 (val) {
         return 处理后的值
       }
     }
  */
    filters:{
        toUp(val){
            return val.toUpperCase()

        }
    }

}
</script>

<style>

</style>

总结:

过滤器可以传参,还可以对某个过滤器结果,后面在使用一个过滤器

vue计算属性-computed

目标:

一个数据,依赖另外一些数据计算而来的结果

语法:

computed:{
    "计算属性名"(){
      return "值"
    }
  }

需求:

求2个数的和显示到页面上

<template>
  <div>
    <p>{{ num }}</p>
  </div>
</template>

<script>
export default {
  data(){
    return{
      a:30,
      b:40
    }
  },
   // 计算属性:
  // 场景: 一个变量的值, 需要用另外变量计算而得来
  /*
    语法:
    computed: {
      计算属性名 () {
        return 值
      }
    }
  */
 // 注意: 计算属性和data属性都是变量-不能重名
 // 注意2: 函数内变量变化, 会自动重新计算结果返回
  computed:{
    num(){
      return this.a + this.b
    }
  }

}
</script>

<style>

</style>

注意:

计算属性也是vue数据变量,所以不要和data里重名,用法和data相同

总结:

一个数据,依赖另外一些数据计算而来的结果

vue计算属性-缓存

目标:
计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变,都直接从缓存取结果

在这里插入图片描述

<template>
<div>
  <p>{{ reverseMessage }}</p>
    <p>{{ reverseMessage }}</p>
    <p>{{ reverseMessage }}</p>
    <p>{{ getMessage() }}</p>
    <p>{{ getMessage() }}</p>
    <p>{{ getMessage() }}</p>
</div>
</template>

<script>
export default {
   data(){
    return {
      msg: "Hello, Vue"
    }
  },
  // 计算属性优势:
  // 带缓存
  // 计算属性对应函数执行后, 会把return值缓存起来
  // 依赖项不变, 多次调用都是从缓存取值
  // 依赖项值-变化, 函数会"自动"重新执行-并缓存新的值
  computed: {
    reverseMessage(){
      console.log("计算属性执行了");
      return this.msg.split("").reverse().join("")
    }
  },
  methods: {
    getMessage(){
      console.log("函数执行了");
      return this.msg.split("").reverse().join("")
    }
  }
}
</script>

<style>

</style>

总结:

计算属性根据依赖变量结果缓存,依赖变化重新计算结果存入缓存,比普通方法性能更高

vue计算属性-完整写法

目标:

计算属性也是变量,如果想要直接赋值,需要使用完整写法

语法:

computed:{
    "属性名":{
      set(值){
       
      },
      get(){
        return"值"
      }
    }
  }

需求:

计算属性给v-model使用

页面准备输入框

<template>
  <div>
    <div>
      <span>姓名:</span>
      <input type="text" v-model="full">
    </div>
  </div>
</template>

<script>
// 问题: 给计算属性赋值 - 需要setter
// 解决:
/*
    完整语法:
    computed: {
        "计算属性名" (){},
        "计算属性名": {
            set(值){

            },
            get(){
                return 值
            }
        }
    }
*/
export default {
  computed:{
    full:{
      // 给full赋值触发set方法
      set(val){
        console.log(val)
      },
      // 使用full的值触发get方法
      get(){
        return"无名氏"
      }
    }
  }

}
</script>

<style>

</style>

总结:

想要给计算属性赋值,需要使用set方法

vue侦听器-watch

目标:

可以侦听data/computed属性值改变

语法:

watch:{
    "被侦听的属性名"(newVal,oldVal){
     
    }
  }

完整例子代码:

<template>
  <div>
    <input type="text" v-model="name">
  </div>
</template>

<script>
export default {
  data(){
    return{
      name:""
    }
  },
   // 目标: 侦听到name值的改变
  /*
  语法:
    watch: {
      变量名 (newVal, oldVal){
        // 变量名对应值改变这里自动触发
      }
    }
  */
  watch:{
    // newVal: 当前最新值
    // oldVal: 上一刻值
    name(newVal,oldVal){
      console.log(newVal,oldVal);
    }
  }

}
</script>

<style>

</style>

总结:

想要侦听一个属性变化,可使用侦听属性watch

vue侦听器-深度侦听和立即执行

目标:

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

语法:

watch:{
    "要侦听的属性名":{
      immediate:true, //立即执行
      deep:true, //深度侦听复杂类型内变化
      handler(newVal,oldVal){
        
      },
    }
  }

完整例子代码:

<template>
  <div>
    <input type="text" v-model="user.name">
    <input type="text" v-model="user.age">
  </div>
</template>

<script>
export default {
  data(){
    return{
      user:{
        name:"",
        age:0
      }
    }
  },
     // 目标: 侦听对象
  /*
  语法:
    watch: {
      变量名 (newVal, oldVal){
        // 变量名对应值改变这里自动触发
      },
      变量名: {
        handler(newVal, oldVal){

        },
        deep: true, // 深度侦听(对象里面层的值改变)
        immediate: true // 立即侦听(网页打开handler执行一次)
      }
    }
  */
  watch:{
    user:{
      handler(newVal,oldVal){
        // user里的对象
        console.log(newVal,oldVal);
      },
      deep:true,
      immediate:true
    }
  }
}
</script>

<style>

</style>

总结:

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

vue组件_基础使用

目标:

每个组件都是一个独立的个体,代码里体现为一个独立的 .vue文件

口诀:

哪部分标签复用,就把哪部分封装到组件内

(重要):

组件内 template只能有一个根标签

(重要):

组件内data必须是一个函数,独立作用域

步骤:

1.创建组件:

封装标签+样式+js - 组件都是独立的, 为了复用;

2.注册组件:

创建后需要注册后再使用;

全局 - 注册使用

全局入口在 main.js , 在new Vue之上注册

语法:

import Vue from 'vue'
import 组件对象 from 'vue文件路径'

Vue.component("组件名",组件对象)

main.js -演示 案例:

// 目标: 全局注册 (一处定义到处使用)
// 1. 创建组件 - 文件名.vue
// 2. 引入组件
import Pannel from './components/Pannel'
// 3. 全局 - 注册组件
/*
  语法: 
  Vue.component("组件名", 组件对象)
*/
Vue.component("PannelG", Pannel)

全局注册 PannelG 组件名后,就可以当做标签在任意Vue文件中 template 里用;

单双标签都可以或者小写加 - 形式,运行后,会把这个自定义标签当做组件解析,使用组件里封装的标签替换到这个位置;

<PannelG></PannelG>
<PannelG/>
<pannel-g></pannel-g>

vscode会自动补全,爱用哪个用哪个

局部 - 注册使用

语法:

import 组件对象 from 'vue文件路径'

export default {
   component: {
      "组件名": 组件对象
   }
}

任意 vue文件中引入,注册,使用

案例:

<template>
  <div id="app">
    <h3>案例:折叠面板</h3>
    <!-- 4. 组件名当做标签使用 -->
    <!-- <组件名></组件名> -->
    <PannelG></PannelG>
    <PannelL></PannelL>
  </div>
</template>

<script>
// 目标: 局部注册 (用的多)
// 1. 创建组件 - 文件名.vue
// 2. 引入组件
import Pannel from './components/Pannel_1'
export default {
  // 3. 局部 - 注册组件
  /*
    语法: 
    components: {
      "组件名": 组件对象
    }
  */
  components: {
    PannelL: Pannel
  }
}
</script>

组件使用总结:

1.(创建)封装 html+css+vue到独立的 .vue文件中

2.(引入注册)组件文件 => 得到组件配置对象

3.(使用)当前页面当做标签使用

vue组件-scoped作用

目标:

解决多个组件样式名相同,冲突问题

需求:

div标签名选择器,设置背景色

问题:

发现组件里的div和外面的div都生效了

解决:

给Pannel.vue组件里 style标签上加上 scoped属性

<style scoped>

在style上加入 scoped属性,就会在此组件的标签上加上一个随机生成的data-v开头的属性

而且必须是当前组件的元素,才会有这个自定义属性,才会被这个样式作用到

总结:
style 上加 scoped,组件内的样式只在当前vue组件生效

vue组件通信_父向子-props

目标:

从外面给组件内传值,先学会语法,练习中在看使用场景

需求:

封装一个商品组件 MyProduct.vue ,外部传入具体要显示的数据

步骤:

1.创建组件 components/MyProduct.vue

2.组件内在props定义变量,用于接收外部传入的值

3.App.vue中引入注册组件,使用时,传入具体的数据给组件显示

案例:

components/MyProduct.vue - 准备标签

<template>
  <div class="my-product">
    <h3>标题: {{ title }}</h3>
    <p>价格: {{ price }}元</p>
    <p>{{ intro }}</p>
  </div>
</template>

<script>
export default {
  props: ['title', 'price', 'intro']
}
</script>

<style>
.my-product {
  width: 400px;
  padding: 20px;
  border: 2px solid #000;
  border-radius: 5px;
  margin: 10px;
}
</style>

App.vue中使用并传入数据

<template>
  <div>
    <!-- 
      目标: 父(App.vue) -> 子(MyProduct.vue) 分别传值进入
      需求: 每次组件显示不同的数据信息
      步骤(口诀):
        1. 子组件 - props - 变量 (准备接收)
        2. 父组件 - 传值进去
     -->
    <Product title="好吃的口水鸡" price="50" intro="开业大酬宾, 全场8折"></Product>
    <Product title="好可爱的可爱多" price="20" intro="老板不在家, 全场1折"></Product>
    <Product title="好贵的北京烤鸭" price="290" :intro="str"></Product>
  </div>
</template>

<script>
// 1. 创建组件 (.vue文件)
// 2. 引入组件
import Product from './components/MyProduct'
export default {
  data(){
    return {
      str: "好贵啊, 快来啊, 好吃"
    }
  },
  // 3. 注册组件
  components: {
    // Product: Product // key和value变量名同名 - 简写
    Product
  }
}
</script>

<style>

</style>

总结:

组件封装复用的标签和样式,而具体数据要靠外面传入

vue组件通信_父向子-配合循环

目标:

把数据循环分别传入给组件内显示

案例:

<template>
  <div>
    <MyProduct v-for="obj in list" :key="obj.id"
    :title="obj.proname"
    :price="obj.proprice"
    :intro="obj.info"
    ></MyProduct>
  </div>
</template>

<script>
// 目标: 循环使用组件-分别传入数据
// 1. 创建组件
// 2. 引入组件
import MyProduct from './components/MyProduct'
export default {
  data() {
    return {
      list: [
        {
          id: 1,
          proname: "超级好吃的棒棒糖",
          proprice: 18.8,
          info: "开业大酬宾, 全场8折",
        },
        {
          id: 2,
          proname: "超级好吃的大鸡腿",
          proprice: 34.2,
          info: "好吃不腻, 快来买啊",
        },
        {
          id: 3,
          proname: "超级无敌的冰激凌",
          proprice: 14.2,
          info: "炎热的夏天, 来个冰激凌了",
        },
      ],
    };
  },
  // 3. 注册组件
  components: {
    // MyProduct: MyProduct
    MyProduct
  }
};
</script>

<style>
</style>

在vue中需要遵循单向数据流原则

1.父组件的数据发生了改变,子组件会自动跟着变

2.子组件不能直接修改父组件传递过来的 props , props是只读的

父组件传给子组件的是一个对象,子组件修改对象的属性,是不会报错的,对象是引用类型,互相更新

总结:

props的值不能重新赋值,对象引用关系属性值改变,互相影响

vue组件通信_单向数据流

目标:

props变量本身是只读 , 不能重新赋值

从父到子的数据流向,叫单向数据流

原因:
子组件修改,不通知父级,造成数据不一致性

如果第一个MyProduct.vue内自己修改商品价格为5.5 , 但是App.vue里原来还记着18.8 ,数据 不一致 了

所以 Vue规定 props里的变量,本身是只读的

总结:

props变量本身是不能重新赋值的

问题:

怎么才能修改子组件接收到的值?

解决:

要影响父组件,然后数据响应式来影响子组件

vue组件通信_子向父

目标:

从子组件把值传出来给外面使用

语法:

  • 父: @自定义事件名=“父methods函数”
  • 子: this.$emit(“自定义事件名”,传值) -执行父methods里的函数代码

案例:

MyProduct_sub.vue

<template>
  <div class="my-product">
    <h3>标题: {{ title }}</h3>
    <p>价格: {{ price }}元</p>
    <p>{{ intro }}</p>
    <button @click="subFn">宝刀-砍1元</button>
  </div>
</template>

<script>
import eventBus from '../EventBus'
export default {
  props: ['index', 'title', 'price', 'intro'],
  methods: {
    subFn(){
      this.$emit('subprice', this.index, 1) // 子向父
      eventBus.$emit("send", this.index, 1) // 跨组件
    }
  }
}
</script>

<style>
.my-product {
  width: 400px;
  padding: 20px;
  border: 2px solid #000;
  border-radius: 5px;
  margin: 10px;
}
</style>

App.vue

<template>
  <div>
    <!-- 目标: 子传父 -->
    <!-- 1. 父组件, @自定义事件名="父methods函数" -->
    <MyProduct v-for="(obj, ind) in list" :key="obj.id"
    :title="obj.proname"
    :price="obj.proprice"
    :intro="obj.info"
    :index="ind"
    @subprice="fn"
    ></MyProduct>
  </div>
</template>

<script>

import MyProduct from './components/MyProduct_sub'
export default {
  data() {
    return {
      list: [
        {
          id: 1,
          proname: "超级好吃的棒棒糖",
          proprice: 18.8,
          info: "开业大酬宾, 全场8折",
        },
        {
          id: 2,
          proname: "超级好吃的大鸡腿",
          proprice: 34.2,
          info: "好吃不腻, 快来买啊",
        },
        {
          id: 3,
          proname: "超级无敌的冰激凌",
          proprice: 14.2,
          info: "炎热的夏天, 来个冰激凌了",
        },
      ],
    };
  },
  components: {
    MyProduct
  },
  methods: {
    fn(inde, price){
      // 逻辑代码
      this.list[inde].proprice > 1 && (this.list[inde].proprice = (this.list[inde].proprice - price).toFixed(2))
    }
  }
};
</script>

<style>
</style>

总结:

父自定义事件和方法,等待子组件触发事件给方法传值

vue组件通信-EventBus

目标:

常用于跨组件通信时使用

两个组件的关系非常的复杂,通过父子组件通讯是非常麻烦的.这时候可以使用通用的组件通讯方案:事件总线( event-bus )

核心语法:

EventBus/index.js -定义事件总线bus对象

import Vue from 'vue'
//导出空白vue对象
export default new Vue()

List.vue注册时间,等待接收要砍价的值,准备兄弟页面

<template>
  <ul class="my-product">
    <li v-for="(item, index) in arr" :key="index">
      <span>{{ item.proname }}</span>
      <span>{{ item.proprice }}</span>
    </li>
  </ul>
</template>

<script>
// 目标: 跨组件传值
// 1. 引入空白vue对象(EventBus)
// 2. 接收方 - $on监听事件
import eventBus from "../EventBus";
export default {
  props: ["arr"],
  // 3. 组件创建完毕, 监听send事件
  created() {
    eventBus.$on("send", (index, price) => {
      this.arr[index].proprice > 1 &&
        (this.arr[index].proprice = (this.arr[index].proprice - price).toFixed(2));
    });
  },
};
</script>

<style>
.my-product {
  width: 400px;
  padding: 20px;
  border: 2px solid #000;
  border-radius: 5px;
  margin: 10px;
}
</style>

MyProduct_sub.vue

<template>
  <div class="my-product">
    <h3>标题: {{ title }}</h3>
    <p>价格: {{ price }}元</p>
    <p>{{ intro }}</p>
    <button @click="subFn">宝刀-砍1元</button>
  </div>
</template>

<script>
import eventBus from '../EventBus'
export default {
  props: ['index', 'title', 'price', 'intro'],
  methods: {
    subFn(){
      this.$emit('subprice', this.index, 1) // 子向父
      eventBus.$emit("send", this.index, 1) // 跨组件
    }
  }
}
</script>

<style>
.my-product {
  width: 400px;
  padding: 20px;
  border: 2px solid #000;
  border-radius: 5px;
  margin: 10px;
}
</style>

总结:

空的Vue对象,只负责 o n 注 册 时 间 , on注册时间, on,emit触发事件,一定要确保$on先执行

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值