VUE学习

Vue

(2.6版本)

  • 渐进式框架(主张最少)
  • 安装
    • 官网:https://cn.vuejs.org/
    • 开发版:

Vue组件特点

  1. 组件式开发【组件相当于零件,页面功能由多个零件开发】
  2. SPA单页面应用程序
  3. 渐进式开发【主张最少】(用多少功能就安装多少模块,所以很轻量化)
  4. 声明式编码,让编码人员无序操作DOM,提高开发效率

Vue的缺点

  • 不利于SEO【页面上的所有内容都是通过JS动态渲染的,页面查看源代码看不到HTML代码】

如何解决Vue不利于SEO的问题

SSR【服务端渲染】:在服务端提前生成好要展示的HTML结构,首次加载页面的时候就展示出来。

声明式渲染

<body>
    // 1.创建一个Vue实例挂载的容器
    <div id='app'>
    	{{name}}-{{age}}
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
	// 2. 创建Vue实例对象
   	let vm = new Vue({
        el:'#app',	// 实例要挂载到哪里
        data:{	// 要挂载的多种数据
            name:'frank',
            age:20,
            sex:'男'
        }
    })
</script>
在浏览器修改:vm.name = '王五'

属性绑定

bind:绑定

  <body>
    <!-- 创建一个Vue实例的挂载容器 -->
    <div id="my_vue">
      <!-- v-dind: 使元素的属性值为js后端传递来的-->
      <a href="#" v-bind:title="value">lalala</a>
      <!-- v-dind:简写形式--直接在属性名称前加冒号 -->
      <img src="#" :alt="value" />
    </div>
  </body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    new Vue({
      el: "#my_vue",
      data: {
        value: "欢迎你",
      },
    });
  </script>

条件渲染

v-if与v-show不同之处?

  • v-show是通过display属性去切换效果的,v-if是通过删除和创建标签实现的
  • 初始加载时,如果同样是false,v-if根本不创建标签,v-show仍然要创建标签,然后再把它隐藏
  • 场景:频繁切换用v-show,否则用v-if

v-if指令:如果为true则当前元素显示

  <body>
    <!-- 创建一个Vue实例的挂载容器 -->
    <div id="my_vue">
      <!-- v-if指令:如果isShow为true则显示,否则不显示 -->
      <h1 v-if="isShow">111</h1>
      <h1 v-if="!isShow">222</h1>
      <!-- v-else指令:不能独立显示,与上一个同级v-if指令对应 -->
      <h1 v-else>333</h1>

      <!-- 复杂的if-else结构 -->
      <h1 v-if='leval=="A"'></h1>
      <h1 v-else-if='leval=="B"'></h1>
      <h1 v-else></h1>

      <!-- v-show指令:效果与v-if效果相同,只是实现效果的方式不同 -->
      <h1 v-show="isShow">777</h1>
      <h1 v-show="!isShow">888</h1>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script>
    let vm = new Vue({
      el: "#my_vue",
      data: {
        isShow: true, // 111,333,777显示
        leval: "A", // 优
      },
    });
  </script>

事件触发

  <body>
    <div id="add">
      <div v-show="isShow">{{name}}</div>
      <!-- v-on指令:事件触发 -->
      <button v-on:click="isShow=!isShow">切换</button><br />
      <!-- v-on简写形式 -->
      <button @click="reverseTitle()">翻转</button>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script>
    let vm = new Vue({
      el: "#add",
      data: {
        name: "我叫张三",
        isShow: true,
      },
      methods: {
        reverseTitle(title, isShow) {
          // 在函数中获取数据(title,isShow)
          // this指向Vue的实例对象vm
          this.name = this.name.split("").reverse().join("");
        },
      },
    });
  </script>

Vue实例对象

  • Vue实例代理了data属性下的所有子属性,用起来更方便(vm.data.XXX == vm.XXX)

Watch监听

<body>
    <div id='app'>
        <h1>
            {{count}}
        </h1>
        <button @click='add'>
            点击Count + 1
        </button>
    </div>
