三阶段总结

一、Vue

1、Vue2.0

下载Vue2.0(源码)第三方包:
    在存放的文件夹路径下打开黑窗口或者直接在vscode中运行:输入 npm i vue@2
        
MVVM:Model-View-ViewModel
    一种软件架构设计模式,决定了写代码的思想和层次。
        M:Model数据模型(数据层,data里定义)
        V:View视图(视图层,html页面)
        VM:ViewModel视图模型(控制层,vue.js源码)
 //  声明式编程:区分于命令式, 只需要声明数据即可,直接用。
语法一:
    const wm = new Vue({
        el:"#app", // 挂载到#app 模版上
        data:{ // 数据层  Model层
            msg:"hello world"
        }
    })
    
注意:el和data是固定的,是Vue实例化出来的wm对象的属性。data里面的msg是随便起的名。
语法二: 
    let json = { // 数据层  Model层
        msg: "hello world",
        age: 18,
        list: ["a", "b", "c", "d", 'e']
    }

    // json已经 被vm对象所管控,只能在#app这个区域使用数据
    const vm = new Vue({
        el: "#app", // 挂载到#app 模版上
        data: json
    })

    console.log(json); // 
    console.log(vm); // 它身上除了有json对象上的属性,还有对应的getter和setter方法

// 想改变json的msg的值,看看改一下vm(通过改变vm代理对象的 msg属性,照样修改了json对象的数据)
    vm.msg = 'hello vue';// 走setter,
 Vue2.0 底层使用的Object.defineProperty()

ViewModel层如何知道数据变化了,更改到view层上?

    1.VM一旦创建,会将data上的数据作为属性挂载到VM实例对象上(可以通过上述代码看出,vm.msg)
    2.内部借助于Object.defineProperty(),将data中的属性遍历,并为每一个属性设置getter和setter方法
    3.当获取数据时,会调用getter方法;设置数据时,会调用setter方法。
    4.设置数据的时候,触发setter方法,setter方法内部会自动触发watcher方法,进行新旧DOM对比,更新渲染到DOM上

2、Vue3.0

下载Vue3.0(源码)第三方包:
    在存放的文件夹路径下打开黑窗口或者直接在vscode中运行:输入 npm i vue
<div id="app">
    {{age}}
    {{name}}
    <!-- {{docublueAge}} -->

    <button @click="addOne">点我加1</button>
    <button @click="add$">点我加!</button>
</div>
<script src="./lib/vue.global.js"></script>
<script>
    
1.选项式api(Vue2.0中也支持):
    1)从Vue中结构出createApp
        let{createApp}=Vue
        
    2)createApp()创建应用的,参数是配置项
        let app=createApp({
            //data选项
            data(){
                return {
                    age:18
                }
            },
            //methods
            methods:{
            	addOne(){
            		this.age++
        		}
        	},
            //computed
            computed:{
                docublueAge(){
                    return this.age*2
                }
            }
        })
        
    3)将应用挂载到#app这个区域的视图层
        app.mount('#app')


2. 组合式api  入口是setup(){}
    let{ref}=Vue
    Vue.createApp({
        setup(){
            //操作age变量
            let age=ref(18)
            let addOne=function(){
                age.value++
            }
            
            //操作name变量
            let name=ref('张三')
            let add$=function(){
                name.value+='!'
            }
            
            return {
                age,addOne,name,add$
            }
            
        }
    }).mount('#app')
                               
</script>

3、选项式api和组合式api

api:application programming interface

Vue2.0  api:选项式api,没有组合式api
Vue3.0  api:选项式api(大多数和Vue2.0选项式api一样,有一些不一样),又有组合式api

4、模板语法

    声明式语法不支持undefined和null声明式的渲染到页面,其他都支持。
        1.文本插值{{}}
        2.{{}}内可以书写表达式(可以计算出一个结果的式子)
        3.{{}}内支持哪些类型的变量
