目 录CONTENT

文章目录
Vue

Vue 课堂笔记

lionkliu
2022-08-31 / 0 评论 / 0 点赞 / 184 阅读 / 19,333 字

1、入门案例

1.1 电影列表

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue_02</title>
</head>

<body>
    <div id="app"></div>
    <template id="my-app">
        <h2>Hello Vue3</h2>
        <h3>666</h3>
        <h3>{{msg}}</h3>
        <div>{{person.name}}</div>
        <div>{{person.age}}</div>
        <hr>
        <h2>电影列表</h2>
        <ul>
            <li v-for="movie in movies">{{movie}}</li>
        </ul>
    </template>

    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    msg: '777',
                    person: {
                        name: 'zhangsan',
                        age: 18
                    },
                    movies: ['大话西游', '奥特曼', '大闹天空']
                };
            },

        })
        app.mount('#app')
    </script>
</body>

</html>

image-20220921084930332

1.2 计数器

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app"></div>
    <template id="my-app">
        当前计数器:
        <button @click="des">-</button>
        <span> {{counter}} </span>
        <button @click="incr">+</button>
    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    counter: 100
                };
            },
            methods: {
                incr() {
                    this.counter++
                },
                des() {
                    this.counter--
                }

            }
        })
        app.mount('#app')
    </script>
</body>

</html>

2、MVVM和Vue响应式原理

2.1 MVVM

image-20220921084455506

  • View层:视图层

    • 在我们前端开发中,通常就是DOM层,主要的作用是给用户展示各种信息。
  • Model层:数据层

    • 数据可能是固定的数据,也可能是从网络上请求下来的数据。
  • VueModel层:视图模型层

    • 视图模型层是View和Model沟通的桥梁。一方面它实现了Data Binding(数据绑定),将Model的改变实时的反应到View中(响应式系统),另一方面它实现了DOM Listener(DOM监听),当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。

2.2 Vue响应式原理

什么是响应式?

  • 当数据改变时,引用数据的函数会自动重新执行

响应式是一个过程,这个过程存在两个参予者:一方是触发,另一方是响应,比如:我家有只小狗,当我朝小狗走过去时,小狗竟会对我摇尾巴,这里我就是触发者,小狗就是响应者,同样的,在数据响应式中的两个参与者

  • 触发者:数据
  • 响应者:引用数据的函数 (副作用函数)

当数据发生改变时,引用数据的函数 响应 数据的改变而重新执行

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app"></div>
    <script>
        const obj = { name: '阿杰' }
        function effect() {
            document.querySelector('#app').innerHTML = obj.name
        }
        effect()

        // 当数据改变的时候,effect如何自动执行?
        // vue中使用proxy对数据进行拦截
        // proxy就是obj的代理对象,当对proxy读取时,会自动执行get函数,赋值时,会自动执行set函数
        const proxy = new Proxy(obj, {
            get(target, key) {
                // target: 代理对象 ,key读取的属性
                console.log(`读取数据`);
                return target[key]
            },
            set(target, key, value) {
                console.log(`赋值`);
                target[key] = value
                effect()
                return true
            }
        })
    </script>
</body>

</html>

image-20220921091449711

image-20220921091417690

2.3 data与methods属性说明

data 属性

  • data属性是传入一个函数,并且该函数需要返回一个对象

  • data中返回的对象会加入到Vue的响应式系统中,之后对该对象的修改或者访问

都会被Vue的响应式系统所处理,更新对应视图 (Vue响应式原理)

image-20220921094335964

methods属性

  • methods属性是一个对象,通常我们会在这个对象中定义很多的方法:
    • 这些方法可以被绑定到模板中;
    • 在这些方法方法中,我们可以使用this关键字来直接访问到data中返回的对象的属性;
image-20220921094620733
  • methods中的函数不可以使用箭头函数

注意,不应该使用箭头函数来定义method函数(例如plus:()->this.a++)。理由是箭头函
数绑定了父级作用域的上下文,所以this将不会按照期望指向组件实例,this.a将是undefined。

image-20220921094715467

3、模板语法

