_vue深入学习">
当前位置:   article > 正文

vue——深入学习_vue深入学习

vue深入学习

1.计算属性和监听器

  • 计算属性:一般情况下属性放在data里边,除此之外有些属性需要经过逻辑计算才能的出来,那么这类属性可以变成计算属性。
<div id="app">
    <label for="length">长:</label>
    <input type="number" name="length" v-model:value="length">
    <label for="width">宽:</label>
    <input type="number" name="width" v-model:value="width">
    <label for="area">面积:</label>
    <input type="number" name="area" v-bind:value="area" readonly>
</div>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            length: 0,
            width: 0,
        },
        computed: {
            area: function(){
                return this.length*this.width;
            }
        }
    });
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 计算属性相比函数更加智能,这是基于他们的响应式依赖进行缓存的。只要相关依赖(例如area)没有发生改变,那么计算属性的函数不会重新执行,而是直接返回之前的值。这个缓存功能让计算属性访问更加高效。
  • 计算属性的Set:计算属性默认是get,但是提供了set就必须要提供get方法。
<div id="app">
    <div>
        <label>省:</label>
        <input type="text" name="province" v-model:value="province">
    </div>
    <div>
        <label>市:</label>
        <input type="text" name="city" v-model:value="city">
    </div>
    <div>
        <label>区:</label>
        <input type="text" name="district" v-model:value="district">
    </div>
    <div>
        <label>详细地址:</label>
        <input type="text" name="address" v-model:value="address">
    </div>
</div>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            district: "",
            city: "",
            province: ""
        },
        computed: {
            address: {
                get: function(){
                    let result = "";
                    if(this.province){
                        result = this.province + "省";
                    }
                    if(this.city){
                        result += this.city + "市";
                    }
                    if(this.district){
                        result += this.district + "区";
                    }
                    return result;
                },
                set: function(newValue){
                    let result = newValue.split(/省|市|区/)
                    if(result && result.length > 0){
                        this.province = result[0];
                    }
                    if (result && result.length > 1){
                        this.city = result[1];
                    }
                    if(result && result.length > 2){
                        this.district = result[2];
                    }
                }
            }
        }
    });
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 监听属性:监听属性可以针对某个属性进行监听,只要这个属性的值发生了改变,就会执行相应的函数。
<div id="app">
    <div>
        <label>搜索:</label>
        <input type="text" name="keyword" v-model:value="keyword">
    </div>
    <div>
        <p>结果:</p>
        <p>{{answer}}</p>
    </div>
</div>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            keyword: "",
            answer: ""
        },
        watch: {
            keyword: function(newKeyword,oldKeyword){
                this.answer = '加载中...';
                let that = this;
                setTimeout(function(){
                    that.answer = that.keyword;
                },Math.random()*5*1000);
            }
        } 
    });
</script>	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

表单输入绑定

  • v-model:指定可以实现表单值与属性的双向绑定。即表单元素中更改了值会自动更新属性中的值,属性中的值更新了会自动更新表单中的值。
  • 绑定的属性和事件:
    v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件。
  1. text和textarea元素使用value属性和input事件。
  2. checkbox和radio使用checked属性和change属性
  3. select字段将value作为prop并将change作为事件。

表单元素绑定

  • input绑定
v-model是v-model:value的缩写,改变 input标签中的值 可以改变下面的属性
<input v-model="message" placeholder="请输入...">
<input v-model:value="message" placeholder="请输入...">
<p>输入的内容是:{{ message }}</p>


