学习vue的一些笔记

Es6的补充

<body>
    <button class="btns">第一个</button>
    <button class="btns">第二个</button>
    <button class="btns">第三个</button>
    <button class="btns">第四个</button>
    <script>
    // ES5 之前,都没有块级作用域的概念, 以至于只能使用function 来解决作用域问题
        // 1. 变量作用域  => 全局
                {
                    var name ="why";
                    console.log(name);
                }
                console.log(name);
        // 2. 没有块级作用域引起的问题: if 的块级
              var func;
              if(true) {
                  var name = 'why',
                func = function() {
                    console.log(name);
                }
                func()  // 此处执行可打印 why 
              }

              name="kobe";  
              func();  // 此处不打印 kobe
              // 以上例子, name 是if语句内定义, 没有块级作用域导致在if语句外也能修改name 的值

        // 3. 没有块级作用域引起的问题: for 的块级
            //   var btns = document.getElementsByClassName("btns");
            //   for(var i=0; i<btns.length; i++) {
            //       btns[i].onclick = function() {
            //           console.log(i);
            //       }
            //   }
        // 4. 使用闭包解决 没有块级作用域的问题
            var btns = document.getElementsByClassName("btns");
                for(var i=0; i<btns.length; i++) {
                   (function(num){
                        btns[i].onclick = function() {
                            console.log(i);
                        }
                   })(i);
                }

                /* ES6  */
                if(true) {
                    const info_name = 'const';
                    console.log(info_name);
                }
                
                // 1. 注意一: 一旦给const 修饰的标识符被赋值后, 不可修改
                // 2.  在使用cosnt 定义符, 必须进行赋值
                const info_index = 1;  //  不可 const info_index; 
                // 3, 常量的含义是指向的对象不可修改, 但可修改对象内部的属性
                const obj = {
                    name: 'why',
                    age: 18,
                    height: 188
                }
                obj.name = "kobe";  // 可这样操作, 且obj.name 将会被kobe 替换
                                    // 而不可修改 obj 这个对象 , 如 const obj = [];不可将对象改成数组
            
            
            // 1. ES5 写法 字面量写法
            /* 
                const info_obj = {
                    info_name: 'why',
                    info_age : 18,
                    info_height : 188
                }
             */
            //  2. ES6写法       增强写法      
            const info_name = 'why';
            const info_age = 18;
            const info_height = 188

            const info_obj = {
                info_name,
                info_age,
                info_height
            }
     </script>

vue 初体验

<!-- 
        1. Vue 初体验: 创建一个hellow文件
            1. 创建html 文件, 使用内联模式引入 vue.js文件
            2. 创建一个ID 为 app 的div元素
                1.<script> 标签内 创建一个常量 app , 将创建的vue实例赋值给常量 
                    1. el => element 元素
                    2. data 在此处 与模块的data(){return {}}  不同, 组件中的data必须是个函数
                    3. vue实例的数据是响应式的  =>?  当在页面开发者工具consle处 修改 
                       app.data.message 的值后, 页面  message 的值也会跟着修改
                    4. 在html标签内 插入值 =》 mustache 语法  {{}}
                    5. mustache 语法 内 不仅可以插入值,  也可以使用表达式
      -->
    <div id="app">
        {{message}}
        {{message + sex}}
    </div>
    <script>
        // const 常量   let 变量
        const app = new Vue({
            el: "#app",
            data: {
                message: "hellow",
                sex: '难'
            }
        })
    </script>
    <!-- 
        2. 使用循环 v-for 
            1. 创建 vue实例, 绑定元素 circulation  => 循环
            2. v-for 的值 中, 多个单词用逗号隔开, 并使用括号v-for="(item, index) in move"
            3. 一般的 使用了 循环语法, 后带  :key="index"  
     -->
     <div id="circulation">
        <ul>
            <li v-for="(item, index) in move" :key="index">{{item}}</li>
        </ul>
    </div>
    <script>
        const circulation = new Vue({
            el: "#circulation",
            data: {
                move: ['奥特曼', '哪吒','娜扎','娃哈哈']
            }
        })
    </script>

    <!-- 
        3. 点击按钮 修改 count 的值
            1. 创建computed元素
            2. 班定 count 数据
            3. 添加methods 方法, 使用 v-on:click 方法  语法糖:@
     -->
     <div id="computed">
        <div>
            <p>{{count}}</p>
            <button @click="increase">+</button><button v-on:class="decrease">-</button>
        </div>
    </div>
    <script>
        const computed = new Vue({
            el: "#computed",
            data: {
                count: 1,
                currentIndex: 0
            },
            methods: {
                // increase 增加  decrease 减少
                // 下面的方法为 ES6写法 increase() {}  ===    increase: function() {}
                increase() {
                    this.count++
                },
                decrease: function() {
                    this.count--
                }
            }
        })
    </script>
        <!--
            4.  MVVM  =>  model  view  view-model  数据, 视图, 视图模型 
            5.  
                1. methods 方法  
                2. function 函数
                3. Vue的生命周期
                4. 挂载
                5. 钩子
                6. 回调函数
        -->