3.1 插值语法

  • 插值表达式(Mustache )的作用是在View中获得Model中的内容,插值表达式不能写在HTML中,不能作为值的部分。
<div id="app"></div>
    <template id="my-app">
        <h2>{{firstname}} - {{lastname}}</h2>
        <h2>function: {{getName()}}</h2>
        <h2>{{msg.split(' ').reverse().join(' ')}}</h2>
        <h2>{{counter>=60?'及格':'不及格'}}</h2>
        <h2>数组取值:{{arr[2]}}</h2>
        <h2>对象取值:{{ obj.age }}</h2>
    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    lastname: "san",
                    firstname: "zhang",
                    counter: 80,
                    msg: 'i am a student',
                    arr: [1, 2, 3, 4],
                    obj: { "name": "xiaoyu", "age": 20 }
                };
            },
            methods: {
                getName() {
                    return this.firstname + this.lastname;
                }

            },
        })
        app.mount('#app')
    </script>

image-20220921102138398

3.2 v-once指令

指明此元素的数据只获取一次,之后数据内容的修改不影响此元素。

<p v-once>{{title}}</p>

3.3 v-text 和 v-html

  • v-text: 纯文本输出内容
  • v-html :就好比是innerHTML
        <p v-text="finishedlink"></p>
        <p v-html="finishedlink"></p>
		data:{
			title:"hello world!",
		    link:"http://www.baidu.com",
			finishedlink:"<a href='http://www.baidu.com'>百度</a>"
		},

image-20211117193102253

3.4 v-pre

  • V-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签
  • 跳过不需要编译的节点,加快编译的速度

<h2 v-pre>{{msg}}</h2>

image-20220921103132535

3.5 v-cloak(了解)

  • 这个指令保持在元素上直到关联组件实例结束编译

  • 需要和 CSS 规则 [v-cloak] { display: none } 一起使用,这个指令可以隐藏未编译的 Mustache 标签直到组件实例准备完毕

image-20220921105009678

3.6 v-bind 属性绑定⭐

  • v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值
  • 简写:

在开发中,有哪些属性需要动态进行绑定呢?比如图片的链接src、网站的链接href、动态绑定一些样式等等

案例:动态绑定网站的链接href,动态改变图片src

① 绑定基本属性

<body>
    <div id="app"></div>
    <template id="my-app">
        <a v-bind:href="link">{{link}}</a>
        <button @click="changeLink">changeLink</button>
        <img :src="imgUrl" height="50" height="50">
        <button @click="changeImg1">第一张图</button>
        <button @click="changeImg2">第二张图</button>

    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    link: 'www.jd.com',
                    imgUrl: './img/1.jpg'
                };
            },
            methods: {
                changeLink() {
                    this.link = 'www.baidu.com'
                },
                changeImg1() {
                    this.imgUrl = './img/1.jpg'
                },
                changeImg2() {
                    this.imgUrl = './img/2.jpg'
                }

            },
        })
        app.mount('#app')
    </script>
</body>

② 绑定class

对象语法

可以根据属性值true或false决定是否绑定

案例:根据isActive变量的值动态决定是否加入active的class

<body>
    <div id="app"></div>
    <template id="my-app">
        <h2 :class="{ggg:isActive}">{{msg}}</h2>
        <button @click="isActive=!isActive">切换</button>
    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    msg: 'hello,msg!',
                    isActive: true
                };
            },
            methods: {

            },
        })
        app.mount('#app')
    </script>
</body>

数组语法

我们可以把一个数组传给 :class,以应用一个 class 列表

<template id="my-app">
    <!-- 字符串 -->
    <h2 :class="['aaa','bbb']">{{msg}}</h2>
    <!-- 变量 -->
    <h2 :class="['aaa','bbb',ccc]">{{msg}}</h2>
    <!-- 三元运算符 -->
    <h2 :class="['aaa',score < 60 ? 'red':'']">{{score}}</h2>
    <!-- 对象 -->
    <h2 :class="['aaa',{red: score < 60}]">{{score}}</h2>

  </template>

