DAY04-侦听和组件化

#第四天 侦听器 组件化


***单词*** watch 看 (这里表示侦听)----- ---counter计数器---- component 组件--- ---- content内容----template 模板
**##侦听器** 监听一个属性值的变化,变化时触发函数 在createApp中添加watch选项,里面定义对应的方法
//响应式 姓氏和名字其中一个变化fullName跟着变化 
<body>
    <div id="app">
        <input type="text" v-model="lastName" placeholder="请输入姓氏"/>
       +
       <input type="text" v-model="firstName" placeholder="请输入名字"/>
       = {{fullName}}
    </div>
    <script src="./lib/vue.global.js"></script>
    <script>
        const {createApp} = Vue;
        const app =createApp({
            data(){
                return {
                    lastName:"",
                    firstName:"",
                    fullName:""
                }
            },
            //watch--不要改名字
            watch:{
                //定义函数--监听谁,定义谁,函数名必须是监听的属性名,形参都是自己定义的名字
                lastName(newVal,oldVal){
                    //newVal表示新的值  oldVal是旧值
                    console.log("lastName新的值:"+newVal,"lastName旧的值:"+oldVal);
                    //计算fullName
                    this.fullName = newVal + this.firstName;
                },
                firstName(newVal,oldVal){
                    //newVal表示新的值  oldVal是旧值
                    console.log("firstName新的值:"+newVal,"firstName旧的值:"+oldVal);
                    //计算fullName
                    this.fullName = this.lastName + newVal;
                }
            },
            methods:{

            }
        })
        app.mount("#app");
    </script>
</body>
侦听 数量价格变化 总价做出响应
<body>
    <div id="app">
        <!-- 绑定价格price -->
        <span>价格:</span>
        <input type="text" v-model="price" placeholder="价格">
        <br>
        <!-- 绑定数量num -->
        <span>数量:</span>
        <input type="text" v-model="num" placeholder="数量">
        <br>
        <span>总价:</span>{{total}}
        <hr>
        <button @click="logToltal">输出data中没有的total</button>
    </div>
    <script src="./lib/vue.global.js"></script>
    <script>
        const { createApp } = Vue;
        const app = createApp({
            data() {
                return {
                    num: 0,
                    price: 0.0,
                }
            },
            watch: {
                //注意,total没在data内定义,侦听时生成total后才可以在其他地方使用,报警告
                //侦听的属性必须在data中定义
                //侦听的属性num,num发生改变则触发num方法
                //参数根据情况可以不加或加1个都可以
                num:function(newVal){
                    console.log("num侦听了");
                    this.total = newVal*this.price;
                },
                //侦听的属性price,price值发生改变则触发price方法
                price:function(newVal){
                    this.total = newVal*this.num;
                }
            },
            methods:{
                logToltal(){
                    console.log(this.total);
                }
            }
        })
        app.mount("#app");
    </script>
</body>

深度监听