02- 插值操作

<div id="app">
        <!-- 
            1. v-for:="item in students"
         -->
        <div>v-for 循环:  <span v-for="item in students">{{item + '-'}}</span></div>

        <!-- 
            2. v-once : 数据在往后的操作中都不会被修改
                1. 如 : 在浏览器开发者模式 修改 app.once="hhh", 页面中的{{once}}显示的内容不会发生改变       
         --> 
        <div>v-once :   <span v-once>{{once}}</span></div>
        <!-- 
            3. v-html : 
                将数据url 以html的标签值形式显示, 隐藏标签
            -->
        <div>正常显示:  <span >{{url}}</span></div>
        <div>v-html:  <span v-html="url"></span></div>
        <!-- 
            4.  v-text :  显示文本
            与{{}} 语法相同, 但不够灵活 => 一下 标签内的文本将不会显示, 而{{}}语法则正常拼接
         -->
        <div v-text="message">,你好啊</div>
        <div >{{message}},你好啊</div>
        <!-- 
            5. v-pre  保留 预先输出格式
         -->
         <div>{{message}}</div>
         <div v-pre>{{message}}</div>
         <!-- 
             6. v-cloak  斗篷
                 在vue 解析之前, div中有一个属性v-cloak
                 在vue 解析之后, div中没有一个属性v-cloak
                1. 斗篷的作用:  
                    1. 当浏览器加载页面 , vue 解析未结束前, 执行 v-cloak 属性
                    2. 当浏览器加载 vue解析后, v-cloack属性将删除

                // 假装以下样式在 <head>处
                <style>
                    [v-cloak] {
                        display: none;
                    }
                </style>
            -->
        <div >{{message}}</div>
        <!-- 
            7. 使用 v-bind 与 v-for 结合实现, 点击某一个值, 该值颜色变红
                1. v-for 语句拥有index属性值
                    1. 动态绑定class, 当设置的currentIndex 值 全等于index  时,active为真
                    2. 交互方法: 修改currentIndex 的值 = index
        -->
        <div class="box">
            <ul>
                <li v-for="(item, index) in students" @click="btnclick(index)" :key="index" :class="{active: currentIndex === index}">{{item}}</li>
            </ul>
        </div>
        
    </div>

 <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'hellow',
                once: '一次',
                students: ['小明','小红', '小兰'],
                url: '<a href="www.baidu.com">百度一下</a>',
                isActive: true,
                currentIndex: 0
            },
            methods: {
              btnclick(index) {
                  return this.currentIndex = index
              }
            }
        
            
        })
    </script>

03- 动态绑定属性