③ 绑定style

<body>
    <div id="app"></div>
    <template id="my-app">
        <!-- 注意:下划线改驼峰 -->
        <h2 :style="{color:'red',fontSize:'55px',backgroundColor:'yellow'}">{{msg}}</h2>
        <!-- 变量 -->
        <h2 :style="obj">{{msg}}</h2>

        <h2 :style="{color:'red',fontSize: size+'px',backgroundColor:'yellow'}">{{msg}}</h2>
        <button @click="size++">变大</button>
    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    msg: 'hello,msg!',
                    obj: { color: 'red', 'font-size': '55px', 'background-color': 'blue' },
                    size: 65
                };
            },
            methods: {

            },
        })
        app.mount('#app')
    </script>
</body>

绑定一个对象

如果我们希望将一个对象的所有属性,绑定到元素上的所有属性,应该怎么做呢

<body>
    <div id="app"></div>
    <template id="my-app">
        <!-- 动态绑定属性名和属性值 -->
        <div :[stuid]="stuname" aaa="giu">{{ msg }}</div>
        <button @click="changeAttr">修改属性</button>
        <h2 v-bind="info"></h2>
    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    msg: 'hello,msg!',
                    stuid: "S2002666",
                    stuname: '张三',
                    info:{
                        name:'zisi',
                        age:18
                    }

                };
            },
            methods: {

            },
        })
        app.mount('#app')
    </script>
</body>

3.7 v-on 事件处理

  • v-on:click可以写成**@click**,是它的语法糖写法

  • 一个事件,可以绑定多个方法。绑定一个方法时,()可以省略。绑定多个方法时,方法要加**()**

给事件绑定的方法传参写法

事件对象

v-on修饰符

  • .stop - 阻止事件冒泡 (相当于调用 event.stopPropagation() )

  • .prevent - 阻止事件默认行为(相当于调用 event.preventDefault() )

  • .once - 只触发一次回调

  • 键盘事件 - 当事件是从特定按键触发时才触发回调 (绑定键盘事件,例如@keyup),Vue 为一些常用的按键提供了别名.enter 、.tab 、.delete (捕获“Delete”和“Backspace”两个按键) 、.esc 、.space 、.up 、.down 、.left 、.right 等等

<body>
    <div id="app"></div>
    <template id="my-app">
        <div class="father" @click="father">
            <!-- @click.stop 阻止事件冒泡 -->
            <div class="son" @click.stop="son"></div>
        </div>
        <!-- @click.prevent 阻止事件默认行为 -->
        <a href="http://www.jd.com" @click.prevent="go">go to jd</a>

        <h2>号码:{{phone}}</h2>
        <!-- 键盘松开就会触发 -->
        <input type="text" @keyup="changePhone">
        <!-- 按下回车才会触发事件 -->
        <input type="text" @keyup.enter="changePhone">
    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    inputValue: "",
                    phone: 1888888888

                };
            },
            methods: {
                father() {
                    alert("i am father!")
                },
                son() {
                    alert("i am son!")
                },
                changePhone(e) {
                    this.phone = e.target.value
                },
                go() {
                    alert('哈哈哈,你被阻止了')
                }

            },
        })
        app.mount('#app')
    </script>
</body>

3.8 v-if 和 v-show 条件渲染

① v-if

  • 当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉

  • 当条件为true时,才会真正渲染条件块中的内容

② v-show

③ v-if 和 v-show区别

在用法上的区别:

  • v-show 是不支持template;

  • v-show 不可以和v-else一起使用

本质的区别:

  • v-show元素无论是否需要显示到浏览器上,它的DOM实际都是有存在的,只是通过CSS的display属性来进行切换;

  • v-if 当条件为false时,DOM是不存在的

开发中如何进行选择呢?

  • 如果我们的原生需要在显示和隐藏之间频繁的切换,那么使用 v-show
  • 如果不会频繁的发生切换,那么使用 v-if