<body>
    <div id="app">
        <input type="text" v-model="user.firstName" placeholder="请输入姓氏"/>
        +
        <input type="text" v-model="user.lastName" placeholder="请输入名字"/>
        = {{user.fullName}} || 计算属性:{{fullN}}
        <hr>
        <button @click="count++">加1</button>{{count}}
        <br>
        <button @click="startWatch">开始监听</button>
        <button @click="stopWatch">结束监听</button>
    </div>
    <script src="./lib/vue.global.js"></script>
    <script>
        const {createApp} = Vue;
        const app =createApp({
            data(){
                return {
                    // user是1个对象
                    user:{
                        firstName:'张',
                        lastName:'三',
                        fullName:''
                    },
                    count:100
                }
            },
            //计算属性
            computed:{
                //fullN是计算属性
                fullN(){
                    return this.user.firstName + this.user.lastName
                }
            },
            //侦听器
            watch:{
                //不能直接监听user
                // user(newVal,oldVal){
                //     console.log("变化了");
                // }
                //对象名:{handler(){},deep:true}
                user:{
                    //handler是固定的写法,不能改名,函数体为对监听属性的操作
                   handler(newVal,oldVal){
                       console.log("新的值"+newVal,"旧值"+oldVal);
                       //注意 newVal表示user的新值
                       this.user.fullName = newVal.firstName + newVal.lastName;
                   },
                    //开启深度监听,默认值deep为false
                    deep:true,
                    //强制马上执行回调函数,在加载时就执行一次,这时侦听赖的属性值还没发生变化
                    immediate:true
                }
            },
            methods: {
                //达到某个条件再开启监听,手动监听---this.$watch()
                startWatch(){
                    console.log(this);
                    //手动开启监听count属性,第二个参数是回调函数
                    this.unwatch = this.$watch('count',(newVal,oldVal)=>{
                        console.log(newVal,oldVal);
                    }) 
                },
                stopWatch(){
                    //停止监听
                    this.unwatch();
                }
            },
        })
        app.mount("#app");
    </script>
</body>

###watch侦听器和computed计算属性区别
场景: watch侦听器适合计算开销比较大或异步处理的场景,watch是根据变化产生的一系列的行为
依赖: computed可以依赖多个属性,watch侦听器依赖1个属性
返回值: watch内没有return返回值
参数: watch内有新值和旧值2个参数
缓存: computed有缓存,watch无

2.组件化(组件单词–component)

2.1 什么是组件化(面向页面)

组件化就是将实现页面某一部分功能的结构、样式和逻辑,封装成为一个整体,使其高内聚,低耦合,达到可复用的目的.
组件系统是vue的最强大的功能之一,它让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树

区别于模块化:
模块化:是从代码逻辑的角度进行划分的,方便代码分层开发,保证每个功能模块的职能单一. 如: 实现某个功能的js代码, 这段功能代码在项目的其它地方也需要用到,就将之封装成具有特定功能的模块,实现可复用和分治;某些css样式,在其它地方也可能用到,我们也可以将之css模块化,实现可复用.具体说来,JS模块化方案很多有ES6 Module/CommonJS/AMD等,CSS模块化开发大多是在less、sass、stylus等预处理器的import/mixin特性支持下实现的.
**页面的组成结构:**块级元素组成,元素之间有兄弟关系和父子关系
**大家之前页面的开发流程:**整个页面的html/css/javascript混在一起
需求: 把一个页面分成几个大的块级元素,这个块级元素对应的页面有html/css/javascript
解决: 组件化思维,把大页面划分成多个小页面,每个小组件的功能,样式等都是健全又独立的,类似集装箱房间,拼合成不同的造型、结构,方便维护

2.2 组件分类

局部组件(局部使用)和全局组件(全局使用)

2.3 组件的根元素

就是我们常定义的#app元素

2.4组件的使用

##组件化
页面的组成结构:块级元素组成,元素之间有兄弟关系和父子关系
组件化思维,把大页面划分成多个小页面,每个小组件的功能,样式等都是健全又独立的,类似集装箱房间,拼合成不同的造型、结构,方便维护
组件分类
局部组件(局部使用)和全局组件(全局使用)
组件的实现流程分三步

  • 组件的定义:
    视图层定义–必须在<template></template>内定义
    组件名字:使用帕斯卡命名法(在驼峰命名法基础上,首字母大写)
    例:userName是驼峰命名法,UserName是帕斯卡命名法
    组件定义时,和createApp内的选项是一致的,选项都可以添加,是完整的模块
    组件的数据层的定义
    const Counter = { template: '#counter', data() { return { count: 1 } } };
    template选项名不能改, #counter是上面template的id选择器

  • 组件的注册:
    1.局部注册:在需要注册的组件中,添加一个components选项
    components:{
    //新组件名作为模板中使用的名字,若省略,则使用原来的组件名为模板名
    新组件名:原来组件名
    }