="app">
        <!-- 
            1. v-bind 绑定属性 => 语法糖 : 
                1. 绑定属性  :src  :value :class :title :href ... 
                2. 作用: 不写死数据, 在后台服务器请求数据, 动态修改属性值
        -->    
        <a v-bind:href="url">百度一下</a>
        <!-- 
            2 .对象语法: :class="{active:isActive}   
                           对象内可使用表达式或使用键值对{active:false, line:true}
         -->
        <p :class="{active:isActive}">动态修改文字颜色</p>
        <p :class="{active:false, line:true}">添加键值对</p>
        <button @click="btnClick">切换</button>

        <!--3.  数组语法:  一般不这么使用-->
        <h1 :class="[info_a, info_b]">获取类名</h1>
        <!-- 
            4.  使用方法 :  getClass()  , 添加了括号代表立即执行
         -->
         <h1 :class="getClass()">修改类名</h1>
        <!-- 
            5.  使用动态绑定 <style> 
                1. 对象语法
                    1. :style="{fontSize: '50px'}"
                    2. :style="{fontSize: finalSize + 'px'}"   => 此处finalSize 是data内的一个数据
                    3. :style="{'font-size': finalSize + 'px}'"
                2. 数组语法
                    1.  :style="[baseStyle, baseStyle1]"
          -->
    </div>

script>
        const app = new Vue({
            el: '#app',
            data: {
                url: 'www.baidu.com',
                isActive: true,
                info_a: 'aaa',
                info_b: 'bbbb',
                finalSize: 100,
                baseStyle: {background: 'red'},
                baseStyle1: {color: '#f00'}
            },
            methods: {
                btnClick() {
                    this.isActive = !this.isActive
                },
                getClass() {
                    // 将值返回
                    return [this.info_a, this.info_b]
                }
            }
        })
    </script>

04- 计算属性

  <div id="app">
        <!-- 
            1. methods 方法 => 每次调用都会刷新页面
            2. computed 计算属性 ,
                1. 有缓存,  每次调用时,当数据没有变化时, 将最后一次修改的结果返回
                2.  执行computed属性, 无需使用括号, 直接以数据的形式传入 mustan语法
                3. 当computed 修改了数据后, 缓存将会清空
         -->
         <p>总价格: {{totalPrice}}</p>
    </div>

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                books: [
                    {id: 1, name: 'html', price: 10},
                    {id: 2, name: 'java', price: 20},
                    {id: 3, name: 'css', price: 30},
                    {id: 4, name: 'python', price: 40}
                ]
            },
            computed: {
                totalPrice() {
                    let result = 0
                    // for (let i in this.books) {
                    // for (let i of this.books) {
                    for (let i=0; i<this.books.length; i++) {
                        result += this.books[i].price
                    }
                    return result
                }
            }
        })
    </script>

    <div id="computed">
        {{fullName}}
    </div>
    <script>
        const info_com = new Vue({
            el: '#computed',
            data: {
                first_name: 'kobe',
                last_name: 'jenny'
            },
            computed: {
                //  计算属性是一个对象, 对象内有set和get 两个函数方法,
                        // 每次调用都会执行set , get 而set方法一般很少使用, 则演变成了
                        //直接将get set 隐藏 , fullName : function() {} => fullName(){}
                fullName: {
                    set: function(info_value) {
                        //console.log('0000', info);  每次行计算属性都会执行set方法 
                        // 当开发者模式 修改 info_com.fullName= 'hha hahha' 时, 页面的fullName值将会改变
                        const names = info_value.split(' ')
                        this.first_name = names[0]
                        this.last_name = names[1]
                    },
                    get: function() {
                        return this.first_name + " " + this.last_name
                    }
                }
            }
        })
    </script>

05-事件监听