</body>
<script>
new Vue({
	el:'#app',
	data:{
		count:1
	},
    methods:{
        add(){
            this.count++
        }
    }
    watch:{
    // 监听count,watch的函数名就叫count
    	count(new,old){
    		console.log(new);
    		console.log(old);
		}
	}
})
</script>

v-model(双向数据绑定)

一般和表单一起使用

v-model是v-model:value的简写形式

v-model只能用于表单标签

  <body>
    <div id="app">
      <h1>{{name}}*{{num}}</h1>
      <button @click="gogo">+++</button><br />
      <input type="text" v-model="role" />
    </div>
  </body>
  <script>
    new Vue({
      el: "#app",
      data: {
        name: "斩尽牛杂",
        num: 1,
        role: "刻晴",
      },
      methods: {
        gogo() {
          this.num++;
        },
      },
      watch: {
        // 浅监听,只能监听一层数据,如果对象内部的属性发生变化,他是无法监听的
        num(newValue, oldValue) {
          console.log(newValue);
          console.log(oldValue);
        },
        // 深监听,可以监听对象内部的属性变化
        role: {
          deep: true,
          handler(newValue) {
            console.log(newValue);
          },
        },
      },
    });
  </script>

数组响应式

  • 数组操作不要用[]形式
  • 只能用数组的几种方法啦操作数据:pop(),push(),unshift(),shift(),splice()
  <body>
    <div id="app">
      <h1>{{name}}</h1>
    </div>
  </body>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        name: ["张三", "李四", "王五"],
      },
    });
    // 数组的操作不要使用[]
    vm.name[0] = "冯八";
    // 只能用数组的几种方法啦操作数据:pop(),push(),unshift(),shift(),splice()
    // vm.name.splice(0, 2, "马六", "赵七");
  </script>

Set

  • 响应式:在JS对数据做的操任何作,页面会即使响应
  • 给data里面的对象添加一个响应式的新属性要用$set才可以
  <body>
    <div id="app">
      <h1>{{ys.name}}-{{ys.sex}}-{{ys.age}}</h1>
      <button @click="addAge">添加年龄</button>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      el: "#app",
      data: {
        ys: {
          name: "刻晴",
          sex: "女",
        },
      },
      methods: {
        addAge() {
          // 只能给data里的对象添加新属性,不能直接给data添加新属性
          this.$set(this.ys, "age", 17);
        },
      },
    });
  </script>

$mount

  • 延时挂载
  • el与 m o u n t 挂载相同, e l 最终还是调用 mount挂载相同,el最终还是调用 mount挂载相同,el最终还是调用mount进行挂载的
  <body>
    <div id="app"><h1>{{name}}</h1></div>
  </body>
  <script src="../vue.js"></script>
  <script>
    let vm = new Vue({
      data: {
        name: "李四",
      },
    }).$mount("#app");

v-text / v-html

  <body>
    <!-- v-html:类似于innerHtml;v-text:类似于innerText -->
    <div id="app">
      <!-- 李四 -->
      <p v-text="name"></p>
      <!-- 李四 -->
      <p v-html="name"></p>
      <!-- <b>王五</b> -->
      <p v-text="name1"></p>
      <!-- 加粗的'王五'-->
      <p v-html="name1"></p>
      <!-- 李四 -->
      <p>{{name}}</p>
      <!-- <b>王五</b> -->
      <p>{{name1}}</p>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    let vm = new Vue({
      data: {
        name: "李四",
        name1: "<b>王五</b>",
      },
    }).$mount("#app");
  </script>