<div id="app" v-cloak>
    {{msg}} <br>
    {{num}} <br>
    {{flag}} <br>
    {{arr}} <br>
    {{obj}} <br>
    {{unde}} <br>
    {{nu}} <br>
    {{num*2}} <br>
    {{flag?"true":"false"}} <br>
    {{num+100}} <br>
    {{msg.split("").reverse().join("")}}
</div>
<script src="./lib/vue.global.js"></script>
<script>
    
Vue.createApp({
    data(){
        return {
            msg:'hello'
            num: 10,
            flag: true,
            arr: [12, 45, 56],
            obj: { name: 'zs', age: 18 },
            unde: undefined,//不显示
            nu: null//不显示
        }
    }
}).mount('#app')

</script>

5、文本类指令

v-html='data中的变量'	写在标签上作为属性(可以识别标签)
v-text='data中的变量'	写在标签上作为属性

常量:字符串常量('字符串');数字常量(数字);布尔常量(true/false)
v-html = '常量'  写在标签上作为属性(可以识别标签)
v-text = '常量'  写在标签上作为属性

注意:
    Vue2.0中使用v-html和v-text会覆盖标签直接的内容(标签内的内容会忽略)
    Vue3.0中使用v-html和v-text,并且标签内有内容,会给你一个提示

6、属性绑定

语法:
    v-bind:属性名='data中的变量'
    v-bind:属性名='常量'
简写:
    :属性名='data中的变量'

7、事件绑定

语法:
    v-on:事件名='少量的js代码(要求代码是赋值语法)'
    v-on:事件名='函数名'
    v-on:事件名='函数名(参数)'
简写:
    @事件名='少量的js代码(要求代码是赋值语法)'
    @事件名='函数名'
    @事件名='函数名(参数)'
事件对象如何获取:
    1.调用时不传参数时,默认就在第一个形参位置就是事件对象。
    2.调用时传递参数时,需要手动的把事件对象$event放在最后一个参数位置。
事件修饰符:
    @事件名.prevent='事件处理函数'
    @事件名.stop='事件处理函数'
    @事件名.prevent.stop='事件处理函数'
    @事件名.prevent
特殊事件:如keyup事件
    按键修改符:
        @keyup.enter='事件处理函数'(键盘按键抬起时并按下了回车键,就会指向事件处理函数)
            .enter
            .delete(捕获'delete'和'Backspace'两个按键)
            .space(空格键)
            .up(上箭头)
            .down(下箭头)
            .left(左箭头)
            .right(右箭头)
    配合功能键:
            .ctrl键
            .alt键
            .shift键
            .meta键
    按下enter键的同时按下ctrl键
           @keyup.ctrl.enter='' 
eg:
<style>
    .red {
        color: red;
    }

    .father {
        width: 300px;
        height: 300px;
        background-color: palegreen;
    }

    .son {
        display: block;
        width: 100px;
        height: 100px;
        background-color: paleturquoise;
    }
</style>
<div id="app">

    <input type="text" @keyup.enter.ctrl="enterFn">

    <!-- <a href="http://www.baidu.com" @click.prevent="alertBd">百度</a> <br> -->

    <!-- <a href="http://www.baidu.com" @click.prevent="alertBd1(5,$event)">百度</a> -->

    <div class="father" @click="fatherFn">
        <a class="son" @click.prevent.stop="sonFn" href="http://www.baidu.com">哈哈哈</a>
    </div>

    <!-- 这种写法也支持:意思是阻止默认行为,但是没有阻止冒泡 -->
    <div class="father" @click="fatherFn">
        <a class="son" @click.prevent href="http://www.baidu.com">哈哈哈</a>
    </div>

</div>
<script src="./lib/vue.global.js"></script>
<script>
Vue.createApp({
    
    data() {
        return {
            age: 18,
            flag: true
        }
    },
    
    methods: {
        addAge() {
            this.age += 5;// 访问属性的时候,要使用this.age访问 (age现在挂载在app应用上的)
        },
        addAgeFive(num) {
            this.age += num
        },
        alertBd(e) { // 形参的第一个位置
            alert("百度");
        },
        alertBd1(num, e) {
            alert("百度");
        },
        sonFn() {
            alert("son")
        },
        fatherFn() {
            alert("father")
        },
        enterFn() {
            alert("我抬起并按下了回车键")
        }
    }
    
}).mount("#app")
        