<div id='app'>
    <!-- 
        1. 当方法没有添加括号时, 触发后会返回一个event 值
     -->
    <button @click="btnClick">按钮1</button>
    <!-- 
        1.当添加了括号()  却没有传参, 则会输出 undefine
     -->
    <button @click="btnClick1()">按钮2</button>
    <!-- 
        1. 当函数由多个形参, 而调用函数传入实参的个数不够时, 未传入的形参将会输出undefine,
        2. 若要获取event,  则 $event 需要跟在形参的最后
        3. 当形参传入没有使用 引号时, 默认调用 data中的数据
     -->
    <button @click="btnClick2('index',$event)">按钮3</button>
    <button @click="btnClick2(index,$event)">按钮4</button>
    </div>
	<script src='../../vue.js'></script>
    <script>
    const app = new Vue ({
       el: '#app',
       data : {
           message: 'hah',
           index: 5
       },
       methods: {
           btnClick() {
               console.log(event)
           },
           btnClick1(info_index) {
               console.log(info_index);
           },
           btnClick2(info_index, event) {
               console.log(info_index, event);
           }
       }
    });
    </script>

06-v-on 修饰符

	div id='app'>
        <div>
            <p>{{message}}</p>
            <!-- 
                1. @click.stop  事件冒泡: 
                    1. 当父按钮不使用修饰符.stop时, 点击按钮将会触发父元素的parentBtn() 执行
                    2. .stop 阻止事件冒泡
             -->
            <div @click="parentBtn">
                <button @click.stop="childBtn">父按钮</button>
            </div>
            <!-- 
                2. @click.prevent 的使用
                    2. 当不使用 .prevent 修饰符时, 点击按钮将会提交并跳转页面  
                    1.  使用了修饰符后, 将会提交数据 并阻止页面跳转
             -->
             <div>
                 <input type="submit" value="提交" @click="childBtn">
             </div>
             <!-- 
                3. @click.enter 键盘监听
                4. @click.once 事件只允许触发一次
              -->

        </div>
    </div>
     
    <script>
    const app = new Vue ({
       el: '#app',
       data : {
           message: 'hah' 
       },
       methods: {
           parentBtn() {
               console.log('parent')
           },
           childBtn() {
               console.log('children')
           }
       }
    });
    </script>

07- 条件语句

 <div id='app'>

        <span v-if="isActive">
            <p>用户名 :  <input type="text" id="info_text" placeholder="用户"></p>
        </span>
        <span v-else>
            <p>邮箱: <input type="text" id="info_email" placeholder="邮箱"></p>
        </span>
        <button @click="btnClick">切换</button>
    </div>  
 <script>
    const app = new Vue ({
       el: '#app',
       data : {
           message: 'hah' ,
           isActive: true
       },
       methods: {
           btnClick() {
                this.isActive = !this.isActive
           }
       }
    });
    </script>

循环语句

    v-for :  
        1. item => 元素
        2. index = > 索引
        3. value => 值
        4. key 属性 : 高效的更新 虚拟DOM

        diff 算法 = 》  different 不同

    Array: 数组的方法
        1. arr.pop()  删除最后一个值
        2. arr.push(value) 在最后一个值添加
        3. arr.shift(value)  删除第一个值
        4. arr.unshift()    在最前面添加值
        5. arr.concat(arr)  拼接数组
        6. arr.join('符号')  在数组的值与值之间使用 符号拼接
        7. arr.splic()
        8. arr.sort()  
        9. arr.reverse()  倒叙
 <div id='app'>
    </div>
     
    <script src='../../vue.js'></script>
    <script>
        // 形参 ...num   代表剩余参数, 可在数组中使用 , === arguments
        function  computed(...num) {
            let sum = 0;
            return sum +=num;
        }
        console.log(computed(10,20,30,10,40,20))
    const app = new Vue ({
       el: '#app',
       data : {
           message: 'hah' 
       }
    
    });
    </script>

09- 图书馆购物车

<style>
        * {
            margin: 0;
            padding: 0;
        }
        body {
            background-color: #f6f6f6;
        }
        #app {
            position: absolute;
            left: 0;
            right: 0;
            top: 200px;
        }
        .table {
            width: 700px;
            border: 1px solid #ccc;
            text-align: center;
        }
        
        .table td {
            border: 1px solid #ccc;
            padding: 5px 10px;
            font-size: 14px;
        }
        .table thead tr td {
            font-weight: bold;
            font-size: 14px;
        }
    </style>
