<div>{{uage *2}}</div>&#...">
最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue基础

    正文概述 掘金(H_pig)   2021-07-19   473

    一、 Vue基础

    一、 模板语法

    1.1数据绑定

    1.1.1文本,v-text、{{}}

    	<div id="app">
    		<div>
    			{{uage *2}}
    		</div>
    		<div v-text="uage"></div>
    	</div>
    
    <script>
    	const app = new Vue({
    		el:'#app',
    		data:{
    			uage:10
    		}
    	})
    </script>
    

    1.1.2 v-once:

    只将数值绑定一次

    	<div id="app">
    		<div v-once>
    			{{uage}}
    		</div>
    	</div>
    

    1.1.3v-pre:

    将标签内的内容不编译进行渲染

    	<div id="app">
    		<div v-pre>
    			{{uage *2}}
    		</div>
    	</div>
    

    1.1.4v-cloak:

    使数据加载之后才渲染页面

    	<div id="app">
    		<div v-cloak>
    			{{uage *2}}
    		</div>
    	</div>
    

    1.1.5 v-html

    插入带html的字符

    	<div id="app">
    		<div v-html ='url'>
    		</div>
    	</div>
    
    <script>
    	const app = new Vue({
    		el:'#app',
    		data:{
    			uage:10,
    			url:'<a href="http://www.baidu.com">ddd</a>'
    		}
    	})
    </script>
    

    1.1.6v-bind:

    动态绑定属性值

    语法糖::

    	<div id="app">
    		<a v-bind:href= "url">
    			我是百度
    		</a>
    	</div>
    
    <script>
    	const app = new Vue({
    		el: '#app',
    		data: {
    			uage: 10,
    			url: 'http://www.baidu.com'
    		}
    	})
    </script>
    
    		.active {
    			color: red;
    		}
    
    		.uncheck {
    			color: yellow;
    		}
    		.green{
    			color: green;
    		}
    
    <script>
    	const app = new Vue({
    		el: '#app',
    		data: {
    			isActive: true,
    			isUncheck: false
    
    		},
    		methods: {
    			btnClick: function () {
    				this.isActive = !this.isActive,
    					this.isUncheck = !this.isUncheck
    
    			},
    			getClass:function(){
    				return  {active:this.isActive,uncheck:this.isUncheck}
    			}
    		}
    	})
    </script>
    

    用法一:直接使用{}绑定一个class

    		<div :class={active:true}>
    			我是直接绑定的样式
    		</div>
    

    用法二:使用变量传入boolean类型控制多个class是否生效

    		<div @click="btnClick" :class="{active:isActive,uncheck:isUncheck}" >
    			我要变色了
    		</div>
    

    用法三:与其他class共同使用,样式冲突的情况下以到单独写的class为主

    		<div @click="btnClick" :class="{active:isActive,uncheck:isUncheck}"class="green" >
    			我要变色了
    		</div>
    

    用法四:如果过于复杂,可以放在一个methods或者computed中

    		<div @click="btnClick" v-bind:class="getClass()" >
    			我要变色了
    		</div>
    //调用方法的时候可以选择不加括号 
    

    使用数组绑定class:

    		<div :class= "['green','fontClass']" class="active" >
    			我绑定了好几个class哦~
    		</div>
    

    这样驻足绑定的方法可以使用data中的变量,也不与单独写的class冲突 但是在渲染的时候,是优先渲染内联class,所以如果有样式重叠,绑定的样式会覆盖掉内联class,截图如下:

    Vue基础

    • v-bind绑定style

      		<div :style="{fontSize:'30px'}">我绑定了style</div>
      		<div :style="{color:color,fontSize:fontSize+'px'}">我也绑定了style</div>
      
      		data: {
      			color: "red",
      			fontSize:30
      
      		},
      
            computed: {
                fullName:function(){
                    return this.firstName + ' ' + this.lastName;
                }
            },
    

    1.1.7v-model

    在表单上创建双向绑定,v-model会忽略所有表单元素的value,checked,selected属性 初始值,而选定Vue实例数据为具体值。

    <body>
        <div id="app">
            <input type="text" v-model = "userName">
            <p>{{userName}}</p>
        </div>
    
    </body>
    <script>
        const app = new Vue({
            el:"#app",
            data:{
                userName:"hong"
            }
        })
    </script>
    

    v-model的相关使用:

    <body>
        <div id="app">
            <!-- v-model与radio的配合使用 -->
    
            <label for="male">
                <input id="male" type="radio" name="sex" v-model="sex" value="男">男
            </label>
            <label for="female">
                <input id="female" type="radio" name="sex" v-model="sex" value="女">女
            </label>
            <p>选中的性别是:{{sex}}</p>
            <!-- v-model与checkBox的配合使用 -->
            <!-- <input type="checkbox" value="篮球" v-model="checked">篮球
            <input type="checkbox" value="足球" v-model="checked">足球
            <input type="checkbox" value="乒乓球" v-model="checked">乒乓球
            <input type="checkbox" value="羽毛球" v-model="checked">羽毛球
            <input type="checkbox" value="橄榄球" v-model="checked">橄榄球
            <input type="checkbox" value="高尔夫" v-model="checked">高尔夫 -->
            <label v-for= "item in hobbies" :for="item" >
                <!-- 注意label的for与input的id都需要动态绑定,input的value也是需要动态绑定的 -->
                <input type="checkbox" :value="item" :id="item" v-model= "checked" >{{item}}
            </label>
            <p>我选中了{{checked}}</p>
            <!-- v-model与select配合使用 -->
            <select  name="" id="" v-model= "checkBooks" multiple>
                <option v-for = "item in books" :value="item">{{item}}</option>
            </select>
            <p>我选中了:{{checkBooks}}</p>
        </div>
    
    </body>
    <script src="../js/vue.js"></script>
    <script>
        Vue.component('cpn', cpnC)
        const app = new Vue({
            el: '#app',
            data: {
                // 给单选框一个默认值“男”
                sex: '男',//单选
                checked: [],//多选
                hobbies:["足球","乒乓球","羽毛球","橄榄球","高尔夫"],
                books:["钢铁是怎样炼成的","啊","Linux该怎么学","前端好难","努力学习"],
                checkBooks:[]
            },
        })
    </script>
    

    1.1.7.1model修饰符

    1. .lazy

      默认情况下v-model是实时同步输入框的值和数据,加上.lazy后变为触发change时间后再同步(即相当于修改后要按下回车,或点击其他位置后才触发数据同步)

      <input type="text" v-model.lazy = "userName">
      
    2. .number

      将用户输入的内容转化成数值类型,转化规则与js的Number()的规则相同

      详见w3shool的JS数据类型转换

      <input type="text" v-model.number = "userName">
      
    3. .trim

      过滤掉输入框的首位空格

      <input type="text" v-model.trim = "userName">
      

    1.2事件绑定

    1.2.1 v-on

    作用:绑定事件监听器

    语法糖:@

    参数:event

    1.2.1.1基本使用

    使用v-on绑定事件

    • 一个元素上可以绑定多个不同的事件
    • 事件的绑定也可以通过methods中定义函数的方法来实现绑定
    • 当定义的事件没有参数,所以我们在调用方法的时候不需要添加()
    <body>
        <div id="app">
            <p>{{total}}</p>
            <!-- 一个元素上可以绑定多个不同的事件 -->
            <div class="div1" @mouseout = "total++" @click = "total--"></div>
            <!-- 事件的绑定也可以通过methods中定义函数的方法来实现绑定 -->
            <!-- 因为现在定义的事件没有参数,所以我们在调用方法的时候不需要添加() -->
            <button v-on:click = "reduce">-</button>
            <button v-on:click = "increase">+</button>
        </div>
    
    </body>
    <script>
        const app = new Vue({
            el:"#app",
            data:{
                total:1
            },
            methods:{
                // 定义total增加的函数
                increase(){
                    this.total++;
                },
                // 定义total减少的函数
                reduce(){
                    this.total--;
                }
    
            }
        })
    </script>
    

    1.2.1.2事件监听传参

    • 当方法需要参数但未传递实参,会将event对象当成默认参数返回
    • 正常传递参数
    • 当需要传递其他参数和event的时候,需要借助$event实现​
    <body>
        <div id="app">
            <!-- 省略参数,会将event事件当成默认的参数返回 -->
            <button @click = "clickBtn">按钮</button>
            <!-- 传递所需参数 -->
            <button @click = "clickBtn1('sss')">按钮</button>
            <!-- 同时传递需要的参数和event,使用vue封装的$event进行传参 -->
            <button @click = "clickBtn2(123,$event)">按钮</button>
            
        </div>
    
    </body>
    <script>
        const app = new Vue({
            el:"#app",
            data:{
    
            },
            methods:{
                clickBtn(){
                    console.log(event);
                },
                clickBtn1(a){
                    console.log(a);
                },
                clickBtn2(a,event){
                    console.log(a,event);
                }
    
            }
        })
    </script>
    

    1.2.2 v-on的修饰符

    • .stop调用了event。stopPropagation()
    • .prevent调用event.preventDefault()
    • .{keyCode|keyAlias}是事件只从特定按键触发时才触发回调
    • .native 监听组件根元素的原生事件
    • .once 只触发一次回调
            <!-- 阻止冒泡 -->
            <button @click.stop = "clickBtn">按钮</button>
            <!-- 阻止默认行为 -->
            <button @click.prevent = "clickBtn">按钮</button>
            <!-- 阻止默认行为,没有表达式 -->
            <form @submit.prevent></form>
            <!-- 串联修饰符 -->
            <button @click.stop,prevent = "clickBtn">按钮</button>
            <!-- 按键别名,键盘上的名称 -->
            <input @keydown.+ = "onEnter">
            <!-- 按键代码,按键对应的代码数字 -->
            <input @keydown.13 = "onEnter">
    

    1.2.2 v-if、v-else、v-else-if

    1..2.2.1 v-if、v-else

    v-if与js的if用法相同,是通过v-if = ""引号中的Boolen值去进行判断,如果为false就隐藏元素是true就显示

    <body>
        <div id="app">
            <div v-if="isShow">true</div>
            <div v-else>false</div>
            <button @click="changeClick">切换</button>
    
        </div>
    
    </body>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                isShow: true
            },
            methods: {
                changeClick() {
                    this.isShow = !this.isShow;
                }
            }
        })
    </script>
    

    1.2.2.2v-else-if

    用处不多,不赘余

        <div id="app">
            <div v-if="score >90 ">优秀</div>
            <div v-else-if="score >80 ">良好</div>
            <div v-else-if="score > 60">及格</div>
            <div v-else>不及格</div>
        </div>
    

    1.3 v-for循环遍历

    用法与for…in相同,详见w3school的for…in介绍

    1.3.1循环数组

    1.3.1.1无索引循环

    <body>
        <div id="app">
            <ul>
                <li v-for = "item in names" v-block>{{item}}</li>
            </ul>
        </div>
    
    </body>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                names:["h","w","l","g","z"]
            },
            methods: {
            }
        })
    </script>
    

    1.3.1.2 有索引循环

    • 加一个小括号,里面加上item和index
            <ul>
                <li v-for = "(item,index) in names" v-block>{{index}}----{{item}}</li>
            </ul>
    

    1.3.2对象循环遍历

    1.3.2.1无key无索引遍历

    <body>
        <div id="app">
            <ul>
                <li v-for = "item in names" v-block>{{item}}</li>
            </ul>
        </div>
    
    </body>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                names:{
                    name:"hong",
                    age:18,
                    sex:"男"
                }
            },
            methods: {
            }
        })
    </script>
    

    1.3.2.2有key无索引遍历

            <ul>
                <li v-for = "(item,key) in names" v-block>{{key}}------{{item}}</li>
            </ul>
    

    1.3.2.2有key有索引遍历

     <ul>
      <li v-for = "(item,key,index) in names" v-block>{{key}}------{{item}}-----{{index}}</li>
    </ul>
    

    1.4(了解)如何正确使用key

    1. v-for使用时,为了能够更好的复用,我们在使用v-for的时候,需要搭配key属性的使用

      <body>
          <div id="app">
              <ul>
                  <li v-for = "item in names" key = "item">{{item}}</li>
                  <li v-for = "item in user" key = "item">{{item}}</li>
              </ul>
          </div>
      
      </body>
      <script>
          const app = new Vue({
              el: "#app",
              data: {
                  names:{
                      name:"hong",
                      age:18,
                      sex:"男"
                  },
                  user:["s","d","f","j"]
              },
              methods: {
              }
          })
      </script>
      

    二、计算属性

    2.1基本使用

        <div id="app">
            <div>{{fullName}}</div>
        </div>
    
            data: {
                firstName: 'zhang',
                lastName: 'san'
            },
            computed: {
                fullName: function () {
                    return this.firstName + ' ' + this.lastName;
                }
            },
    

    三、ES6语法

    1. 对象的增强语法

      ES5的创建方法

      var a = new Object();
      a.sname = "hong";
      
      var a = {
          sname = "hong"
      }
      
    2. ES6语法

      const sname =  "hong";
      var a = {
          sname,
      }
      //在es6的语法中,上面写法会吧sname当成key,将变量sname的值赋值给它
      

    四、组件

    4.1 全局组件与局部组件

    <body>
        <div id="app">
            <!-- 全局组件在哪里都可以调用 -->
            <global-c></global-c>
            <!-- 局部组件只有在注册的组件内才能调用 -->
            <cpn></cpn>
        </div>
        <div id="app2">
            <global-c></global-c>
            <!-- <cpn></cpn> -->
        </div>
    
    </body>
    <script src="../js/vue.js"></script>
    <script>
        // 定义组件
        const cpnC = Vue.extend({
            template: `        
            <div>
                <span>hhh</span>
                <input type="text">
            </div>
            `
        })
        // 全局组件注册
        Vue.component('globalCi', cpnC)
        const app = new Vue({
            el: '#app',
            data: {
    
            },
            // 局部组件注册
            components: {
                cpn: cpnC
            }
        })
        const app2 = new Vue({
            el: "#app2",
        })
    </script>
    

    4.2父子组件

    <body>
        <div id="app">
            <cpn></cpn>
        </div>
    </body>
    <script src="../js/vue.js"></script>
    <script>
        // 定义组件1
        const cpnC = Vue.extend({
            template: `        
            <div>
                我是组件1
            </div>  
            `
        })
        const cpnC2 = Vue.extend({
            template: `
            <div>
                我是组件2
                <!-- 将注册好的组件在父组件中调用-->
                <sonCpn></sonCpn>
            </div>
            `,
            components:{
                // 将组件1注册到组件2,此时组件1为字子组件,组件2为父组件
                sonCpn:cpnC
            }
        })
        const app = new Vue({
            el: '#app',
            data: {
    
            },
            // 在root根组件中注册组件2,在使用组件
            components: {
                cpn: cpnC2
            }
        })
        const app2 = new Vue({
            el: "#app2",
        })
    </script>
    

    4.2.1父子组件语法糖

    旧写法

        // 定义组件
        const cpnC = Vue.extend({
            template: `        
            <div>
                我是组件1
            </div>
            `
        })
        // 全局组件注册
        Vue.component('globalCi', cpnC)
    

    新写法

        Vue.component("ss",{
            template: `        
            <div>
                我是组件1
            </div>  
            `
        })
    //------------------------------------------
            components: {
                cpn: {
          template: `        
            <div>
                我是组件1
            </div>  
            `
                }
            }
    //-----------------------------------------------
    const cpn = {
         template: `        
            <div>
                我是组件1
            </div>  
            `
    }
    //在vue组件中定义
        const app = new Vue({
            el: '#app',
            components: {
                //ES6语法,key与value相同时,直接写一个就可以了
                cpn
            }
        })
    
    

    4.2.2将template抽离出来

    4.2.2.1使用script标签

    使用<script type="text/x-template"></script>标签将html代码包裹,并赋以ID值,实现html代码的剥离

    <body>
        <div id="app">
            <cpn></cpn>
            <cpn1></cpn1>
            <!-- <cpn2></cpn2> -->
    
        </div>
        <script type="text/x-template" id="test">
            <div>
                我是组件,但代码抽离了哦~
            </div>
        </script>
    
    
    </body>
    <script src="../js/vue.js"></script>
    
    <script>
        // 下面是注册全局组件的方式
        Vue.component('cpn', {
            template: "#test"
        })
    
        const app = new Vue({
            el: '#app',
            // 下面是注册局部组件的方式
            components: {
                cpn1: {
                    template: "#test"
                }
    
            }
        })
    </script>
    

    Vue基础

    4.2.2.2使用template标签

    使用<template></template>标签将html代码包裹,并赋以ID值,实现html代码的剥离

        <template id="test02">
            <div>
                hi~我是用template标签实现的
            </div>
        </template>
    

    实现方法与上面相同只是标签使用方法不同

    :low_brightness:注意,在组件中使用变量是可以的但是data要使用data(){}方法,用==return返回一个对象==的方式实现,如下

        // 下面是注册全局组件的方式
        Vue.component('cpn1',{
            template:"#test02",
            //data必须使用方法,然后return返回
            data(){
                return {
                    title:"我是标题"
                }
            }
        })
    

    4.2.3 父子组件传值

    4.2.3.1父传子
    • 通过props属性进行传值

      <body>
          <div id="app">
              <cpn :cmovies="movies"></cpn>
          </div>
          <!-- 下面的是子组件的html -->
          <template id="ccpn">
              <div>
                  {{cmovies}}
              </div>
          </template>
      </body>
      <script src="../js/vue.js"></script>
      <script>
          // 下面是子组件
          const cpn = {
              template: '#ccpn',
              props: ['cmovies'],
              data() {
                  return{
                  }
              }
          }
          // 下面是根组件也是父组件
          const App = new Vue({
              el: "#app",
              data() {
                  return {
                      movies: ['海王', '海贼']
                  }
              },
              components: {
                  cpn,
              }
      
          })
      </script>
      
    4.2.3.1.1 porps属性的使用
    • 动态props

      上面的代码就是动态的props

    • 静态props

      <body>
          <div id="app">
              <!-- props静态的赋值 -->
              <cpn cmovies="sss"></cpn>
          </div>
          <template id="ccpn">
              <div>
                  {{cmovies}}
              </div>
          </template>
      </body>
      
    • props验证

       props: { 
                          // 基础类型检测, null意味着任何类型都行
                          propA: Number,
                           // 多种类型
                          propB: [String, Number],
                           // 必传且是String
                          propC: {
                              type: String,
                              required: true
                          },
                           // 数字有默认值
                          propD: {
                              type: Number,
                              default: 101
                          },
                           // 数组、默认值是一个工厂函数返回对象
                          propE: {
                              type: Object,
                              default: function () {
                                  console.log("propE default invoked.");
                                  return {
                                      message: "I am from propE."
                                  };
                              }
                          }, 
                          // 自定义验证函数
                          propF: {
                              isValid: function (value) {
                                  return value > 100;
                              }
                          }
                      }
      

      单向数据流

      props 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件五一修改父组件的状态。

      所以不应该在子组件中修改 props 中的值,Vue 会报出警告。

      let childNode = {
        template: `
                <div class="child">
                  <div>
                    <span>子组件数据</span>
                    <input v-model="forChildMsg"/>
                  </div>
                  <p>{{forChildMsg}}</p>
                </div>`,
        props: {
          "for-child-msg": String
        }
      };
      let parentNode = {
        template: `
                <div class="parent">
                  <div>
                    <span>父组件数据</span>
                    <input v-model="msg"/>
                  </div>
                  <p>{{msg}}</p>
                  <child :for-child-msg="msg"></child>
                </div>
              `,
        components: {
          child: childNode
        },
        data() {
          return {
            msg: "default string."
          };
        }
      };
      

      这里我们给父组件和子组件都有一个输入框,并且显示出父组件数据和子组件的数据。当我们在父组件的输入框输入新数据时,同步的子组件数据也被修改了;这就是 props 的向子组件传递数据。而当我们修改子组件的输入框时,浏览器的控制台则报出错误警告

    • 修改 props 数据

      • 通常有两种原因:
      • prop 作为初始值传入后,子组件想把它当做局部数据来用
      • prop 作为初始值传入后,由子组件处理成其他数据输出

      应对办法是:

      • 定义一个局部变量,并用 prop 的值初始化它

      但是由于定义的 ownChildMsg 只能接受 forChildMsg 的初始值,当父组件要传递的值变化发生时,ownChildMsg 无法收到更新。

      let childNode = {
        template: `
                <div class="child">
                  <div>
                    <span>子组件数据</span>
                    <input v-model="forChildMsg"/>
                  </div>
                  <p>{{forChildMsg}}</p>
                  <p>ownChildMsg : {{ownChildMsg}}</p>
                </div>`,
        props: {
          "for-child-msg": String
        },
        data() {
          return { ownChildMsg: this.forChildMsg };
        }
      };
      

      这里我们加了一个

      用于查看 ownChildMsg 数据是否变化,结果发现只有默认值传递给了 ownChildMsg,父组件改变只会变化到 forChildMsg,不会修改 ownChildMsg。

      • 定义一个计算属性,处理 prop 的值并返回

        由于是计算属性,所以只能显示值,不能设置值。我们这里设置的是一旦从父组件修改了 forChildMsg 数据,我们就把 forChildMsg 加上一个字符串"---ownChildMsg",然后显示在屏幕上。这时是可以每当父组件修改了新数据,都会更新 ownChildMsg 数据的。

        let childNode = {
          template: `
                  <div class="child">
                    <div>
                      <span>子组件数据</span>
                      <input v-model="forChildMsg"/>
                    </div>
                    <p>{{forChildMsg}}</p>
                    <p>ownChildMsg : {{ownChildMsg}}</p>
                  </div>`,
          props: {
            "for-child-msg": String
          },
          computed: {
            ownChildMsg() {
              return this.forChildMsg + "---ownChildMsg";
            }
          }
        };
        
      • 更加妥帖的方式是使用变量存储 prop 的初始值,并用 watch 来观察 prop 值得变化。发生变化时,更新变量的值。

        let childNode = {
          template: `
                  <div class="child">
                    <div>
                      <span>子组件数据</span>
                      <input v-model="forChildMsg"/>
                    </div>
                    <p>{{forChildMsg}}</p>
                    <p>ownChildMsg : {{ownChildMsg}}</p>
                  </div>`,
          props: {
            "for-child-msg": String
          },
          data() {
            return {
              ownChildMsg: this.forChildMsg
            };
          },
          watch: {
            forChildMsg() {
              this.ownChildMsg = this.forChildMsg;
            }
          }
        };
        
      • 单向数据流

      props 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件五一修改父组件的状态。

      所以不应该在子组件中修改 props 中的值,Vue 会报出警告。

      let childNode = {
        template: `
                <div class="child">
                  <div>
                    <span>子组件数据</span>
                    <input v-model="forChildMsg"/>
                  </div>
                  <p>{{forChildMsg}}</p>
                </div>`,
        props: {
          "for-child-msg": String
        }
      };
      let parentNode = {
        template: `
                <div class="parent">
                  <div>
                    <span>父组件数据</span>
                    <input v-model="msg"/>
                  </div>
                  <p>{{msg}}</p>
                  <child :for-child-msg="msg"></child>
                </div>
              `,
        components: {
          child: childNode
        },
        data() {
          return {
            msg: "default string."
          };
        }
      };
      

      这里我们给父组件和子组件都有一个输入框,并且显示出父组件数据和子组件的数据。当我们在父组件的输入框输入新数据时,同步的子组件数据也被修改了;这就是 props 的向子组件传递数据。而当我们修改子组件的输入框时,浏览器的控制台则报出错误警告

    • 修改 props 数据

      通常有两种原因:

      • prop 作为初始值传入后,子组件想把它当做局部数据来用

      • prop 作为初始值传入后,由子组件处理成其他数据输出

      应对办法是

      • 定义一个局部变量,并用 prop 的值初始化它

        但是由于定义的 ownChildMsg 只能接受 forChildMsg 的初始值,当父组件要传递的值变化发生时,ownChildMsg 无法收到更新。

        let childNode = {
            template: `
                    <div class="child">
                      <div>
                        <span>子组件数据</span>
                        <input v-model="forChildMsg"/>
                      </div>
                      <p>{{forChildMsg}}</p>
                      <p>ownChildMsg : {{ownChildMsg}}</p>
                    </div>`,
            props: {
              "for-child-msg": String
            },
            data() {
              return { ownChildMsg: this.forChildMsg };
            }
          };
      

      这里我们加了一个

      用于查看 ownChildMsg 数据是否变化,结果发现只有默认值传递给了 ownChildMsg,父组件改变只会变化到 forChildMsg,不会修改 ownChildMsg。

      • 定义一个计算属性,处理 prop 的值并返回

        由于是计算属性,所以只能显示值,不能设置值。我们这里设置的是一旦从父组件修改了 forChildMsg 数据,我们就把 forChildMsg 加上一个字符串"---ownChildMsg",然后显示在屏幕上。这时是可以每当父组件修改了新数据,都会更新 ownChildMsg 数据的。

      let childNode = {
        template: `
                <div class="child">
                  <div>
                    <span>子组件数据</span>
                    <input v-model="forChildMsg"/>
                  </div>
                  <p>{{forChildMsg}}</p>
                  <p>ownChildMsg : {{ownChildMsg}}</p>
                </div>`,
        props: {
          "for-child-msg": String
        },
        computed: {
          ownChildMsg() {
            return this.forChildMsg + "---ownChildMsg";
          }
        }
      };
      
      • 更加妥帖的方式是使用变量存储 prop 的初始值,并用 watch 来观察 prop 值得变化。发生变化时,更新变量的值。
      let childNode = {
        template: `
                <div class="child">
                  <div>
                    <span>子组件数据</span>
                    <input v-model="forChildMsg"/>
                  </div>
                  <p>{{forChildMsg}}</p>
                  <p>ownChildMsg : {{ownChildMsg}}</p>
                </div>`,
        props: {
          "for-child-msg": String
        },
        data() {
          return {
            ownChildMsg: this.forChildMsg
          };
        },
        watch: {
          forChildMsg() {
            this.ownChildMsg = this.forChildMsg;
          }
        }
      };
      
    4.2.3.2 子传父
    • 在子组件中通过$emit()来触发事件。

    • 在父组件中通过v-on来监听子组件事件

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
      </head>
      <body>
          <!-- 父组件模板 -->
          <div id="app">
              <!-- 调用childMessage方法的时候如果省略参数,系统将会自动接收子组件方法传递过来的值 -->
              <cpn @btn-click = childMessage></cpn>
          </div>
          
      <!-- 子组件模板 -->
          <template id="cpn">
              <div>
                  <button @click = "logClick(item)" v-for = "item in categories">{{item.wname}}</button>
              </div>
          </template>
      </body>
      <script src="../js/vue.js"></script>
      <script>
          // 子组件
          const cpn ={
              template:"#cpn",
              data(){
                  return {
                      categories:[
                          {
                              id:1,
                              wname:'篮球'
                          },{
                              id:2,
                              wname:'乒乓球'
                          },
                          {
                              id:3,
                              wname:'羽毛球'
                          },
                      ]
                  }
              },
              methods:{
                  logClick(item){
                      // 这个输出是在子组件本身内完成的
                      console.log("我点击了",item.wname);
                      // 下面是将数据传递给父组件
                      this.$emit('btn-click',item.wname,)
                  }
              }
          }
          // 父组件
          const app = new Vue({
              el:'#app',
              data(){
                  return{
                  message:'hello'
      
                  }
              },
              methods:{
                  childMessage(arg){
                      console.log(arg);
                  }
              },
              components:{
                  cpn
              }
          })
      </script>
      </html>
      

    父子组间访问

    4.3.4.1 父访问子
    • $children

      Vue基础

      • 整体代码:
      <!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <script src="../js/vue.js" type="text/javascript"></script>
      </head>
      
      <body>
          <div id="app">
              <button @click="btnClick">按钮</button>
              <Cpn></Cpn>
          </div>
          <template id="cpn">
              <div>我是子组件</div>
          </template>
      </body>
      
      <script>
          //下面是子组件
          const Cpn = {
              template: '#cpn',
              // 子组件的data必须使用方法的形式
              data(){
                  return{
                      msg:"我是一条在子组件的消息"
                  }
              },
              methods: {
                  showMessage() {
                      console.log("sss");
                      return  "我是返回的内容"
                  }
              }
          };
        //下面是父组件  
          const app = new Vue({
              el: "#app",
              data() {
                  return {
                     
                  }
              },
              methods: {
                  btnClick() {
                      // 获取$children
                      console.log(this.$children);
                      // 获取子组件中的方法并调用
                      console.log(this.$children[0].showMessage());
                      // 获取子组件data中的变量
                      console.log(this.$children[0].msg)
                  },
              },
              components: {
                  Cpn
              }
          })
      </script>
      
      </html>
      
      • 关键代码:
       methods: {
                  btnClick() {
                      // 获取$children
                      console.log(this.$children);
                      // 获取子组件中的方法并调用
                      console.log(this.$children[0].showMessage());
                      // 获取子组件data中的变量
                      console.log(this.$children[0].msg)
                  },
              },
      
    • $refs

      • 在需要使用的子集上通过属性ref添加属性名

      • 在父级使用$refs.属性名来获取自组件中的数据

      • 整体代码

        <!DOCTYPE html>
        <html lang="en">
        
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
            <script src="../js/vue.js" type="text/javascript"></script>
        </head>
        
        <body>
            <div id="app">
                <button @click="btnClick">按钮</button>
                <Cpn ref="son" ></Cpn>
            </div>
            <template id="cpn">
                <div>我是子组件</div>
            </template>
        </body>
        
        <script>
            const Cpn = {
                template: '#cpn',
                // 子组件的data必须使用方法的形式
                data(){
                    return{
                        msg:"我是一条在子组件的消息"
                    }
                },
                methods: {
                    showMessage() {
                        console.log("sss");
                        return  "我是返回的内容"
                    }
                }
            };
            const app = new Vue({
                el: "#app",
                data() {
                    return {
                       
                    }
                },
                methods: {
                    btnClick() {
                        // // 获取$children
                        // console.log(this.$children);
                        // // 获取子组件中的方法并调用
                        // console.log(this.$children[0].showMessage());
                        // // 获取子组件data中的变量
                        // console.log(this.$children[0].msg)
        
                        // 打印$refs
                        console.log(this.$refs);
                        // 获取aaa的msg变量
                        console.log(this.$refs.son.msg);
                        // 获取aaa的方法
                        console.log(this.$refs.son.showMessage());
                    },
                },
                components: {
                    Cpn
                }
            })
        </script>
        
        </html>
        
      • 关键代码;

            btnClick() {
                // 打印$refs
                console.log(this.$refs);
                // 获取aaa的msg变量
                console.log(this.$refs.son.msg);
                // 获取aaa的方法
                console.log(this.$refs.son.showMessage());
            },
        
    • 子访问父(理解)

      • $parent

        • 完整代码

          <!DOCTYPE html>
          <html lang="en">
          
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>Document</title>
              <script src="../js/vue.js" type="text/javascript"></script>
          </head>
          
          <body>
              <div id="app">
                  <cpn ref="son"></cpn>
              </div>
              <!-- 下面是cpn子组件 -->
              <template id="cpn">
                  <div>
          
                      <div>我是cpn组件</div>
                      <ccpn></ccpn>
                  </div>
          
          
          
              </template>
              <!-- 下面是ccpn组件 -->
              <template id="ccpn">
                  <div>
                      <div>我是ccpn组件</div>
                      <button @click="checkParent">按钮</button>
                  </div>
              </template>
          </body>
          
          <script>
              // 下面是cpn的子组件
              const ccpn = {
                  template: "#ccpn",
                  methods: {
                      checkParent() {
                          console.log(this.$parent.msg);
                      }
          
                  }
          
              }
              // 下面是第一个子组件
              const cpn = {
                  template: '#cpn',
                  // 注册ccpn组件
                  components: {
                      ccpn
                  },
                  data() {
                      return {
                          msg: "我是cpn组件中的一条消息"
                      }
                  },
                  methods: {}
              };
          
              const app = new Vue({
                  el: "#app",
                  components: {
                      cpn,
                  }
              })
          </script>
          
          </html>
          
        • 关键代码:

              methods: {
                  checkParent() {
                      console.log(this.$parent.msg);
                  }
          
              }
          
      • $root

        • 完整代码

          <!DOCTYPE html>
          <html lang="en">
          
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>Document</title>
              <script src="../js/vue.js" type="text/javascript"></script>
          </head>
          
          <body>
              <div id="app">
                  <cpn ref="son"></cpn>
              </div>
              <!-- 下面是cpn子组件 -->
              <template id="cpn">
                  <div>
          
                      <div>我是cpn组件</div>
                      <ccpn></ccpn>
                  </div>
          
          
          
              </template>
              <!-- 下面是ccpn组件 -->
              <template id="ccpn">
                  <div>
                      <div>我是ccpn组件</div>
                      <button @click="checkParent">按钮</button>
                  </div>
              </template>
          </body>
          
          <script>
              // 下面是cpn的子组件
              const ccpn = {
                  template: "#ccpn",
                  methods: {
                      checkParent() {
                          console.log(this.$root.msg);
                      }
          
                  }
          
              }
              // 下面是第一个子组件
              const cpn = {
                  template: '#cpn',
                  // 注册ccpn组件
                  components: {
                      ccpn
                  },
                  data() {
                      return {
                          msg: "我是cpn组件中的一条消息"
                      }
                  },
                  methods: {}
              };
          
              const app = new Vue({
                  el: "#app",
                  data(){
                      return{
                          msg:"我是根组件的一条消息"
                      }
                  },
                  components: {
                      cpn,
                  }
              })
          </script>
          
          </html>
          
        • 关键代码

                  methods: {
                      checkParent() {
                          console.log(this.$root.msg);
                      }
          
                  }
          

          Vue基础

    五、插槽

    5.1普通插槽的使用

    • 首先在子组件中需要改变的地方写上插槽(<slot></slot>)

    • 在父级调用组件的标签内写这里需要显示的内容(调用就必须使用双标签

    • 整体代码:

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <script src="../js/vue.js" type="text/javascript"></script>
          <style>
              img {
                  width: 100px;
                  height: 100px;
              }
          </style>
      </head>
      
      <body>
          <div id="app">
              <!-- 第一个插槽显示按钮 -->
              <cpn> <button>按钮</button></cpn>
              <!-- 第二个插槽显示图片 -->
              <cpn> <img src="../img/01.png" ></cpn>
              <!-- 第三个插槽显示文字 -->
              <cpn> <span>我就是一段文字</span></cpn>
          </div>
          <!-- 下面是子组件 -->
          <template id="cpn">
              <div>
                  <h2>我是一个子组件</h2>
                  <!-- 定义一个插槽 -->
                  <slot></slot>
              </div>
          </template>
      </body>
          
      <script>
          const cpn = {
              template: "#cpn",
          };
          const app = new Vue({
              el: "#app",
              components: {
                  cpn
              }
          })
      </script>
      </html>
      
    • 关键代码:

          <div id="app">
              <!-- 第一个插槽显示按钮 -->
              <cpn> <button>按钮</button></cpn>
              <!-- 第二个插槽显示图片 -->
              <cpn> <img src="../img/01.png" ></cpn>
              <!-- 第三个插槽显示文字 -->
              <cpn> <span>我就是一段文字</span></cpn>
          </div>
          <!-- 下面是子组件 -->
          <template id="cpn">
              <div>
                  <h2>我是一个子组件</h2>
                  <!-- 定义一个插槽 -->
                  <slot></slot>
              </div>
          </template>
      

      Vue基础

    5.2默认插槽值

    • 使用过程与上面一样,不同的是在子组件中直接给<solt></slot>一个默认值

    • 在调用的时候,如果没有指定插槽内容,就会显示默认的插槽内容

      <body>
          <div id="app">
              <!-- 第一个插槽显示按钮 -->
              <cpn> <button>我是另一个按钮</button></cpn>
              <!-- 第二个插槽默认内容 -->
              <cpn></cpn>
              <!-- 第三个插槽显示文字 -->
              <cpn> <span>我就是一段文字</span></cpn>
          </div>
          <!-- 下面是子组件 -->
          <template id="cpn">
              <div>
                  <h2>我是一个子组件</h2>
                  <!-- 给插槽一个默认值 -->
                  <slot><button>按钮</button></slot>
              </div>
          </template>
      </body>
      
      

      Vue基础

    5.3具名插槽

    • 使用name属性给插槽一个标识

    • 在调用的时候使用属性slot来确定给哪个插槽替换

    • 如果没有用名称来确定的标识的内容,就会去寻找未具名的插槽,将其替换

    • 如果没有未具名的插槽,未指定name的内容将不会显示

    • 整体代码

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <script src="../js/vue.js" type="text/javascript"></script>
          <style>
              img {
                  width: 100px;
                  height: 100px;
              }
          </style>
      </head>
      
      <body>
          <div id="app">
              <cpn>
                  <!-- 将第一个插槽替换为按钮 -->
                  <button slot="first">&lt;</button>
                  <!-- 将第二个插槽替换为文本+输入框 -->
                  <span slot="second">
                      <span>搜索</span>
                      <input type="text" placeholder="搜索">
                  </span>
                  <!-- 第三个插槽变空 -->
                  <span slot="third"></span>
                  <!-- 替换没有名称的插槽 -->
                  <span>淦</span>
                  <span>淦</span>
              </cpn>
      
          </div>
          <!-- 下面是子组件 -->
          <template id="cpn">
              <div>
                  <slot name="first">我是第一个插槽</slot>
                  <slot name="second">我是第二个插槽</slot>
                  <slot name="third">我是第三个插槽</slot>
                  <slot></slot>
              </div>
          </template>
      </body>
      
      <script>
          const cpn = {
              template: "#cpn",
          };
          const app = new Vue({
              el: "#app",
              components: {
                  cpn
              }
          })
      </script>
      
      </html>
      
    • 关键代码

         <div id="app">
              <cpn>
                  <!-- 将第一个插槽替换为按钮 -->
                  <button slot="first">&lt;</button>
                  <!-- 将第二个插槽替换为文本+输入框 -->
                  <span slot="second">
                      <span>搜索</span>
                      <input type="text" placeholder="搜索">
                  </span>
                  <!-- 第三个插槽变空 -->
                  <span slot="third"></span>
                  <!-- 替换没有名称的插槽 -->
                  <span>淦</span>
                  <span>嘿</span>
              </cpn>
      
          </div>
          <!-- 下面是子组件 -->
          <template id="cpn">
              <div>
                  <slot name="first">我是第一个插槽</slot>
                  <slot name="second">我是第二个插槽</slot>
                  <slot name="third">我是第三个插槽</slot>
                  <slot></slot>
              </div>
          </template>
      

      Vue基础

          <!-- 下面是子组件 -->
          <template id="cpn">
              <div>
                  <slot name="first">我是第一个插槽</slot>
                  <slot name="second">我是第二个插槽</slot>
                  <slot name="third">我是第三个插槽</slot>
              </div>
          </template>
      

      Vue基础

    5.4作用域插槽

    • 在子组件中的插槽上通过:来绑定一个属性名与属性值,语法为<slot :list = "Arr"> 内容 </slot>属性名不能包含大写字母

    • 父级在调用的时候需要在组件内写一个<template slot-scope="slot">内容</template>(低版本必须用template,高版本可以不用)

    • 整体代码

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <script src="../js/vue.js" type="text/javascript"></script>
          <style>
              img {
                  width: 100px;
                  height: 100px;
              }
          </style>
      </head>
      
      <body>
          <div id="app">
              <cpn></cpn>
              <cpn>
                  <template slot-scope="slot">
                      <span v-for="item in slot.list">{{item}}-</span>
                  </template>
              </cpn>
      
          </div>
          <!-- 下面是子组件 -->
          <template id="cpn">
              <div>
                  <h2>我是子组件</h2>
                  <slot :list="Arr">
                      <ul>
                          <li v-for="item in Arr">
                              {{item}}
                          </li>
                      </ul>
                  </slot>
              </div>
          </template>
      </body>
      
      <script>
          const cpn = {
              template: "#cpn",
              data() {
                  return {
                      Arr: ["xiaoming", "xiaohong", "xiaoguang"]
                  }
              }
          };
          const app = new Vue({
              el: "#app",
      
      
              data() {
                  return {
      
                  }
              },
              methods: {},
              components: {
                  cpn
              }
          })
      </script>
      
      </html>
      
    • 关键代码:

          <div id="app">
              <cpn></cpn>
              <cpn>
                  <template slot-scope="slot">
                      <span v-for="item in slot.list">{{item}}*</span>
                  </template>
              </cpn>
      
          </div>
          <!-- 下面是子组件 -->
          <template id="cpn">
              <div>
                  <h2>我是子组件</h2>
                  <slot :list="Arr">
                      <ul>
                          <li v-for="item in Arr">
                              {{item}}
                          </li>
                      </ul>
                  </slot>
              </div>
          </template>
      

      Vue基础

    六、webpack


    起源地下载网 » Vue基础

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元