</script>

8、条件渲染

v-if 作用:用来控制标签的显示和隐藏。
v-if 原理:使用js中创建(document.createElement())和删除(ele.remove())

v-show 作用:用于控制标签的显示和隐藏。
v-show 原理:使用js中display:none和display:block来控制的
v-if和v-show的区别:
    原理:
        v-if 利用标签的创建和删除
        v-show 利用标签的display显示和隐藏
    性能:
        v-if 每一次切换都会消耗性能
        v-show 初始显示,只消耗一次性能
    使用时:
        v-if 不频繁使用显示和隐藏时
        v-show 频繁使用显示和隐藏时
    安全性:
        v-if 安全性能更好
        v-show 安全性不好
    使用template标签:
        v-if 可以用在template标签上
        v-show 不可以用在template标签上
eg:
<div id="app">
       <button @click="age++">点我变大</button> {{age}}

       <!-- <p v-if="age<18">未成年</p>
       <p v-else>成年</p> -->

<!--<p v-show="age<18">未成年</p>
       <p v-show="age>=18">成年</p> -->


       <!-- 它是一个标签,但是不会显示到页面 -->
       <template v-if="age<18">
            成年人的世界,你懂得~
       </template>
 </div>
<script src="./lib/vue.global.js"></script>
<script>
    Vue.createApp({
    
        data () {
            return {
                 age:16
            }
        },
    
        methods: {
            
        },
    
    }).mount("#app")
</script>

9、循环

口诀:想让谁出现多次,就把v-for写在谁身上

语法一:
    遍历数字:
        v-for='item in 数字' :key='唯一的,有id使用id,没有id使用index'

语法二:
    遍历数组:
        v-for='(item,index) in data中的数组' :key='唯一的,有id使用id,没有id使用index'

语法三:
    遍历对象:
        v-for='(value,key,index) in data中的对象' :key='唯一的,有id使用id,没有id使用index'
eg:
<div id="app">
    <!-- 口诀:想让谁出现多次,就把v-for写在谁身上 -->
    <!-- 语法一: 遍历数字 -->
    <span v-for="(item,index) in 10" :key="index">{{item}} ====={{index}}<br></span>
    <!-- 遍历数组 -->
    <ul>
        <li v-for="(item,index) in arr" :key="index">{{item}}</li>
    </ul>

    <ul>
        <li v-for="(item,index) in list" :key="item.id">{{item.produt}}</li>
    </ul>

    <span v-for="(item,key) in obj" :key="key">{{item}} ---{{key}}</span>