<div id='app'>
        <!-- 当 books 这个数组的长度大于0 则条件成立显示 购物栏, 否则将执行 v-else 语句 -->
        <div v-if="books.length">
            <table class="table">
                <thead>
                    <tr>
                        <td class="index"></td>
                        <td class="books_name">名称</td>
                        <td class="books_time">出版日期</td>
                        <td class="books_price">价格</td>
                        <td class="books_count">数量</td>
                        <td class="book_delete">移除</td>
                    </tr>
                </thead>
                <tbody>
                    <!-- 
                        1. v-for 循环遍历, 多个值 使用逗号隔开,并在括号内
                     -->
                    <tr v-for="(item, index)  in books">
                        <td>{{item.index}}</td>
                        <td>{{item.name}}</td>
                        <td>{{item.time}}</td>
                        <!-- 
                            1. fullToFix 是一个过滤器语句
                                相等于 {{"¥ " + item.price.toFixed(2)}}
                            2. 过滤器有形参 price, 使用时无需传入实参
                         -->
                        <td>{{item.price | fullToFix}}</td>
                        <td>
                            <!-- 
                                1. 使用index 来确定当前所点击的按钮属于第几行
                                2. :disable 语句执行的条件时当 书本的个数等于0时, 按钮不可点击
                             -->
                            <button @click="decreament(index)" :disabled="item.count === 0">-</button>{{item.count}}<button @click="increament(index)">+</button>
                        </td>
                        <td><button @click="btnClick(index)">移除</button></td>
                    </tr>
                </tbody>
            </table>
            <div class="totalprice">
                <p>总价格: {{totalPrice | fullToFix}}</p>
            </div>
            </div>
            <div v-else>
                <p>您的购物车为空</p>
            </div>
        </div>
     
ipt>
    const app = new Vue ({
       el: '#app',
       data : {
            books: [
                {
                    index: 1,
                    name: 'java',
                    time: '2020-1',
                    price: 10,
                    count: 1
                },
                {
                    index: 1,
                    name: 'javascript',
                    time: '2020-1',
                    price: 20,
                    count: 1
                },
                {
                    index: 1,
                    name: 'c++',
                    time: '2020-1',
                    price: 30,
                    count: 1
                },
                {
                    index: 1,
                    name: 'html',
                    time: '2020-1',
                    price: 40,
                    count: 1
                }
            ]
       },
       computed: {
          totalPrice() {
              let sum = 0;  
              for( let i in this.books) {
                sum+= this.books[i].price * this.books[i].count
              }
              return sum
          }  
       },
       methods: {
           increament(index) {
               /*
                  1. 操作的是books 这个数组内的count 值, 最终值要返回给这个数组中的某行的count
                  2. 若 要多此一举
                        @click="increament(item.count)"
                        increament(num) {
                            num++;
                            this.books.count = num;
                        }


               */
               this.books[index].count++
           },
           decreament(index) {
               this.books[index].count--
           },
           btnClick(index) {
            // 删除数组的某一行, 使用splice()
               this.books.splice(index, 1)
           }
       },
       filters: {
           fullToFix(price) {
               return  '¥ ' + price.toFixed(2) 
           }
       }
    });
    </script>

10-数组