计算属性

  • 意义不同;watch是一系列操作,计算属性目的是做一些简单的计算
  • 异步请求:watch可以,计算属性不可以
  • 缓存效果:计算属性有,watch没有
  <body>
    <div id="app">
      <p>原名:{{name}}</p>
      <p>翻转:{{reversename}}</p>
      <p>原数组:{{arr}}</p>
      <p>偶数:{{everArr}}</p>
      <p>小于3的数:{{x_Arr}}</p>
      <button @click="getNum">原数</button>
      <button @click="setNum">变化</button>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    let vm = new Vue({
      data: {
        name: "ok gogo",
        arr: ["1", "2", "3", "4", "5", "6"],
        a: 4,
      },
      computed: {
        // 单纯获取计算属性的值
        reversename() {
          return this.name.split("").reverse().join("");
        },
        everArr() {
          return this.arr.filter((item) => item % 2 == 0);
        },
        x_Arr() {
          return this.arr.filter((item) => item < 3);
        },
        // 可以设置计算属性的值,也可以获取
        my_Num: {
          set(newValue) {
            this.a = newValue;
          },
          get() {
            return this.a * 10;
          },
        },
      },
      methods: {
        getNum() {
          // 读取计算属性
          console.log(this.my_Num);
        },
        setNum() {
          // 修改计算属性
          this.my_Num = 5;
        },
      },
    }).$mount("#app");
  </script>

类样式(绑定样式)

    <style>
      .classA {
        background-color: pink;
      }
      .classB {
        font-weight: bold;
      }
      .classC {
        color: blue;
      }
      .classD {
        color: yellowgreen;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <!-- 对象形式 -->
      <p :class="name">大家好,才是真的好。</p>
      <!-- 数组形式 -->
      <p :class="name1">风驰天下,大运摩托。</p>
      <button @click="reverse">交换</button>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    let vm = new Vue({
      data: {
        name: {
          classA: true,
          classB: true,
          classC: true,
        },
        name1: ["classA", "classB", "classD"],
      },
      methods: {
        reverse(){
          this.name.classC == this.$set(this.name,'classD',true)
        }
      },
    }).$mount("#app");
  </script>

行内样式

  <body>
    <div id="app">
      <p :style="{color:'red'}">啦啦啦</p>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    let vm = new Vue().$mount("#app");
  </script>

列表渲染

mounted:开局自执行

  <body>
    <div id="app">
      <!-- 无序列表 -->
      <ul>
        <!-- v-dind:key 作用:确定元素唯一性,提高更新虚拟DOM的效率,提高性能 -->
        <!-- v-for:遍历数组 -->
        <li v-for="(value,index) in name" :key="index">{{index}}-{{value}}</li>
      </ul>
      <ul>
        <li v-for="(value,index) of name" :key="index">{{index}}-{{value}}--</li>
      </ul>
      <ul>
        <li v-for="(value,index) in name1" :key="index">{{index}}-{{value}}</li>
      </ul>



      <!-- 有序列表 -->
      <ol>
        <li v-for="i in 10">{{i}}</li>
      </ol>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    let vm = new Vue({
      data: {
        name: ["张三", "李四", "王五"],
        name1: [],
      },
      mounted() {
        // 模拟ajax
        setTimeout(() => {
          this.name1 = [1, 2, 3, 4, 5];
        }, 1000);
      },
    }).$mount("#app");
  </script>

$refs

  <body>
    <div id="app">
      <input type="text" ref="name" />
      <button @click="gogo">提交</button>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      data: {},
      methods: {
        gogo() {
          console.log(this.$refs.name.value);
        },
      },
    }).$mount("#app");
  </script>

常用的几个事件修饰符

  • .stop:阻止事件冒泡
  • .prevent:组织元素的默认行为
  • .self:只对元素事件本身触发有效,对子节点触发无效
  • once:只触发一次
  • capture:采用事件捕获模式
  <body>
    <div id="app">
      <!-- .stop阻止事件冒泡 -->
      <div @click="a1" style="background-color: yellowgreen">
        <div @click.stop="a2" style="background-color: pink; width: 100px">
          123
        </div>
      </div>

      <!-- .prevent:阻止事件的默认行为 -->
      <form action="app.html" @submit.prevent>
        <button>提交</button>
      </form>

      <div @click.self="b1">
        <div @click="b2" style="background-color: pink; width: 100px">拉卡打开</div>
      </div>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      el: "#app",
      data: {},
      methods: {
        a1() {
          console.log("parent");
        },
        a2() {
          console.log("student");
        },
        b1() {
          console.log('BB');
        },
        b2() {
          console.log('bb');
        },
      },
    });
  </script>