</div>
<script src="./lib/vue.global.js"></script>
<script>
Vue.createApp({
    
    data() {
        return {
            str: "helloworld",
            arr: ["apple", "peach", "pear", "banana", "watermelon"],
            list: [
                { id: 1, produt: "手机1" },
                { id: 2, produt: "手机2" },
                { id: 3, produt: "手机3" },
                { id: 4, produt: "手机4" },
            ],
            obj: {
                name: "zs",
                age: 18,
                sex: "男"
            }
        }
    },
    
    methods: {

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

10、v-if和v-for的优先级

Vue2.0中审查元素:v-for的优先级高于v-if
Vue3.0中审查元素:v-if的优先级高于v-for

注意:v-if和v-for尽量不要写在一个标签上;v-show和v-for可以写在一个标签上。

11、购物车案例

<div id="app">
    <table border="1px">
        <thead>
            <tr>
                <td>商品名称</td>
                <td>商品单价</td>
                <td>商品数量</td>
                <td>商品小计</td>
                <td>操作</td>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(item,index) in list" :key="item.id">
                <td>{{item.product}}</td>
                <td>{{item.price}}</td>
                <td>
                    <button>-</button>
                    <input type="text" :value="item.num" size="2">
                    <button @click="addNum(item.id)">+</button>
                </td>
                <td>
                    {{item.price*item.num}}
                </td>
                <td>
                    <button @click="delNum(item.id)">x</button>
                </td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="5">
                    <!-- 模板语法可以写表达式:只要计算出一个结果就可以 -->
                    {{list.reduce((sum,item)=>sum+=item.price*item.num,0)}}
                </td>
            </tr>
        </tfoot>
    </table>
</div>
<script src="./lib/vue.global.js"></script>
<script>


Vue.createApp({
    data() {
        return {
            list: [
                { id: 1, product: "小米手机", price: 10, num: 1 },
                { id: 2, product: "华为手机", price: 60, num: 1 },
                { id: 3, product: "红米手机", price: 30, num: 1 },
                { id: 4, product: "锤子手机", price: 30, num: 1 },
                { id: 5, product: "小灵通手机", price: 10, num: 1 },
            ]
        }
    },
    methods: {
        addNum(id) {
            //  id: 代表的是具体的哪一个商品  点击的具体的商品
            // 找到商品
            let goods = this.list.find(item => item.id == id);  // 找到的是list的那一个对象
            goods.num++;// 对象的num属性

            // list会自动变化
        },
        delNum(id) {
            // 过滤: filter会改变原数组吗,不会
            let newList = this.list.filter(item => item.id != id);// 过滤出你没有点击删除的所有项
            this.list = newList; // 把list重新覆盖啦
        }
    },
}).mount("#app")
</script>

12、表单输入绑定(v-model)

eg:
    v-model的底层原理:
<div id="app">
    <!-- <input type="text" v-model="msg"> -->
    <!-- 实现一个v-model -->


    <!-- 1. 先实现 model到view层 -->
    <!-- <input type="text" v-bind:value="msg"> -->
    <!-- 2. 将view层同步到model层 -->
    <input type="text" v-bind:value="msg" @input="fn">
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
    el: '#app',
    
    data: {
        msg: "hello world"
    },
    
    methods: {
        fn(e){
            this.msg = e.target.value; // 将输入的内容赋值给msg变量
        }
    },
    
})
</script>

12.1、v-model的作用于复选框

v-model='data中变量的值'

data中变量的值的类型分两大类:
    1)data变量的值的类型是数组:v-model关联的值是 以数组形式包含所有选中状态的复选框的value的值。
    2)data变量的值的类型是非数组:v-model关联的值是 布尔类型的值(使用频率最高)。
eg:
v-model对于复选框关联的值:
    1)v-model的值是'数组'形式:复选框的value值,以数组的形式返回。
    2)v-model的值是'非数组'形式:复选框的选中状态。
 <div id="app">
    <input type="checkbox" v-model="abc" value="篮球">篮球 <br>
    <input type="checkbox" v-model="abc" value="足球">足球 <br>
    <input type="checkbox" v-model="abc" value="排球"> 排球<br>
    <input type="checkbox" v-model="abc" value="铅球">铅球 <br>

    {{abc}}
</div>
<script src="./lib/vue.js"></script>
<script>
    
    const vm = new Vue({
        el: '#app',
        
        data: {
            abc: ''
            // abc: [],  /* 写的比较少 */
        }
    })

</script>

12.2、v-model的作用于下拉列表

eg:
v-model对于下拉列表关联的值:
    关联的是下拉列表option的值。
<div id="app">
    <select v-model="str">
        <option value="上海">上海</option>
        <option value="北京">北京</option>
    </select>
</div>	
<script src="./lib/vue.js"></script>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            str: "上海"
        }
    })
</script>

12.3、v-model的作用于输入框和文本域

v-model对于文本域和输入框关联的值是一样的;都是输入的值。

13、选项卡案例

代码思路:

    1. 默认显示的哪一项   需要使用索引值就可以完成,v-for在遍历的同时在创建标签,只有满足  index==item.id才拥有这个类名   只有第二个按钮会高亮。
    2. 点击的元素的id 赋值给index,index导致:class=”“位置进行了重新判断。
<style>
        .btnActive {
            background-color: orange;
        }

        #app .divActive {
            display: block;
        }

        #app div {
            display: none;
            border: 1px solid grey;
            width: 300px;
        }
    </style>