3.9 v-for 列表渲染

  • v-for的基本格式是 item in 数组,数组通常是来自 data 或者 props。item是我们给每项元素起的一个别名,这个别名可以自定来定义

  • 在遍历一个数组的时候,如果需要拿到数组的索引,可以使用格式: (item, index) in 数组,注意上面的顺序:数组元素项item是在前面的,索引项index是在后面的

    <template id="my-app">
        <h2>电影列表</h2>
        <ul>
            <li v-for="movie in movies">{{index+1}} -- {{movie}}</li>
        </ul>
    </template>

    <template id="my-app">
        <h2>电影列表</h2>
        <ul>
            <li v-for="(movie,index) in movies">{{index+1}}、{{movie}}</li>
        </ul>
    </template>
  • v-for也支持遍历 对象 ,并且支持有一二三个参数
    • 一个参数: “value in object”;
    • 二个参数: “(value, key) in object”;
    • 三个参数: “(value, key, index) in object”;
    <template id="my-app">
        <h2>person</h2>
        <ul>
            <li v-for="(item,key,index) in person">{{index+1}} -- {{key}} -- {{item}}</li>
        </ul>
    </template>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    person:{
                        name:'zhangsan',
                        age:18,
                        height:188
                    }

                };
            },
        })
        app.mount('#app')
    </script>

补充:数组更新检测

变更方法

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新

    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    arr: [6, 8, 5, 1,9]
                };
            },
            methods: {
                changeArr() {
                    // this.arr.push(66,77,88)
                    // 从数组最后删除一个元素
                    // this.arr.pop()
                    // 从数组最前面删除一个元素
                    // this.arr.shift()
                    // 数组头添加元素
                    // this.arr.unshift(1)
                    // 指定删除, splice(索引,个数); 新增:splice(索引,个数,新增)
                    // this.arr.splice(1, 1,66,77)
                    // this.arr.sort((a, b) => a - b)
                    this.arr.reverse()
                }
            },
        })
        app.mount('#app')
    </script>

不变更方法

3.10 v-model – 数据双向绑定⭐⭐

<body>
    <div id="app"></div>
    <template id="my-app">
        <h2>{{msg}}</h2>
        <input type="text" v-model="msg">
    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    msg: 'hello,msg!'

                };
            },
        })
        app.mount('#app')
    </script>
</body>

原理

<body>
    <div id="app"></div>
    <template id="my-app">
        <h2>{{msg}}</h2>
        <input type="text" :value="msg" @input="msg=$event.target.value">
    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    msg: 'hello,msg!'
                };
            },
        })
        app.mount('#app')
    </script>
</body>

diff算法

4、计算属性和监听属性

4.1、计算属性—computed

什么是计算属性

计算属性的重点突出在 属性 两个字上(属性是名词),首先它是个 属性 其次这个属性有 计算 的能力(计算是动词),这里的 计算 就是个函数;简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;

4.2、监听属性 —watch

基础用法

immediate 立即执行

deep 深度监听

$watch API

this.$watch() 返回一个函数,调用这个函数就会停止监听

<body>
    <div id="app"></div>
    <template id="my-app">
        <h2>{{info.name}}</h2>
        <button @click="startListen">开始监听</button>
        <button @click="stopListen">停止监听</button>
        <button @click="info.name='lisi'">修改info</button>

    </template>
    <script src="./lib/vue.global.js"></script>
    <script>
        var unwatch = null;
        const app = Vue.createApp({
            template: '#my-app',
            data() {
                return {
                    msg: 'hello,msg!',
                    info: {
                        name: 'kobe',
                        age: 21,
                        height: 191
                    }

                };
            },
            methods: {
                startListen() {
                    console.log('开始监听。。。。');
                    unwatch = this.$watch('info', (newValue) => {
                        console.log(newValue);
                    }, { deep: true, immediate: false })
                },
                stopListen(){
                    console.log('停止监听。。。。');
                    unwatch()
                }

            },
        })
        app.mount('#app')
    </script>
</body>