vue提供的几个键盘修饰符

.enter 回车键
.esc 退出键
.space 空格键
.up 上
.down 下
.right 右
.left 左
.delete 删除键+退格键
.tab 制表符键

  <body>
    <div id="app">
      <input type="text" @keyup.once.enter="gogo" />
      <input type="text" @keydown.enter="gogo" />
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      el: "#app",
      data: {},
      methods: {
        gogo() {
          console.log("粗发");
        },
      },
    });
  </script>

v-modol(双向数据绑定)

  <body>
    <div id="app">
      <input
        type="text"
        v-model="look"
        placeholder="最基础的数据双向绑定"
      />{{look}}
      <hr />
      性别
      <label><input type="radio" value="" v-model="message.sex" /></label>
      <label><input type="radio" value="" v-model="message.sex" /></label>

      <hr />
      爱好
      <label><input type="checkbox" value="羽毛球" v-model="message.love" id="" />羽毛球</label>
      <label><input type="checkbox" value="乒乓球" v-model="message.love" id="" />乒乓球</label>
      <label><input type="checkbox" value="排球" v-model="message.love" id="" />排球</label>
      <br>
      <button @click='gogo'>提交</button>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      data: {
        look: "",
        message: {
          sex: "男",
          love:['羽毛球']
        },
      },
      methods:{
        gogo(){
          console.log(this.message);
        }
      }
    }).$mount("#app");
  </script>

修饰符

  • .lazy修饰符:让v-model从原来的oninput事件变成onchange事件(change:改变)(变懒)
  • .number修饰符:将内容自动转换为数字类型
  • .trim修饰符:去掉字符串亮两边的空格
  <body>
    <div id="app">
      <!-- lazy(懒):v-model只在失去焦点后执行 -->
      <input type="text" v-model.lazy="my_lazy" />{{my_lazy}}
      <br>
      <!-- .number:将v-model输入的值转化为数字类型 -->
      <input type="number" v-model.number='my_number' @change='gogo'>{{my_number}}
      <br>
      <input type="text" v-model.trim='my_trim'>{{my_trim}}
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      el: "#app",
      data: {
        my_lazy: "",
        my_number:null,
        my_trim:''
      },
      methods:{
        gogo(){
          console.log(this.my_number);
        }
      }
    });
  </script>

组件的创建

  • 全局组件:在任何一个vue实例挂载的容器中使用(一次写一个)
  • 局部组件:只能在当前vue实例挂载的容器中使用(可以创建多个)
  • 组件中任然可以使用之前的data,methods,computed,watch,但是data这里要改成一个函数,并且必须要return一个{}出来
  • components:组件
  <body>
    <div id="app">
      <go></go>
      <login></login>
    </div>
    <div id="ppa">
      <gogo></gogo>
      <login></login>
    </div>
  </body>
  <script src="../vue.js"></script>
  <script>
    // 全局组件可以在全部的Vue实例中使用
    Vue.component("login", { template: "<p>这是全局的</p>" });
    new Vue({
      el: "#app",
      // 局部组件
      components: {
        go: {
          template: '<a href="#">这是app局部的</a>',
        },
      },
    });

    new Vue({
      el: "#ppa",
      components: {
        gogo: {
          template: '<a href="#">这是ppa局部的</a>',
        },
      },
    });
  </script>

脚手架工具@vue/cli3

  1. 全局安装:npm install -g @vue/cli
  2. 版本检查:vue -V
  3. 装: vue create 名字
  4. 启动:npm run serve

组件之间信息的传递?

  • 给子组件传递数据
    • 如果是变量,记得给属性名前加v-bind指令
    • 如果是字符串,直接传递即可
子组件:
<template>
  <div>
    <!-- 5. 将获得的内容展示在页面上 -->
    <h1>{{ title }}</h1>
    <p v-for="(index, value) in list" :key="index">{{ value }}</p>		
  </div>
</template>