<div id="app">
    <button v-for="(item) in list" :key="item.id" :class="{'btnActive':index==item.id}"
        @click="changeIndex(item.id)">{{item.title}}</button>
    <div v-for="(item) in list" :key="item.id" :class="{'divActive':index==item.id}">
        {{item.content}}
    </div>
</div>
<script src="./lib/vue.global.js"></script>
<script>
    let app = Vue.createApp({
        data() {
            return {
                index: 1,
                list: [
                    { id: 0, title: "教育", content: "教育的内容" },
                    { id: 1, title: "娱乐", content: "娱乐的内容" },
                    { id: 2, title: "体育", content: "体育的内容" },
                ]
            }
        },
        methods: {
            changeIndex(id) {
                //  id:  具体点击的元素的id
                this.index = id;
            }
        },
    })
    app.mount("#app")
</script>

14、样式绑定

class绑定:
    1)基本绑定样式:
        <p class="active"> 白日依山尽 </p>
        <p :class="'active'"> 白日依山尽 </p>
        <p :class="x"> 白日依山尽 </p>
        <p :class="flag?x:''"> 白日依山尽 </p>
    2)对象的方式:
        <p :class="{'active':false,'border':true}"> 黄河入海流 </p>
    3)数组的方式:
        <p :class="['active','border']"> 欲穷千里目 </p>
        <p :class="[x,y]"> 欲穷千里目 </p>

style绑定:
    1)对象的形式:
        <p :style="{backgroundColor:'red',fontSize:'28px'}"> 更上一层楼 </p>
        <p :style="{backgroundColor:z}"> 更上一层楼 </p>
<script src="./lib/vue.global.js"></script>
<script>
    let app = Vue.createApp({
        data() {
            return {
                flag: true,
                x: 'active',
                y: 'border',
                z: "orange"
            }
        },
    })
    app.mount("#app")
</script>

15、计算属性

1.什么是计算属性?为什么使用计算属性?
    模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。
2.什么时候使用?
    依赖其他属性计算而来的属性,可以写到computed选项中,写起来像方法,使用起来是属性。
3.计算属性和方法的区别?
    1)使用的时候,方法需要带(),计算属性不需要带(),依赖项发生不发生,调用一次,重新执行一次方法体。
    2)计算属性值会基于其响应式依赖被缓存。当依赖项不发生,直接从缓存中取,当依赖项发生变化,会重新调用一次。
计算属性:
1)
computed: {
    
            计算属性的名字:function(){
                return ;
            } 
    
        }
上述写法存在的问题:只能读,不能写。

2)计算属性变成 可读可写:
 computed: {
     
            计算属性的名字: {
                // 获取的语法
                get() {
                    return;
                },
                set(val){
                }
            }
     
        }

15.1、计算属性案例

<div id="app">
    <input type="checkbox" v-model="isAll"> 全选
    <hr>
    <p v-for="item in list" :key="item.id">
        <input type="checkbox" v-model="item.isCheck">
        {{item.product}}
    </p>
</div>
<script src="./lib/vue.global.js"></script>
<script>
    /* 
      下面属性中,哪个可以写成计算属性, 写成了计算属性,它会不会改变呢?
         什么时间使用计算属性,当一个属性的值依赖于其他的属性计算而来的时候,
         isAll需要依赖list中所有的isCheck计算而来
           1. isCheck全部为true,isAll就是true,isCheck有一个是false,isAll就是false
           2. 当更改isAll的值的时候,说明有修改计算属性的需求,所以需要使用带getter和setter的方法
    */
    let app = Vue.createApp({
        data() {
            return {
                list: [
                    { id: 1, product: "小米手机", isCheck: false },
                    { id: 2, product: "华为手机", isCheck: true },
                    { id: 3, product: "红米手机", isCheck: true },
                    { id: 4, product: "锤子手机", isCheck: true },
                    { id: 5, product: "小灵通手机", isCheck: true },
                ]
            }
        },
        computed: {
            // 这种语法只能读,不能更改,(只能去改一下list的isCheck,去查看isAll的效果)
            // isAll:function(){
            //     return this.list.every(item=>item.isCheck==true)
            // }
            // 这种语法 : 可以读可以写
            isAll: {
                get() {
                    return this.list.every(item => item.isCheck == true)
                },
                set(val) {
                    console.log(val);
                    this.list.forEach(item => {
                        item.isCheck = val; // 把当前修改的状态  赋值给下面每一个的isCheck
                    })
                }
            }
        }
    })
    app.mount("#app")