4.3 watch与computed的区别

  • computed是计算属性,watch是监听一个值的变化而执行对应的回调
  • computed函数所依赖的属性不变的时候会使用缓存;watch每次监听的值发生变化时候都会调用回调
  • computed的函数内必须调用return;watch可以没有
  • computed一般用在 当一个属性受多个属性影响的时候(例如:购物车总价格);watch用在 当一条数据影会响多条数据的时候(例如:搜索城市天气)
  • computed函数不能有异步操作;watch可以

5、组件化开发🎯

vue.js 有两大法宝,一个是数据驱动,另一个就是组件化,那么问题来了,什么叫做组件化,为什么要组件化?接下来我就针对这两个问题一一解答,所谓组件化,就是把页面拆分成多个组件,每个组件依赖的 CSS、JS、模板、图片等资源放在一起开发和维护。 因为组件是资源独立的,所以组件在系统内部可复用,组件和组件之间可以嵌套,如果项目比较复杂,可以极大简化代码量,并且对后期的需求变更和维护也更加友好。

image-20221012110441960

组件开发三要素:
prop , 自定义事件 , slot是组成组件的三个重要因素。

  1. prop用于定义组件的属性。
  2. 自定义事件用于触发组件的事件。
  3. slot用于组件功能的扩展。

注意 : 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝

5.1、组件注册

① 全局组件

Vue.component(tagName组件名, options) 进行全局注册,例如

Vue.component('my-component', {
  // 选项
})

这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。

② 局部组件

  • 局部组件注册在某个vue对象中,
  • 只有注册过该局部组件的vue对象才能使用这个局部组件
// 定义组件
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
// 使用的组件
new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

注意局部注册的组件在其子组件中*不可用*

区别:全局组件是挂载在 Vue.options.components 下,而局部组件是挂载在 vm.$options.components 下,这也是全局注册的组件能被任意使用的原因。

5.2、组件间通信

在学习组件间通信前,先明白什么是父组件,什么是子组件。我们将某段代码封装成一个组件,而这个组件又在另一个组件中引入,而引入该封装的组件的文件叫做父组件,被引入的组件叫做子组件。

  • 父组件传递给子组件:通过props属性,子组件自定义属性(props)

  • 子组件传递给父组件:通过$emit触发事件

① 父传子 — props属性

什么是props

  • props是组件上注册的一些自定义属性(attribute);

  • 父组件可以通过在子组件标签上给自定义属性(attribute)赋值,来达到传递信息给子组件

  • 子组件可以直接取出这些属性对应的值

  • props有两种常见的用法:

方式一:字符串数组 :数组中的字符串就是自定义属性(attribute)的名称;

方式二:对象类型 :对象类型我们可以在指定attribute名称的同时,指定它需要传递的类型、是否是必须的、默认值等等;

可以绑定静态属性(写死的数据)和动态属性(数据可变)

父组件向子组件传递数据:

  • 传递静态数据 ,在组件使用标签上声明静态数据 key=value 在子组件定义内部使用props声明接收数据
  • 动态属性::key=""进行绑定

ShowInfo.vue 子组件

<template>
  <div>
    <h2>{{title}}</h2>
    <p>
      {{message}}
    </p>
  </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  // 自定义属性
  props: ['title', 'message'],
};
</script>
<style scoped></style>

App.Vue 父组件中引用 ShowInfo.vue 子组件

<template>
  <div>
    <show-info :title="title" :message="message"></show-info>

  </div>
</template>
<script>
import ShowInfo from './components/ShowInfo.vue'
export default {
  data() {
    return {
        title:'二十大',
        message:`提出到2035年我国发展的总体目标,指明未来五年全面建设社会主义现代化国家主要目标任务;`
    };
  },
  components:{
    ShowInfo
  }
};
</script>
<style scoped></style>

image-20221026081915465

单向数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

② 子传父 — 事件传值$emit

  • 在子组件标签上定义传递事件 ,如@key=value形式,@传递事件名=父组件传递事件名
  • 在子组件中通过this.$emit('事件传递名')调用父组件事件
  • 通过this.$emit('事件传递名')传递事件时,可以携带子组件中的data数据,并且父组件事件函数接收

案例1

Tabbar.vue

