zoukankan      html  css  js  c++  java
  • vue的一些注意点

    Vue注意点

    v-html

    你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容插值。

    利用标签模板,过滤 HTML 字符串,防止用户输入恶意内容。

    function SaferHTML(templateData) {
        let s = templateData[0];
        console.log(s);
        for (let i = 1; i < arguments.length; i++) {
            let arg = String(arguments[i]);
    
            // Escape special characters in the substitution.
            s += arg.replace(/&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/>/g, "&gt;");
    
            // Don't escape special characters in the template.
            s += templateData[i];
        }
        return s;
    }
    

    条件渲染

    template不支持v-show

    默认情况下在切换dom时相同的结构会被复用,如果不需要复用,需要添加key

    <template v-if="loginType === 'username'">
      <label>Username</label>
      <input placeholder="Enter your username" key="1">
    </template>
    <template v-else>
      <label>Email</label>
      <input placeholder="Enter your email address" key="2">
    </template>
    

    checkbox

    多个复选框。v-model需要绑定到一个数组

    //html
    <div id='example-3'>
      <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
      <label for="jack">Jack</label>
      <input type="checkbox" id="john" value="John" v-model="checkedNames">
      <label for="john">John</label>
      <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
      <label for="mike">Mike</label>
      <br>
      <span>Checked names: {{ checkedNames }}</span>
    </div>
    
    //js
    new Vue({
      el: '#example-3',
      data: {
        checkedNames: []
      }
    })
    

    多选时的select框同理

    箭头函数

    不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a)
    vm.$watch('a', newValue => this.myMethod())。因为箭头函数是和父级上下文绑定在一起的,this 不会是如你所预期的 Vue 实例,经常导致 Uncaught TypeError: Cannot read property of undefined
    Uncaught TypeError: this.myMethod is not a function 之类的错误。

    数组更新检测

    Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:push()、pop()、shift()、unshift()、splice()、sort()、reverse()。

    变异方法 (mutation method),顾名思义,会改变被这些方法调用的原始数组。相比之下,也有非变异 (non-mutating method) 方法,例如:filter(), concat() 和 slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:

    example1.items = example1.items.filter(function (item) {
      return item.message.match(/Foo/)
    })
    

    注意事项

    由于 JavaScript 的限制,Vue 不能检测以下变动的数组:

    var vm = new Vue({
      data: {
        items: ['a', 'b', 'c']
      }
    })
    vm.items[1] = 'x' // 不是响应性的
    vm.items.length = 2 // 不是响应性的
    

    为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:

    // Vue.set
    Vue.set(vm.items, indexOfItem, newValue) 
    
    // Array.prototype.splice
    vm.items.splice(indexOfItem, 1, newValue)
    

    你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:

    vm.$set(vm.items, indexOfItem, newValue)
    
    

    为了解决第二类问题,你可以使用 splice:

    vm.items.splice(newLength)
    
    

    Vue.set可改为vm.$set

    对象更改检测注意事项

    还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:

    var vm = new Vue({
      data: {
        a: 1
      }
    })
    // `vm.a` 现在是响应式的
    
    vm.b = 2
    // `vm.b` 不是响应式的
    

    对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。例如,对于:

    var vm = new Vue({
      data: {
        userProfile: {
          name: 'Anika'
        }
      }
    })
    

    你可以添加一个新的 age 属性到嵌套的 userProfile 对象:

    Vue.set(vm.userProfile, 'age', 27)
    

    如果需要为已有对象赋予多个属性:

    vm.userProfile = Object.assign({}, vm.userProfile, {
      age: 27,
      favoriteColor: 'Vue Green'
    })
    

    删除属性用Vue.delete或者vm.$delete。

    Vue.delete(vm.items,0);
    //或者
    vm.$delete(vm.items,0);
    

    解析 DOM 模板时的注意事项

    有些 HTML 元素,诸如 <ul>、<ol>、<table> 和 <select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li>、<tr> 和 <option>,只能出现在其它某些特定的元素内部。

    这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

    <table>
      <blog-post-row></blog-post-row>
    </table>
    

    这个自定义组件 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is 特性给了我们一个变通的办法:

    <table>
      <tr is="blog-post-row"></tr>
    </table>
    

    需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:

    单个根元素

    每个组件必须只有一个根元素

    <h3>{{ title }}</h3>
    <div v-html="content"></div>
    

    以上模板会报错,将其包裹在一个父元素内即可解决

    <div class="blog-post">
      <h3>{{ title }}</h3>
      <div v-html="content"></div>
    </div>
    

    组件名大小写

    当组件名使用 kebab-case方式时,在引用这个自定义元素时必须使用 kebab-case
    当组件名使用 PascalCase方式时,引用这个自定义元素时可使用 kebab-case 或者 PascalCase

    但是,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的

    事件名

    跟组件和 prop 不同,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。

    this.$emit('myEvent')
    
    <my-component v-on:my-event="doSomething"></my-component>
    

    以上监听是无法生效的,v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的)。因此,推荐始终使用 kebab-case 的事件名

    事件处理

    常规绑定方法

    //html
    <div id="example-2">
      <!-- `greet` 是在下面定义的方法名 -->
      <button v-on:click="greet">Greet</button>
    </div>
    //js
    var example2 = new Vue({
      el: '#example-2',
      data: {
        name: 'Vue.js'
      },
      // 在 `methods` 对象中定义方法
      methods: {
        greet: function (event) {
          // `this` 在方法里指向当前 Vue 实例
          alert('Hello ' + this.name + '!')
          // `event` 是原生 DOM 事件
          if (event) {
            alert(event.target.tagName)
          }
        }
      }
    })
    

    内联 JavaScript 语句中调用方法

    //html
    <div id="example-3">
      <button v-on:click="say('hi', $event)">Say hi</button>
      <button v-on:click="say('what', $event)">Say what</button>
    </div>
    //js
    new Vue({
      el: '#example-3',
      methods: {
        say: function (message, event) {
          alert(message)
        }
      }
    })
    

    v-model

    <input v-model="searchText">
    //等价于
    <input
      v-bind:value="searchText"
      v-on:input="searchText = $event.target.value"
    >
    

    给组件添加 v-model 属性时,默认会把 value 作为组件的属性,然后把 'input' 值作为给组件绑定事件时的事件名

    但是在单选框、复选框等类型的输入控件,需要的就不是默认的value特性以及input事件了,有两种方法进行修改

    html

    <base-checkbox v-model="lovingVue"></base-checkbox>
    
    1. 修改v-model语法糖
    Vue.component('base-checkbox', {
      props:['value']
      template: `
        <input
          type="checkbox"
          v-bind:checked="value"
          v-on:change="$emit('change', $event.target.checked)"
        >
      `
    })
    
    1. 在 Vue 2.2 版本,你可以在定义组件时通过 model 选项的方式来定制 prop/event:
    Vue.component('base-checkbox', {
      model: {
        prop: 'checked',
        event: 'change'
      },
      props: {
        checked: Boolean
      },
      template: `
        <input
          type="checkbox"
          v-bind:checked="checked"
          v-on:change="$emit('change', $event.target.checked)"
        >
      `
    })
    

    为组件添加原生事件

    为v-on添加.native修饰符即可

    <base-input v-on:focus.native="onFocus"></base-input>
    

    特殊情况: 如果使用focus监听input元素,并且input元素被包裹在一个父元素中,.native监听器将默认失败

    $attrs、$listeners、inheritAttrs

    名词解释

    $attrs--继承所有的父组件属性(除了prop传递的属性、class 和 style )

    inheritAttrs:默认值true,继承所有的父组件属性(除props的特定绑定)作为普通的HTML特性应用在子组件的根元素上,如果你不希望组件的根元素继承特性设置inheritAttrs: false,但是class属性和style会继承。

    $listeners--属性,它是一个对象,里面包含了作用在这个组件上的所有监听器,你就可以配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素。

    代码演示:

    //HTML
    <div id="app">
    	<base-input v-model="a" placeholder="tip" label="name" class="a" :style="{color: 'red'}"></base-input>
    </div>
    
    //JS
    Vue.component('base-input', {
    	props: ['value'],
    	template: `
    	<label>
    	{{$attrs.placeholder}}
    	{{$attrs.label}}
    	  <input
    	    v-bind:value="value"
    	    v-on:input="$emit('input', $event.target.value)"
    	    v-bind="$attrs">
      	</label>
    	`
    });
    var v = new Vue({
    	el: '#app',
    	data: {
    		a: '123',
    	}
    });
    

    因为inheritAttrs的默认值为ture,所以组件的根元素label将继承父组件的所有属性(除了class、style和props传递的属性);组件内的input则通过v-on="$attrs"绑定了父组件的属性。

    渲染结果为:

    <label placeholder="tip" label="name" class="a" style="color: red;">
    	tip
    	name
        <input placeholder="tip" label="name">
    </label>
    

    若将inheriAttrs值设为false,
    根元素label将不会继承父组件的属性。

    <label class="a" style="color: red;">
    	tip
    	name
        <input placeholder="tip" label="name">
    </label>
    

    $attrs可以打包父组件的属性,同样的,$listeners则打包父组件的事件

    //html
    <div id="app">
    	<base-input @click="func" @focus="funf" v-model="a" placeholder="tip" label="name" class="a" :style="{color: 'red'}"></base-input>
    </div>
    
    //js
    Vue.component('base-input', {
    //	inheritAttrs: false,
    	props: ['value'],
    	template: `
    	<label>
    	{{$attrs.placeholder}}
    	{{$attrs.label}}
    	  <input
    	    v-bind:value="value"
    	    v-on:input="$emit('input', $event.target.value)"
    	    v-bind="$attrs"
    	    v-on="$listeners">
      	</label>
    	`
    });
    var v = new Vue({
    	el: '#app',
    	data: {
    		a: '123',
    	},
    	methods: {
    		func: function(){
    			console.log('被点击了');
    		},
    		funf: function(){
    			console.log('获得焦点');
    		}
    	},
    });
    

    插槽

    如果组件没有包含一个元素,则任何传入它的内容都会被抛弃。

    $nextTick()

    如果数据变化后想获取真实dom中的内容,需要等待页面渲染完毕后再去获取所有的dom操作最好放在nextTick中

    slot插槽

    如果组件模板没有包含一个 元素,则任何传入它的内容都会被抛弃。

    <my-component>
        Your Profile
    </my-component>
    

    当有多个内容需要分配至相应插槽中,可以将内容包裹在设置了slot特性的

  • 相关阅读:
    osg控制相机移动
    osg绘制胶囊体
    Pset_RampFlightCommon
    osg抓图
    osg截取场景图片
    osg实现三视图
    Sonar系列:Gitlab集成Sonarqube实现自动检测代码并发送报告给提交者(五)
    Sonar系列:通过Jenkins集成sonarqube做持续扫描(四)
    来到这座城市3年了
    DongTai--被动型IAST工具部署体验
  • 原文地址:https://www.cnblogs.com/y-dt/p/9787580.html
Copyright © 2011-2022 走看看