</script>

16、侦听器

侦听器:
      侦听data中数据的变化。

写法一:
    侦听的是基本数据属性:
    watch:{
          "哪个data":function(newval,oldval){}
      }
写法二:
    侦听对象:
    watch:{
         "侦听哪个对象":{
             deep:true,-------必须写,深度侦听
             immediate:true,-------打开页面就侦听
             handler(newval){
                 newval: 改变后的对象的值,对象中所有的属性都在newval包含
             }
         }
      }
注意:
    1)watch 默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。
    2)我们可以用一个对象来声明侦听器,这个对象有 handler 方法和 immediate: true 选项,这样便能强制回调函数立即执行.
eg:
<div id="app">
    <input type="text" v-model="user.firstName"> +
    <input type="text" v-model="user.lastName"> = {{ user.fullName }}
</div>
<script src="./lib/vue.global.js"></script>
<script>
    const app = Vue.createApp({
        data() {
            return {
                user: {
                    firstName: '张',
                    lastName: '三',
                    fullName: ''
                }
            }
        },
        watch: {
            // 写法是可以的,易懂,但是写起来层次比较多就比较麻烦啦
            // 'user.firstName': function (newval, oldval) {
            //     this.user.fullName = newval + this.user.lastName;//  全名 = 新的值 +lastName
            // },
            // 'user.lastName': function (newval, oldval) {
            //     this.user.fullName = this.user.firstName + newval; // 
            // }

            // 侦听的直接是一个user对象,newval就是最新的user对象
            user: {
                deep: true, // 在侦听对象时必须带上 deep:true
                immediate: true, // 打开页面就立即的侦听
                handler(newval, oldval) {
                    // console.log(newval); // 变化后的新的对象,包含着你的firstName和你的lastName,两个任何一个发生变化,user就会变化
                    this.user.fullName = newval.firstName + newval.lastName;
                }
            }
        },
    })

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

16.1、手动开启侦听

    this.$watch("data属性",()=>{})   返回一个一个方法,调用这个方法进行结束侦听
eg:
<div id="app">
    {{count}}
    <button @click="count++">count+1</button>
    <button @click="startWatch">开始监听</button>
    <button @click="endWatch">结束监听</button>
</div>
<script src="./lib/vue.global.js"></script>
<script>
    let app = Vue.createApp({
        data() {
            return {
                count: 1
            }
        },
        methods: {
            startWatch() {
                this.end = this.$watch("count", (newval) => {
                    console.log(newval);
                })
            },
            endWatch() {
                this.end()
            }
        },
    })
    app.mount("#app")
</script>

17、vue中的响应式系统

 

30、组件通信

1.父组件向子组件传值:
    父组件需要在子组件身上通过自定义属性传值,子组件内部通过props接收。
2.子组件向父组件传值:
    父组件需要在子组件身上绑定自定义事件,子组件内部通过$emit(触发的事件,需要传的值)。
3.兄弟组件传值:(只用于Vue2.0中)
    1)先实例一个公共的通信对象(一般js文件)。
            import { createApp } from 'vue'

            //实例化通信对象 并导出
            export default createApp()
    2)并且在两个兄弟组件引入这个通信对象。
            import eventBus from '../utils/eventBus'
    3)在接受值的组件中通过$on监听事件。
                mounted() {
                // 监听事件
                // Vue 3 中 没有$on方法, 会报错
                eventBus.$on('tranferdata', (data) => {
                  console.log('接收到的数据:', data);
                })
        }
    4)在发送值的组件中通过$emit去触发事并传值。
                methods:{
            handleClick(){
                // Vue 3 中 没有$emit方法, 会报错
                eventBus.$emit('tranferdata',88888);
            }
        }