new Vue({
  el: '#example-3',
  data: {
    message: ""
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • textarea绑定
<span>输入的内容是:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="请输入多行内容..."></textarea>
  • 1
  • 2
  • 3
  • checkbox绑定
<div id='example-3'>
  <input type="checkbox"  value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox"  value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox"  value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>
new Vue({
  el: '#example-3',
  data: {
    checkedNames: []
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • radio绑定
<div id="example-4">
    <input type="radio" value="" v-model="gender">
    <label></label>
    <br>
    <input type="radio" value="" v-model="gender">
    <label></label>
    <br>
    <span>Picked: {{ gender }}</span>
</div>
new Vue({
  el: '#example-4',
  data: {
    gender: ''
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • select绑定
<div id="example-5">
    <select v-model="selected">
        <option disabled value="">请选择</option>
        # 如果有value值 选择的就是value值
        <option value="1">A</option>
        <option>B</option>
        <option>C</option>
    </select>
    <span>Selected: {{ selected }}</span>
</div>
new Vue({
  el: '...',
  data: {
    selected: ''
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

修饰符

  • .lazy
    在默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步,可以添加lazy修饰符,从而转变为使用change事件进行同步:
<!-- 在"change"时而非"input"时更新 光标移除input输入框的时候 -->
<input type="text" v-model:value.lazy="message">
<input v-model.lazy="message" >

new Vue({
  el: '#app',
  data: {
    message: ''
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • .number
    给v-model添加number修饰符,可以自动将用户的输入值转为数值类型。
<input v-model.number="age" type="number">
    • .trim
      给v-model添加trim修饰符可以自动过滤用户输入的首尾空白字符。
    <input v-model.trim="msg">

      2.自定义组件

      2.1基本使用

      <div id="app">
          <button-counter></button-counter>
          <button-counter></button-counter>
          <button-counter></button-counter>
      </div>
      <script>
          Vue.component('button-counter', {
              template: '<button v-on:click="count+=1">点击了{{ count }}次</button>'
              data: function(){
                  return {
                      count: 0
                  }
              },
          });
          let vm = new Vue({
              el: "#app",
              data: {}
          });
      </script>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18

      在上诉实例中创建了一个组件button-counter,实现了能够记录点击了多少次按钮的功能。组件是可以复用得到Vue实例,因此他们与new vue接收相同的选项。例如data,methods等等。
      注意:组件中的ddata必须为一个函数

      2.2给组件添加属性

      • 通过prop对自己创建的组件添加属性。
      <div id="app">
          <blog-post v-for="blog in blogs" :title="blog.title"></blog-post>
          <blog-post v-bind:blogs="blogs"></blog-post>
      </div>
      <script>
          Vue.component('blog-post', {
              props: ['blogs'],
              template: `
              <table>
                  <tr>
                      <th>序号</th>  
                      <th>标题</th>  
                  </tr>  
                  <tr v-for="(blog,index) in blogs">
                      <td>{{index+1}}</td>
                      <td>{{blog.title}}</td>
                  </tr>
              </table>
              `
          })
          new Vue({
              el: "#app",
              data: {
                  blogs: [
                      {"title":"钢铁是怎样练成的?","id":1},
                      {"title":"羊脂球","id":2},
                      {"title":"百年孤独","id":3},
                  ]
              }
          });
      </script>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 单一根元素
        如果自定义的组件中,会出现很多html元素,那么根元素必须只能有一个,其余的元素必须包含在这个根元素中。
      • 错误案例:
      <h3>{{ title }}</h3>
      <div v-html="content"></div>
      • 1
      • 正确案例
      <div class="blog-post">
        <h3>{{ title }}</h3>
        <div v-html="content"></div>
      </div>
      • 1
      • 2
      • 3
      • 子组件事件和传递事件到父组件
      <div id="app">
          <blog-item v-for="blog in blogs" v-bind:blog="blog" @check-changed="checks"></blog-item>    
          
          <div v-for="blog in componentblog">
              {{blog.title}}
          </div>
      </div>
      <script>
          Vue.component('blog-item',{
              props:['blog'],
              template:`
              <div>
                  <span>{{blog.title}}</span>
                  <input type="checkbox" @click="onCheck">   
              </div>
              `,
              methods:{
                  onCheck:function(){
                      // console.log(123)
                      this.$emit('check-changed',this.blog)
                  }
              }
          })
      
          new Vue({
              el: '#app',
              data: {
                  blogs:[
                      {"title":"复仇者联盟","id":1},
                      {"title":"哈利波特","id":2},
                      {"title":"回到未来","id":3},
                  ],
                  componentblog:[]
              },
              
              methods:{
                  checks:function(blog){
                      // indexOf 判断某个元素在数组中的位置,返回下标
                      var index = this.componentblog.indexOf(blog)
                      if(index >= 0){
                          this.componentblog.splice(index,1)
                      }else{
                          this.componentblog.push(blog)
                      }
                      console.log(blog)
                  }
              }
          })
      </script>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48

      注意:定义子组件传给父组件事件名称的时候,不要使用驼峰命名法,而是使用“-”

      • 自定义组件v-model
        组件上的v-moel默认会利用名为value的prop(属性)和名为input的事件,但是不同类型的控件可能会有不同的用处,通过设置model选项来实现不同的处理方式
      <div id="app">
          <stepper v-model:value="goods_count"></stepper>
      </div>
      
      <script>
           Vue.component('stepper',{
              props:['count'],
              model:{
                  event: 'count-changed',//触发什么事件时修改属性
                  prop: "count"//修改什么属性
              },
              template:`
              <div>
                  <button @click="sub">-</button>  
                  <span>{{count}}</span>
                  <button @click="add">+</button>  
              </div>
              `,
              methods:{
                  sub:function(){
                      this.$emit("count-changed", this.count-1)
                  },
                  add:function(){
                      this.$emit("count-changed", this.count+1)
                  }
              }
          });
      
          new Vue({
              el: "#app",
              data:{
                  "goods_count":0
              }
          })
      </script>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 插槽
        使用插槽在已经定义完的组件里插入新的元素或者文本
      <div id="app">
          <navigation-link url="/profile/">
              个人中心
          </navigation-link>
      </div>
      <script>
          Vue.component('navigation-link', {
              props: ['url'],
              template: `
              <a v-bind:href="url" class="nav-link">
                  <slot></slot>
              </a>
              `
          })
          new Vue({
              el: "#app"
          });
      </script>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

      3.生命周期函数

      • 生命周期函数代表的是Vue实例或者是Vue组件,在网页中各个生命阶段所执行的函数,生命周期函数可以分为创建阶段运行期间以及销毁期间
      • 创建期间函数:beforeCreate、created、beforeMount、mounted;
      • 运行期间函数:beforeUpdate、updated;
      • 销毁期间函数:beforeDestroy、destroyed。
        在这里插入图片描述
      <!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="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      </head>
      <body>       
      	<div id="app">       
      <p id="username">{{username}}</p>       
      <button @click='username ="dk"'>更改username</button>       
      <error-view v-bind:message='message' v-if='message'></error-view>       
      <button @click='message=""'>点击</button>    
      	</div>    
      <script>
              
              Vue.component('error-view', {            
              props: ['message'],            
              data: function(){                
              return {                    
              hello: 'world'                
              }            
              },            
              template: `                
              <p style='color:red'>{{ message }}</p>            
              `,            
              // 组件的方式演示销毁          
              beforeDestroy(){
              //Vue实例或组件在被销毁之前执行的函数。在这个函数中Vue或者组件中所有的属性都是可以使用的。                
              	console.log('beforeDestroy')                
              	console.log(this.hello)            
              	},            
      	destroyed(){                
      	//Vue实例或组件都是被销毁后执行的。此时Vue实例上所有东西都会解绑,所有事件都会被移除,所有子元素都会被销毁	console.log('destroyed')                
      		console.log(this.hello)            
      		}        
      		})            
      	new Vue({            
      		el: '#app',            
      		data: {               
      		username:'duke',               
      		message:'dukfs'            
      		},            		   
      	beforeCreate(){                
      	//vue或者组件刚刚实例化,data、methods都还没有被创建                
      	console.log('============')                
      	console.log(this.username)                
      	console.log('============')
                  },
                  
              created(){                
              //data和methods已经被创建可以使用,但是模板还没有被编译。                
              console.log(this.username)            
              },                        
              beforeMount(){                
              //模板已经被编译,但是并没有挂到网页中                
              console.log(document.getElementById('username').innerText)            
              },
                  
              mounted(){                
              //模板已经挂在到网页上                
              console.log(document.getElementById('username').innerText)
               },
                  
               beforeUpdate(){                
               //在网页运行期间,data中的数据可能会更新,但是并没有在模板中进行更新,因此网页中显示的还是之前的                
               console.log(document.getElementById('username').innerText)
                },
               updated(){                
               //数据在data中更新了,也在网页中更新了。                
               console.log(document.getElementById('username').innerText)
                 }        
                 })
      </script>
      </body>
      </html>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74

      过滤器

      • 过滤器就是数据在真正进行渲染到页面中的时候,可以使用这个过滤器进行一些处理,把最终处理的结果渲染到网页中。
      • 过滤器使用
        过滤器在两个地方中使用,由管道符号指示:
      1. 双花括号插值**
      <!-- 在双花括号中 -->
      {{ message|capitalize }}
      • 1
      1. 在v-bind表达式
      <!-- 在 `v-bind` 中 -->
      <div v-bind:id="rawId|formatId"></div>
      
      • 1
      • 2
      • 过滤器定义
      1. 在组件的选项中定义本地的过滤器
      filters: {
        capitalize: function (value) {
          if (!value) return ''
          value = value.toString()
          return value.charAt(0).toUpperCase() + value.slice(1)
        }
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      1. 在创建Vue实例之前全局定义过滤器
      Vue.filter('capitalize', function (value) {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
      })
      
      new Vue({
        // ...
      })
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      4.网络应用

      • Vue结合网络数据开发应用,axios,网络请求库,使用的时候导入
      <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

        post请求

        axios.post(地址).then(function(response){},function(err){})

          get请求

          axios.get(地址).then(function(response){},function(err){})
            • axios+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="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>    
            	<script src="https://unpkg.com/axios/dist/axios.min.js"></script>   
            </head>
            <body>   
            	<div id="app">       
            		<button @click='getJoke'>获取笑话</button>       
            		<p>{{ joke }}</p>    
            	</div>    
            	<script>
                    
                    	new Vue({            
                    		el: '#app',            
                    		data: {                
                    			joke: ''            
                    		},              
                    	methods: {                
                    		getJoke: function(){                    
                    			var that = this                    
                    			axios.get('https://autumnfish.cn/api/joke/list?num=4')                        
                    				.then(function(response){                            
                    				// console.log(response.data)                            
                    				// console.log(that.joke)                            
                    				that.joke = response.data.jokes                        
                    				},function(err){                            
                    				console.log(err)})                
                    				
                    					}            
                    				}        
                    				})
                   axios.post('https://autumnfish.cn/api/user/reg', {username: 'dk'})       
                   .then(function(response){           
                   		console.log(response)       
                   		},function(err){            
                   			console.log(err)        
                    })//网络请求GEt和POST请求的区别,两者之间的地址也不一样,此外,get请求一般用于向    
            	</script>
            </body>
            </html>
            
            
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13
            • 14
            • 15
            • 16
            • 17
            • 18
            • 19
            • 20
            • 21
            • 22
            • 23
            • 24
            • 25
            • 26
            • 27
            • 28
            • 29
            • 30
            • 31
            • 32
            • 33
            • 34
            • 35
            • 36
            • 37
            • 38
            • 39
            • 40
            • 41
            • 42
            • 43
            • 44
            • 45
            声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/69798
            推荐阅读
            相关标签
              

            闽ICP备14008679号