<script>
        // 条件一: 在一个数组中, 将小于100的值取出
        var arr = [5,30,100,55,90,101,102,300,1055,105,1111,1422,1];
        var arr1 = []
        for(var i=0; i<arr.length;i++) {
            if(arr[i] <= 100) {
                arr1.push(arr[i])
            }
        }
        console.log(arr1);
        // 条件二: 将取出的值全部 *2
        var arr2 = [];
        for(var j=0; j<arr1.length;j++) {
            arr2.push(arr1[j] *2)
        }
        console.log(arr2);
        // 条件三: 将取出的值*2后汇总
        var sum=0;
        // for (var b=0; b<arr2.length;b++) {
        for(var b of arr2){
            sum+= b
        }
        console.log(sum);

        /*
            以原生的方法将以上三个条件输出, 语句太过于麻烦, 而是用封装好的高阶函数,则更加简洁
            1. 使用链式调用 同时执行三个条件语法

            2. 
                flite() 起到过滤的效果, 将执行条件返回
                map()  起到加工的作用。 将返回的值 进行*2 加工
                reduce() 功能最强大

        */
        let newarr = [];
        let total = arr.filter(function(i) {
            return i <= 100
        }).map(function(i){
            return i*2
        }).reduce(function(prevalue,i){
            return prevalue + i
        },0)
        // console.log(arr)
        console.log(total)

        let newarr2 = [];
        let totalNum = arr.filter(i => i<=100).map(i => i*2).reduce((prevalue, i) => prevalue + i)
        console.log(totalNum)

    </script>

11- 组件化思想