<template>
  <div class="tabbar">
    <template v-for="(item, index) in tabs" :key="index">
      <div class="tab" @click="tabChange(index)">
        <span :class="{ active: index === currentIndex }">{{ item }}</span>
      </div>
    </template>

    <!-- <div class="tab"><span>平板</span></div>
    <div class="tab"><span>手机</span></div> -->
  </div>
</template>
<script>
export default {
  props: ["tabs"],
  emits: ["tabClick"],
  data() {
    return {
      currentIndex: 0,
    };
  },
  methods: {
    tabChange(index) {
      this.currentIndex = index;
      this.$emit("tabClick", index);
    },
  },
};
</script>
<style scoped>
.tabbar {
  width: 300px;
  margin: 0 auto;
  display: flex;
  cursor: pointer;
  text-align: center;
}
.tab {
  flex: 1;
}
.active {
  border-bottom: 5px solid red;
}
</style>

App.vue

<template>
  <div class="app">
    <Tabbar :tabs="tabs" @tab-click="tabChange"></Tabbar>
    <h2>{{ info[currentIndex] }}</h2>
  </div>
</template>
<script>
import Tabbar from "./components/Tabbar.vue";
export default {
  data() {
    return {
      tabs: ["电脑", "手机", "平板"],
      info: ["电脑页面", "手机页面", "平板页面"],
      currentIndex: 0,
    };
  },
  methods: {
    tabChange(index) {
      this.currentIndex = index;
    },
  },
  components: {
    Tabbar,
  },
};
</script>
<style scoped>
.app {
  width: 800px;
  margin: 0 auto;
}
</style>

效果:点击切换Tabbar,并且下面也会随之改变

image-20221026083837668

③ provide/inject

④ 兄弟组件通信

5.3、插槽

Vue插槽

什么是插槽?

相当于一个占位符,用来扩展组件,使组件更加灵活

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slotslot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。新语法的由来可查阅这份 RFC

具名插槽

带有名字的插槽

默认插槽

在没有指定插槽name时,会替换slot里面内容

6、Vue生命周期钩子函数

Vue 实例生命周期

七、Vue-CLI — Vue脚手架

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供:

  • 通过 @vue/cli 实现的交互式的项目脚手架。
  • 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发。
  • 一个运行时依赖 (@vue/cli-service),该依赖:
    • 可升级;
    • 基于 webpack 构建,并带有合理的默认配置;
    • 可以通过项目内的配置文件进行配置;
    • 可以通过插件进行扩展。
  • 一个丰富的官方插件集合,集成了前端生态中最好的工具。
  • 一套完全图形化的创建和管理 Vue.js 项目的用户界面。

7.1、安装

注:Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)。

npm install -g @vue/cli
# OR
yarn global add @vue/cli

7.2、创建一个项目

# 命令行输入
vue create hello-world(项目名称)

通过可视化页面创建项目:

# 命令行输入
vue ui
image-20211111210122758

7.3、运行及打包

# 运行
npm run serve
默认端口:localhost:8080

# 打包
npm run build
打包好会生成一个dist文件夹,里面就是打包好的html css js 代码

九、VueX — 状态管理

VueX官网文档

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式 (opens new window)就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

state:

💁‍♂️:同来定义一些组件共享数据

state: {
    count: 0,
  },

如何使用?

在任何组件都可以通过this.$store.state.count或者$store.state.count获取

Mutations

💁‍♂️:用来对共享数据状态修改的方法

在Mutations里面定义的方法,都有一个默认参数,默认参数会将状态对象传递给自定义方法

  mutations: {
    increCount(state) {
      state.count ++
    }
  },

在组件中通过this.$store.commit("methodsName")调用Mutations里的methodsName方法

注意:

可以通过this.$store.commit传递参数,但commit只有两个参数,因此想要传递多个参数时,要将多个参数包装成一个对象,如何再传递

Getters

💁‍♂️:用来对共享数据计算的方法,相当于组件中computed属性

使用:this.$store.getters.计算属性

Actions

Modules


参考文章:

https://blog.csdn.net/gaoxin666/article/details/83279001

0

评论区

// // // //