<script>
export default {
  name: "Main",
  // 子组件接受父组件给的数据
  // props: ["list", "title"],  // 方法一

  // 方法二:带有验证性质的
  props: {	// 4. 从父组件获得内容
    list: {
      type: Array,
      // 必须传入
      required: true,
      // 自定义验证器
      validator(value) {
        return value.length >= 3;
      },
    },
    title: {
      type: String,
      // 默认值
      default:'Hello LSH'
    },
  },
};
</script>

父组件:
<template>
  <div>
    <Header></Header>
    <Main :list="list" title="hello"></Main>	<!-- 3. 将获得的值放入转化后的组件中 -->
    <Footer></Footer>
  </div>
</template>

<script>
import Main from "../components/Main.vue";	// 1. 引入子组件
export default {
  name: "home",
  data() {
    return {
      list: ["面条", "米饭", "肉"],
    };
  },
  components: {
    Main,	// 2. 将子页面转换为父页面的组件
  },
};
</script>

组件之间的通信

父传子

1.在父组件中嵌套子组件

2.在父组件的template中使用子组件标签

3.在子组件中使用props接收数据

4.接收之后,可以在子组件中自由的使用,但是不能修改

子传父

父元素
<template>
  <div>
    <Show :myText="list"></Show>
    <!-- 3. 设置自定义事件,获得参数 -->
    <Index @newTodo="addTodo($event)"></Index>
  </div>
</template>

<script>
import Index from "./components/Input.vue";
import Show from "./components/Show.vue";
export default {
  name: "todos",
  data() {
    return {
      // 1. 声明接收变量
      list: [],
    };
  },
  methods: {
    // 2. 给父元素创建一个函数,获得的数据来自子元素
    addTodo(title) {
      this.list.push({ title, done: false });
    },
  },
  components: {
    Index,
    Show,
  },
};
</script>
<style scoped lang="scss"></style>

子元素
<template>
  <div>
    <input type="text" v-model="text" /><br />
    <button @click="gogo">上传</button>
  </div>
</template>

<script>
export default {
  name: "Input",
  data() {
    return {
      text: null,
    };
  },
  methods: {
    gogo() {
      // 4. 触发自定义事件,并且传参
      this.$emit("newTodo", this.text);
      console.log(this.text);
      this.text = "";
    },
  },
};
</script>
<style scoped lang="scss"></style>

sync

父组件
<template>
  <div>
    {{ bar }}
    <!-- 1. 在自定义事件后加 .sync,他就会自动添加一个自定义事件:updata:aaa   (aaa指:自定义事件名) -->
    <Children :aaa.sync="bar"></Children>
  </div>
</template>

<script>
import Children from "./components/add.vue";
export default {
  name: "Index",
  data() {
    return {
      bar: "父组件",
    };
  },
  components: {
    Children,
  },
};
</script>
<style scoped lang="scss"></style>

子组件
<template>
  <div>
    <button @click="gogo">改变</button>
  </div>
</template>

<script>
export default {
  name: "add",
  methods: {
    gogo() {
      // 调用updata:aaa事件,并且可以直接传参,这里参数用于修改bar的值
      this.$emit("update:aaa", "大家好");
    },
  },
};
</script>
<style scoped lang="scss"></style>

事件总线

  1. 创建一个独立的Vue实例XXX,并且导出
  2. 通过XXX.$on(‘自定义事件名’,回调函数)
  3. 在另一个组中,XXX.emit(‘自定义事件名’,‘参数’)
声明一个js文件,传出一个独立的Vue实例

// 事件总线
import Vue from 'vue'
export default new Vue()

父组件,作用:引入子组件
<template>
  <div>
    <A></A>
    <B></B>
  </div>
</template>

<script>
import A from "./components/A.vue";
import B from "./components/B.vue";
export default {
  name: "Index",
  components: {
    A,
    B,
  },
};
</script>
<style scoped lang="scss"></style>

子组件A :监听,绑定事件
<template>
  <div>{{ eat }}</div>
</template>

