Vue组件和模块化

作者: 追逐_chase | 来源:发表于2018-09-30 13:15 被阅读2次
    Vue.jpeg

    组件

    • 组件为了拆分Vue实例的代码量,能够让我们以不同的组件,来划分不同的功能模块,需要什么样的功能就使用对应的组件

    • 组件化:是从UI界面的角度划分;方便代码分层开发,保证功能模块的单一

    • 模块化:是逻辑代码的角度划分,前端组件化,方便UI组件的重复利用

    创建组件方式一

     <script src="node_modules/vue/dist/vue.js"></script>
    
    
    //组件的使用
    <div id="app">
        <!--
        自定义的组件
        注意:myComl在写成元素的时候 驼峰命名不在适用,需要在中间添加一个 - 链接 my-coml
        若是在命名的时候没有驼峰命名,在引用的时候就不必在使用 - 链接,直接使用可以了
        -->
        <my-coml></my-coml>
    
    </div>
    
    
    <script>
    
        //1创建全局的Vue组件  模板对象
       var coml =   Vue.extend({
            //指定组件要展示的html结构
            template:"<h2> 这是使用Vue.extend创建的组件</h2> "
    
        })
    
        //Vue.component("组件的名称",创建出来的组件模板对象)
        Vue.component("myComl",coml)
    
    //实例创建
        new Vue({
            el:"#app",
    
        })
    </script>
    
    
    

    创建方式二

    <script src="node_modules/vue/dist/vue.js"></script>
    
    <div id="app">
        <mycmol></mycmol>
    </div>
    
    
    <script>
        //创建组件 在模板对象直接用对象代替
        Vue.component("mycmol",{
            data:function () {
    
                return {
                    count:0
                }
            },
            template:`<div>
    <h1>这是第二种创建组件的方式</h1>
     <button @click='count++'>这是开始{{count}}</button>
    </div>`
        })
    
        new Vue({
    
            el:"#app"
        })
    </script>
    
    
    • 注意:在创建模板时,必须要只有一个根元素,所以需要用容器元素包裹子元素
    • 组件可以有自己的data,但是组件的data是一个function(函数),必须返回一个对象

    创建方式三

    //引包
       <script src="node_modules/vue/dist/vue.js"></script>
    
    //HTML
    </div><div id="app">
        <mycoml3></mycoml3>
    </div>
    
    <!--模板代码结构-->
    <template id="teml">
        <div>
            <h1>这是通过template元素创建的组件的结构</h1>
            <h4>这样方便些html元素</h4>
        </div>
    
    
    //JS
    <script>
        //创建组件
        Vue.component("mycoml3",{
            template:"#teml"
        })
    
        new Vue({
            el:"#app"
        })
    </script>
    
    

    定义私有组件

    
    <div id="app">
        <login></login>
    
    </div>
    
    <script>
    
    
    
        new Vue({
            el:"#app",
            components:{
                //定义私有组件
                //组件的名称
                login:{
                  //模板对象字符串
                    template:`<div>
                            <label>
                            name:
                            <input type="text" placeholder="登录。。。">
                             </label>
    
                          </div>`
                }
    
            }
    
    
        })
    </script>
    

    多个组件之间的切换

    • Vue中提供了component元素,这是一个占位符元素,可以根据:is属性来绑定要显示的元素
      <component :is="comName"></component>
    <div id="app">
    
        <a href="" @click.prevent="loginHandle">登录</a>
        <a href="" @click.prevent="registerHandle">注册</a>
        <a href="" @click.prevent="forgetHandle">忘记密码</a>
    
        <!--Vue提供的component元素,来展示对应名称的组件-->
        <!--component是一个暂未符 根据:is属性 后面对应的名称 来展示对应的组件-->
        <component :is="comName">
      <!--绑定一个属性 变量  根据@click点击方法 赋值 切换组件-->
        </component>
    </div>
    
    
    <script>
    
        Vue.component("login",{
    
            template:"<h2>登录组件</h2>"
        })
    
        Vue.component("register",{
    
            template:"<h2>注册组件</h2>"
        })
    
        Vue.component("forget",{
            template:"<h2>忘记密码组件</h2>"
        })
    
    
        new Vue({
            el:"#app",
            data:{
            //默认显示 登录组件
                comName:"login"
            },
            methods:{
    
                loginHandle:function () {
                    this.comName = "login"
                },
                registerHandle:function () {
    
                    this.comName = "register"
                },
                forgetHandle:function () {
                    this.comName = "forget"
                }
    
            }
    
        })
    </script>
    
    

    多个组件之间的过渡

    • 就按照上面的代码例子说 我们只需要加一个transition元素
    • 注意:多个组件之间的过渡有一个mode属性,mode="out-in表示一个组件包动画先离开完全之后,另外一个组件在进来
    
    //样式
     .v-enter,
            .v-leave-to{
                opacity: 0;
                transform: translateY(50px);
            }
    
            .v-enter-active,
            .v-leave-active{
    
                transition: all 0.5s ease;
            }
    
    
      <transition mode="out-in" >
    
            <!--Vue提供的component元素,来展示对应名称的组件-->
            <!--component是一个暂未符 根据:is属性 后面对应的名称 来展示对应的组件-->
            <component :is="comName">
                <!--绑定一个属性 变量-->
    
            </component>
    
        </transition>
    

    父组件传值子组件

    <div id="App">
        <!--父组件,在引用子组件的时候,可以通过属性绑定(v-bind:)的方式,把需要传递的数据给子组件-->
        <coml :parmsg="msg"></coml>
    </div>
    
    
    
    <script>
        new Vue({
            el:"#App",
            data:{
                msg:"父组件是不是?"
    
            },
            methods:{
    
            },
            components:{
                coml:{
                    data:function () {
                    //字组件中的data数据 ,并不是父组件传递的,是子组件私有的
                        //比如:子组件通过Ajax,请求回来的数据,可以放到data身上
                        //data里面的数据是可读可写的
                        return {
                            title:"这是一个标题",
                            content:"www"
                        }
                    },
                    template:`<h1>这是一个子组件的H1++{{parmsg}}++{{title}}</h1>`,
                    //绑定好属性之后,在props中 写入这个属性,这样才可以使用这个数据
                    // 组件中的所有props中的数据,都是通过父组件传递给子组件的
                    //里面的数据之可读的
                    props:["parmsg"]
    
                }
            }
        })
    
    
    
    
    • 小总结
      • 父组件在向子组件传值时
      • 1.通过属性绑定(v-bind:)定义一个新的属性
      • 2.将这个新的属性写入props数组,这个里面的数据只可读,不可更改,否则报错

    父组件传递方法给子组件

    • v-on方属性绑定
    <div id="app">
        <!--父组件传递方法给子组件-->
        <teml @func="show"></teml>
    </div>
    
    
    <!--模板---子组件-->
    <template id="tml">
        <div>
            <h1>子组件现不现实</h1>
    
            <input type="button" value="子组件" @click="myclick">
    
        </div>
    
    </template>
    
    
    <script>
        new Vue({
            el:"#app",
            data:{},
            methods:{
                show(){
                    console.log("点击父组件上的方法");
                }
            },
            components:{
                teml:{
                    data:function () {
    
                        return{}
                    },
                    template:"#tml",
                    props:[],
                    methods:{
                        myclick:function () {
    
                            console.log("是不是点击");
                            //拿到父组件的方法,调用
                            //emit出发 调用
                            this.$emit("func");
                        // 注意如果父组件上的函数有参数,那么这个 emit的第二个参数起,就是父组件函数参数与之对应
                    //调用父组件中的方法,并向父组件方法中传递参数this.$emit("func",123,456);
                        }
                    }
    
    
                }
    
            }
    
    
        })
    </script>
    
    

    小案例

    • 结合组件的的介绍点训练
    //引包, Vue.js 和  bootstrap
     <script src="node_modules/vue/dist/vue.js"></script>
        <link rel="stylesheet" href="lib/bootstrap-3.3.7.css">
    
    
    //Html
    
    <div id="app">
    
            <!--父组件 向 子组件传递方法 -->
            <temp @func="loadCommtent"></temp>
    
    <ul class="list-group">
        
        <li class="list-group-item" v-for="item in list" :key="item.id">
            <span class="badge">评论人:{{item.name}}</span>
            {{item.content}}
        </li>
       
    </ul>
    
    </div>
    
    
    //模板字符串
    <template id="tmp1">
        <div>
            <div class="form-group ">
             <label >评论人:</label>
             <input type="text" class="form-control" v-model="name">
            </div>
            <div class="form-group ">
                <label >评论内容:</label>
               <textarea class="form-control" v-model="content"></textarea>
               </div>
    
            <div class="form-group">
                <input type="button" value="发表评论" class="btn btn-primary" @click="postComment">
            </div>
        </div>
    </template>
    
    
    //JS
    
    <script>
    
        var contentbox = {
            data:function () {
                return {
    
                    name:"",
                    content:""
    
                }
            },
            template:"#tmp1",
            methods:{
                //发表评论的方法
                postComment(){
                    //1.数据存到 本地 localStorage
                    //2.localStorage只支持字符串,把对象转化成json字符串,在之前要处理判断
                    //是否有字符串
                    //3.若是localStorage中的评论字符串,为空不存在,则可以返回一个`[]`让json.parse转换
                    if (!this.name || !this.content) {
                        alert("请正确输入。。。")
                        return;
                    }
                    var comment = {id:Date.now(),name:this.name,content:this.content};
                    
                    //获取本地数据
                    var list = JSON.parse(localStorage.getItem("cms") ||"[]");
    
                    list.unshift(comment);
    
                    //保存数据到本地
                    localStorage.setItem("cms",JSON.stringify(list));
    
                    //清空属性数据
                    this.name = this.content = "";
    
                    this.$emit("func");
                    
                
    
                }
            }
        }
    
        new Vue({
    
            el:"#app",
            data:{
                list:[
                    {id:Date.now(),name:"TT",content:"这是一个新的评论"},
                    {id:Date.now(),name:"CC",content:"CC这是一个新的评论"},
                    {id:Date.now(),name:"DD",content:"DD这是一个新的评论DDDD"}
    
                ]
            },
            created() {
                this.loadCommtent();
            },
            methods:{
                loadCommtent:function () {
                    //获取本地数据
    
                   var list = JSON.parse(localStorage.getItem("cms")||"[]");
                    //赋值给list属性
                   this.list = list;
    
                    
                }
            },
            components:{
                temp:contentbox
            }
    
        })
    </script>
    
    

    render渲染

    • render属性对应的是一个方法函数,这个函数有一个固定的形参createElements是一个方法,当你把 模板组件传入的时候,返回一个渲染的页面html, 这个方法会把原来的div删除,把返回的html渲染删除的div界面
     <div id="app">
    
        </div>
    
    <script>
        var login = {
            template:"<h1>这是登录组件</h1>"
        }
    
        new Vue({
            el:"#app",
            data:{},
            methods:{},
            render:function(createElements){
                //createElements是一个方法,调用它,能够把指定的组件模板,渲染为html结构
                return createElements(login);
                //注意:返回的结果会替换页面中 指定的那个容器(也就是会把页面中的div删除掉,把这个返回的代替原来删除的)
            }
    
        })
    
    </script>
    
    
    

    喜欢文章的👍一下,谢谢,有想学习[web]可以私聊我。

    image.png

    相关文章

      网友评论

        本文标题:Vue组件和模块化

        本文链接:https://www.haomeiwen.com/subject/nkodoftx.html