2.全局注册:
app.component(新组件名’,原来组件名)

  • 组件的使用
    • 组件的使用:
      位置– 在对应组件或根组件的视图区使用
      注意–以标签名字的写法–若有多个单词,单词首字母要小写,中间加“-”。
      例:“my-counter”,在解析时,Vue会自动解析为MyCounter,找到我们自己注册的组件

局部组件

//局部组件
<!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">
    <!-- 组件使用 这里将组件注册的名字当标签使用-->
    <!-- 使用组件名时,每个组件都要小写,单词之间用‘-’隔开,Vue解析为MyCounter -->
    <!-- 只有一个单词的时候首字母可小写可大写 -->
    <my-counter>
    </my-counter>
    <!-- 但标签可以 -->
  <my-counter/>
  </div>
   <!-- 组件的视图定义 -->
  <template id="counter">
    <div>
     
      <h5>我是组件Counter的数据:</h5>
      {{count}}
    </div>

  </template>
  <script src="./vue.global.js"></script>
  <script>
    //组件数据层定义,声明的时候用帕斯卡命名法
    const Counter={
      // template选项名不能改, '#counter'是上面template的选择器 相当于挂载template
      template: '#counter',
      data(){
        return{
          count:1
        }
        
      }
    };
  </script>
  <script>
    const {createApp}=  Vue;
    const app=createApp({
      data(){
        return{
          
        }
      },
      // 组建的注册
      components:{
        //注册组件的名字:组件名
        MyCounter:Counter,
        //也可以简写为Counter  等价于Counter:Counter
      }
    })
    app.mount('#app')
  </script>
</body>
</html>

全局组件

//全局组件
<!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>全局组件</title>
</head>

<body>
    <div id="app">
        <!-- 使用组件在这里写,组件的名字作为标记名,若1个单词,首字母可大写 -->
        <!-- 使用Header组件--全局组件 -->
        <my-header />
        <!-- 使用Content组件-局部组件 -->
        <!-- <Content/> -->
    </div>
    <!-- 定义组件的模板 -->
    <template id="header">
        <header>头部信息{{msg}}</header>
        <!-- Content组件在Header组件进行了注册,所以可以在这使用 -->
        <Content />
    </template>

    <script src="./lib/vue.global.js"></script>
    <!-- 引入外部组件 -->
    <script src="./components/Content.js"></script>
    <script>
        // Header组件的定义
        const Header = {
            template: '#header',
            data() {
                return {
                    msg: 'Header'
                }
            },
            components: {
                //局部组件的注册
                Content
            }
        }

        const { createApp } = Vue;
        const app = createApp({
            data() {
                return {
                }
            }
        })
        //一定在mount前注册
        //全局组件app.component('自己起的名字',组件)
        //app.component('my-header',Header);
        app.component('MyHeader', Header);
        app.mount("#app");
    </script>
</body>

</html>

扩展
局部组件和全局组件的区别
全局组件:
1、Vue.component是Vue提供的创建全局组件的方法。语法:Vue.component(“组件名”,{})
2、props:[‘content’], 【接收传过来的content值】
3、template:“

{{content}}

”【组件的内容模板,接收内容替换原标签内容后进行渲染】
4、 v-bind:content=“item”【向子组件传 递一个绑定值】
局部组件:
1、以对象字面量的方式进行声明局部组件,语法:var 组件名=function(){}
2、在实例化Vue对象的时候,在参数components里面对组件进行注册,之后才能以标签的形式使用这个组件。

watch和computed的区别
**场景:**watch侦听器适合计算开销比较大或异步处理的场景,watch是根据变化产生的一系列的行为
依赖: computed可以依赖多个属性,watch侦听器依赖1个属性
返回值: watch内没有return返回值
参数: watch内有新值和旧值2个参数
缓存: computed有缓存,watch无

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值