<script>
import event from "../../../assets/eventBus";
export default {
  data() {
    return {
      eat: "下午吃啥?",
    };
  },
  mounted() {
    // let aaa = this;  // 如果不使用箭头函数,可以将this交给一个变量
    event.$on("eat", (need) => {
      console.log(need);
      this.eat = need;
    });
  },
};
</script>
<style scoped lang="scss"></style>

组件B :触发事件
<template>
  <div>
    <button @click="gogo">下午吃啥</button>
  </div>
</template>

<script>
import event from "../../../assets/eventBus";
export default {
  methods: {
    gogo() {
      event.$emit("eat",'超级肉夹馍');
    },
  },
};
</script>
<style scoped lang="scss"></style>

provide/inject(后代之间数据传递)

  • provide:提供
  • inject:注入
爷爷组件 :用于暴露数据
<template>
  <div>
    爷爷组件
    <two></two>
  </div>
</template>

<script>
import two from "./two.vue";
export default {
  name: "one",
  // 将定义的值暴露给后代组件
  data() {
    return {};
  },
  provide: {
    name1: "父亲组件",
    name2: "儿子组件",
  },
  mounted() {
    this.name1 = "123";
    console.log(this.name1);
  },
  components: {
    two,
  },
};
</script>
<style scoped lang="scss"></style>

父亲组件 :获取爷爷组件暴露的内容
<template>
  <div>
    {{name1}}
    <three></three>
  </div>
</template>

<script>
import three from './three.vue'
export default {
  name:'two',
  // 获得祖先暴露的值
  inject:['name1'],
  components:{
    three
  }
}

</script>
<style scoped lang='scss'>
</style>

儿子组件 :获取爷爷组件暴露的内容
<template>
  <div>{{ name2 }}</div>
</template>

<script>
export default {
  name: "three",
  // 获得祖先暴露的值
  inject: ["name2"],
};
</script>
<style scoped lang="scss"></style>

内容分发(插槽)

  • 有名字的与具名插槽相互匹配
  • 没名字的都进入默认插槽
  • 在子组件中,定义一些数据給父组件使用的叫做作用于插槽
  • slot:插槽
父组件
<template>
  <div>
    父组件
    <Children>
      <a href="http://www.baidu.com">百度</a>
      <!-- 根据slot值,插入到对应名称的插槽中 -->
      <a href="#" slot="yh">雅虎</a>
      <a href="#" slot="zh">知乎</a>
      <a href="#" slot="tb">淘宝</a>
      <a href="#" slot="jd">京东</a>

      <template slot="zyy" slot-scope="props">{{props.text}}</template>
    </Children>
  </div>
</template>

<script>
import Children from "./children.vue";
export default {
  name: "parent",
  components: {
    Children,
  },
};
</script>
<style scoped lang="scss"></style>

子组件
<template>
  <div>
    子组件<br />
    <!-- 默认插槽 -->
    <!-- 没有名字的进入默认插槽 -->
    <slot></slot>
    <hr />
      
    <!-- 有名字的进入各自对应的插槽 -->
    <!-- 具名插槽 -->
    <slot name="tb"></slot><br />
    <slot name="jd"></slot><br />
    <slot name="zh"></slot><br />
    <slot name="yh"></slot>
    <hr />

    <!-- 作用域插槽 -->
    <!-- 在子组件中,定义一些数据給父组件使用 -->
    <slot name="zyy" text="作用域插槽"></slot>
  </div>
</template>

<script>
export default {};
</script>
<style scoped lang="scss"></style>

:is指令

  • :is=‘XXX’,这里的XXX一定是组建的名称,来自于components{}
  • 作用:根据XXX的值来渲染某个组件,当我们切换XXX的值,:is组件就会切换成不同的组件
  • v-once:对低开销的静态组件使用
父组件
<template>
  <div>
    <select v-model="tab">
      <option value="Tab1">Tab1</option>
      <option value="Tab2">Tab2</option>
      <option value="Tab3">Tab3</option>
    </select>
    <!-- :is='XXX',这里的XXX一定是组建的名称,来自于components{} -->
    <!-- 作用:根据XXX的值来渲染某个组件,当我们切换XXX的值,:is组件就会切换成不同的组件 -->
    <div :is='tab'></div>
  </div>