4.跨组件传值:
    外层组件通过provide选项传值,内层组件通过inject接受值。(注意:外层组件的里面每一层组件都可以收到传过去的值,哪个组件想接受就添加inject选项,但接受到值后不能修改值)
                provide: {
            money: 88888,
            arr: [1, 2, 3]
          }
                inject:['money']
                inject:['money','arr']
5.v-model用在自定义组件上,实现对子组件内容的双向绑定:
    1)在自定义组件上使用v-model。
            <MyInput v-model="phone" />
    2)在子组件的操作如下:
        Vue3.0中:里面的'modelValue'、'update:modelValue'、:value="modelValue"中的'modelValue'都是固定的。

            <input type="text" placeholder="输入手机号" :value="modelValue" @input="handleInput">
 
            export default {
      props: ['modelValue'],//声明通过哪个属性接收传来的值
      emits: ['update:modelValue'],//声明事件, 将来可以通过触发该事件来更新父组件中v-model对应属性的值.
      // mounted(){
      //   this.$emit('update:modelValue',this);
      // },
      methods: {
        handleInput(e) {
          this.$emit('update:modelValue', e.target.value)
        }
      }
    }

        Vue2.0中:里面的'abc'、'update:abc'、:value="abc"中的abc不是固定的。

            <input type="text" placeholder="输入手机号" :value="abc" @input="handleInput">
                
            export default {
      props: ['abc'],//声明通过哪个属性接收传来的值
      emits: ['update:abc'],//声明事件, 将来可以通过触发该事件来更新父组件中v-model对应属性的值.
      methods:{
        handleInput(e){
          this.$emit('update:abc',e.target.value)
        }
      }
    }

31、ref参数

    ref放置在'标签'上:获取的是所在标签的dom节点。
    ref放置在'组件'上:获取的是所在组件的实例,进而可以获取子组件上的属性和方法。

32、插槽

1.作用:自定义组件内容。
2.分类:
    1)默认插槽 <slot />
    2)具名插槽 <slot />
3.如何使用:
    1)在自定义组件中写内容。
    2)在子组件中接受的位置处写<slot />。
    注意:
        1)自定义组件不能再用单标签了<Dialog />;必须使用双标签<Dialog></Dialog>了。
        2)<slot />标签也有name属性,代表标签的名字;可进行布置精准插槽。v-slot:title写在父组件上,<slot name="title" />写在子组件上。如下:
        eg:
            父组件
                <Dialog>
                  <template v-slot:title>
                    警告
                  </template>
                  <template v-slot:text>
                    你的svip还有3天过期!
                  </template>
                </Dialog>
            子组件:
                <div class="dialog" v-show="isvisible"  @click="hide">
                    <div class="content"  @click.stop="">
                        <!-- <slot />  这是默认插槽 -->
                        <!-- <slot name="" />  这是具名插槽 -->
                        <div class="title"> <slot name="title" /> </div>
                        <div class="text"> <slot name="text" /> </div>
                        <div class="btns">
                            <span @click="hide">取消</span>
                            <span @click="hide">确定</span>
                        </div>
                    </div>
                </div>

33、内置组件

1.动态组件:component;缓存组件:keep-alive
2.如何使用:
    keep-alive 缓存组件,需要包裹在需要缓存的组件外部, 被缓存的组件会保留在计算机内存中, 组件在下一次切换时只需要从内存中读取并显示出来即可。
    keep-alive标签上有2个属性:
        1)include 指定需要缓存的组件列表。
        2)exclude 指定不需要缓存的组件列表。

    <keep-alive include="ChildA,ChildB" exclude="ChildC">
      <component :is="coms[index]" />
    </keep-alive>
3.与两个生命周期配合使用:activated------激活状态;deactivated------缓存状态。
    activated() {
    console.log('A组件激活了');
  },
    deactivated() {
    console.log('A组件缓存了');
  },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wr_kobe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值