组件:
1. 将一个模版封装成模块, 在多个地方使用。 => 建立一次, 多次使用
2. 便于维护, 对于后期的修改较友好

    1. 全局组件: 
        1. 创建模版
            1. 在Vue 实例之间 使用 Vue.extend(模版)
                1. extend() 值 可以使用 `template: html元素`  在extend 内创建模版
                2. extend() 值 可以使用 ``template: htmlID    在HTML中创建模版, 使用id值绑定
                    1. HTML中使用 <template  id="tel">...元素内容</template> 
                    2. extend(`template: "#tel"`)
                    
                    1. HTML 中使用<script type="text/x-template">
        2. 注册组件
            1. Vue.component('HTML中使用的标签名', 注册时赋值的常量)
        3. 使用组件  挂载到 vue 实例上
            1. 因注册的是全局组件, 则可在各个实例中 使用 所注册的标签名调用 
            2. 若在Vue实例外使用, 则是个无效的标签

        4. 组件注册的语法糖语法: 
            1. 不使用 Vue.extend() 方法, 直接将 模版放置 components属性内, 
                components: {
                    template: `<div>...</div>`
                }

    2. 局部组件: 
        1. 创建模版
            1. 模版的创建方法 与 全局组件一样
            2. 创建一个 .vue 文件, 并将接口导出  
                 1.  export {组件名}  => 调用时必须使用这个组件名                         
                 2.  export default {组件名}  => 调用时可使用自主创建的组件名
        2. 注册组件
            1. 方法一: 注册的方式和全局组件一致
            2。方法二: 
                1. 调用导出的接口 使用 import 组件名 from 文件路径  (若是在某个子组件中调用, 则需要在该组件的script 标签内 引用接口)
                2. 在Vue 实例中 使用 components 属性 添加
        3. 使用组件 (只允许在注册的Vue实例中使用)


    3. 父组件与子组件
        1. 父组件中插入子组件: 
             1. 在父组件的 模版内使用 子组件的元素名
             2. 并在父组件的conponents 属性中注册子组件
             3. 子组件的创建要在父组件之前, javascript 是循规蹈矩, 由上至下运行, 
                当子组件在父组件之后创建,父组件注册的组件将无法获取到子组件的信息,发生错误

    
    4. 组件属性: 
        1. data  =>  组件中的data属性必须是个函数, 函数的值是独立的  data(){}
        2. props:  父传子     (properties 属性)
            1. 父组件 内 创建数据 =>  在data:{move:['海王','海贼王 ',' 电影']} 中创建数据
            2. 子组件创建props 属性,设置要使用的值, 在父组件模版中 传入值给子组件
                1. 使用数组: 
                    1. 子组件属性 props: ['cmove', 'cmessage']  => 创建要获取数据的名称
                    2. 在父组件的模版中,动态传递数据
                        1. <cpn :cmove="move" :cmessage="message"></cpn>  (cpn 是子组件的元素名)
                        2. 在子组件的模版内就是使用数据
                            1. <template> <p>{{cmessage}} {{cmove}}</p></template>
                2. 使用对象: 
                    1. 子组件属性 props: {
                                            cmessage: {type: String, default: aaa},
                                            cmove: {type: Array, required: true}  
                                                                => required 必传属性,否则报错
                                            ** 当获取传递值的类型为对象或数组时,默认值必须是个函数, 否则会报错
                                            **  default (){
                                                    return []
                                                }
                                          }
      
                    2. 在父组件的模版中,动态传递数据
                        1. <cpn :cmove="move" :cmessage="message"></cpn>  (cpn 是子组件的元素名)
                        2. 在子组件的模版内就是使用数据
                            1. <template> <p>{{cmessage}} {{cmove}}</p></template>

                    3. 当props 使用驼峰标识时, props: ['strStr']
                       在模版中的使用必须将 驼峰形式以 '-' 拼接的方式输出 => html 解析dom无法识别驼峰
                        如:  <cpn :cstr-str="str">  而使用mus语法则无需转换 <p>{{strStr}}</p> 
        3. $emit()  子传父
            1. 子组件创建数据 data(){ books: [....]}
            2. 子组件模版创建按钮 , <button @click="btnClick(item)" v-for="item in books">{{item}}
            3. 子组件methods属性创建方法 发射数据给父组件
                1. methods: { btnClick(item){this.$emit('childbtn', item)}}
                2. ↑ 'childbtn' 是自定义方法名,  item 是数据本身event
            4. 父组件模版
                1. 父组件methods 属性创建btnClick的方法
                2. 在子组件 标签<cpn @childbtn="btnClick">   👈 @childbtn 是子组件发射来的方法
  <div id='app'>
        <cpn :cmove="move" :cmessage="message" @childbtn="btnClick"></cpn>
    </div>
    <div id='banner'>
        <cpn/>
    </div>
    <script src='../../vue.js'></script>
    <script>
    
    //创建子组件, 并在父组件中使用
    const cpn_child = Vue.extend({
        template: '<div>我是子组件</div>',
        // methods: {
        //     btnClick(item){
        //         // 按钮点击, 子组件发射一个自定义名为 'childBtn'的方法, 并将item传送回去给父组件
        //         this.$emit('childbtn', item);
        //     }
        // }
 
    })
    // 父组件 
    const cpm = Vue.extend({
        template: `
            <div> 
                <p>插入模版</p>
                <p>{{cmove}}</p>
                <p>{{cmessage}}</p>
                <div>
                    <button @click="btnClick(item)" v-for="item in books">{{item.name}}</button>
                </div>
                <cpn_child/>    
            </div>
        `,
        components: {
            cpn_child
        },
        data(){
            return {
                books: [
                    {
                        id:1,
                        name: '按钮1'
                    }, {
                        id:2,
                        name: '按钮2'
                    },
                    {
                        id:3,
                        name: '按钮3'
                    },
                    {
                        id:4,
                        name: '按钮4'
                    }
                ]
            }
        },
        // 子组件, 使用props 创建获取父组件数据的名称
        // props: ['cmove', 'cmessage']
        props: {
            cmove: {
                type: Array,
                default() {
                    return []   // 当属性类型为数组或对象时,必须使用工厂函数, 否则会报错
                }
            },
            cmessage: {
                type: String,
                default: 'aaa',
                // required: true   // 必须传值, 否则报错
            }
        },
        methods: {
            btnClick(item){
                // 按钮点击, 子组件发射一个自定义名为 'childBtn'的方法, 并将item传送回去给父组件
                this.$emit('childbtn', item);
            }
        }
        
        
    })
    
    // 全局组件 cpn
    Vue.component('cpn', cpm)
    // 创建 Vue 实例 app
    const app = new Vue ({
       el: '#app',
       data : {
           message: 'hah' ,
           move: ['海王','海贼王 ',' 电影']
       },
       methods: {
           btnClick(item){
               console.log(item)
           }
       }
    });
    // 创建实例  banner 
    const banner = new Vue({
        el: '#banner'
    })
    </script>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值