</template>

<script>
import Tab1 from "./tab1.vue";
import Tab2 from "./tab2.vue";
import Tab3 from "./tab3.vue";
export default {
  name: "tabs",
  data(){
    return{
      tab:'Tab1'
    }
  },
  components: {
    Tab1,
    Tab2,
    Tab3,
  },
};
</script>
<style scoped lang="scss"></style>

子组件1
<template>
  <div><span style="background:pink;">Tab1</span></div>
</template>

<script>
export default {};
</script>
<style scoped lang="scss"></style>


子组件2
<template>
  <div>Tab2</div>
</template>

<script>
export default {
}

</script>
<style scoped lang='scss'>
</style>


子组件3
<template>
  <div>Tab3</div>
</template>

<script>
export default {
}

</script>
<style scoped lang='scss'>
</style>

keep-alive

  • 可以对失活的组件进行缓存,可以通过$childer查看当前子组件的列表
  • inclode:要缓存的是哪些组件
  • exclode:不要缓存的是那些组件
  • keep:保持
  • alive:或者
    <keep-alive exclude="Tab2">
      <div :is="tab"></div>
    </keep-alive>

$nextTick

  • $nextTick:在上一轮的所有的异步操作都完成了,再执行
  • next:下一个
  • tick:标记;刻点
      // $nextTick:在上一轮的所有的异步操作都完成了,再执行
      this.$nextTick(() => {
        console.log(newValue);
        console.log(this.$children);
      });

filter(过滤器)

  • 对数据进行格式化处理
  • {{ 变量 | 处理规则 }}
{{ 3120314(变量) | rmb }}		==>  $3,120,314
······
filters:{
    rmb: function(value) {
      let i = String(value)
        .split("")
        .reverse();
      for (let b = 1; b < i.length; b++) {
        if (b % 3 == 0) {
          i[b] =   i[b]+",";
        }
      }
      i='$'+i.reverse().join('')
      // console.log(i);
      // let c=null
      // for(let b=0;b<i.length;b++){
      //   c+=i[b]
      // }
      // console.log(value);
      return i;
    },
}

钩子函数

beforeCreate组件实例加载前
created组件实例加载完成
beforeMount模板挂载前
mounted模板挂载完成后
beforeUpdate数据更新前
update数据更新后
beforeDestroy数据销毁前
destroyed数据销毁完成
activated激活
deactivated失活
  beforeCreate() {
    console.log("组件实例创建之前");
  },
  created() {
    console.log("组件实例挂载完成");
  },
  beforeMount() {
    console.log("模板挂载之前");
  },
  mounted() {
    console.log("模板挂载之后");
  },
  beforeUpdate() {
    console.log("数据更新之前");
  },
  updated() {
    console.log("数据更新完成");
  },
  beforeDestroy() {
    console.log("数据销毁之前");
  },
  destroyed() {
    console.log("数据销毁");
  },
  activated(){
    console.log('激活');
  },
  deactivated(){
    console.log('失活');
  }

自定义指令

全局样式

less预处理器

cnpm i less@4.1.2 less-loader@5.0.0 --save-dev

防抖

思考:

<template>
  <el-input v-model="text" @input="debounceInput" />
</template>

<script>
  export default {
    mounted () {
      this.debounceInput = this.debounce(this.handle, 1000,false)
    },
    data () {
      return {
        text: '',
        debounceInput: () => {},
      }
    },

    methods: {
      handle (value) {
        console.log(value)
      },

      debounce (func, delay = 1000, immediate = false) {
        let timer = null
        //不能用箭头函数
        return function () {
          //在时间内重复调用的时候需要清空之前的定时任务
          if (timer) {
            clearTimeout(timer)
          }
          //适用于首次需要立刻执行的
          if (immediate && !timer) {
            func.apply(this,arguments)
          }
          timer = setTimeout(() => {
            func.apply(this,arguments)
          }, delay)
        }
      },
    }
  }
</script>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值