Vue指令快速上手

141 阅读3分钟

这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

Vue指令快速上手

模板语法

显示普通文本

<span>消息内容:{{ msg }}</span>

JavaScript表达式

{{ msg.split('').reverse().join('') }}

{{ result >0 ? 'YES':'NO' }}

演示:

<template>
  <div class="hello">
    <h1>第一个全局组件</h1>
    <ul>
      <li>{{ name }}</li>
      <li>{{ name.split('').reverse().join('') }}</li>
      <li>{{ result > 0 ? 'YES' : 'NO'}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      'name': '组件',
      result: 100
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

image-20211114095824133

image-20211114095834578

HTML

<span v-html="rawHtml"></span>

演示:

<template>
  <div class="hello">
    <h1>第一个全局组件</h1>
    <p>{{ rawHtml }}</p>
    <p v-html="rawHtml"></p>
    <ul>
      <li>{{ name }}</li>
      <li>{{ name.split('').reverse().join('') }}</li>
      <li>{{ result > 0 ? 'YES' : 'NO'}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      'name': '组件',
      result:  100,
      rawHtml: '<h3 style="color:#ff0000">hello</h3>'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

image-20211114100228927

image-20211114100239817

如果直接{{rawHtml}}输出则不会转义

需要使用指令v-html

指令是指带有v-前缀的特殊属性

常用的指令

v-bind

作用:响应式的更新HTML属性

场景:设置class、style、href、src等

设置href

<a v-bind:href="url">..</a>
<a :href="url">..</a>

image-20211114101401648

image-20211114101411141

点击超链接 即可跳转到设置的url地址

设置class

对象语法

v-bind:class="{active:isActive,'text-danger':hasError}"

<template>
  <div class="hello">
    <h1>第一个全局组件</h1>
    <p>{{ rawHtml }}</p>
    <p v-html="rawHtml"></p>
    <a v-bind:href="url">跳转1</a><br>
    <a v-bind:href="url">跳转2</a>
    <h3 v-bind:class="{'text-danger': result > 0}">123456</h3>
    <ul>
      <li>{{ name }}</li>
      <li>{{ name.split('').reverse().join('') }}</li>
      <li>{{ result > 0 ? 'YES' : 'NO'}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      'name': '组件',
      result:  100,
      rawHtml: '<h3 style="color:#ff0000">hello</h3>',
      url: 'http://www.baidu.com'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
.text-danger {
  color: #f00
}
</style>

添加css样式

.text-danger {
  color: #f00
}

设置css

<h3 v-bind:class="{'text-danger': result > 0}">123456</h3>

效果

image-20211114102354543

image-20211114102428415

将result的值改为小于0则不显示红色

数组语法

v-bind:class="[{active:isActive},errorClass]"

设置style

对象语法

v-bind:style="{ color:activeColor,fnotSize:fontSize+'px' }"

数组语法

v-bind:style="[baseStyles,overridingStyles]"
    <h3 v-bind:style="{ color:'#00f' }">设置css的style1</h3>
    <h3 v-bind:style="[{ color:'#00f' },{border: '1px solid #0f0'}]">设置css的style2</h3>
    

效果:

image-20211114103544871

v-model

表单输入绑定

基本语法

<input v-model="message">
<template>
  <div class="hello">
    <h3>登录</h3>
    <input type="text" v-model="username"><br>
    <input type="password" v-model="password"><br>
    <input type="button" value="登录" @click="login">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    login() {
      console. log('用户名:', this.username)
      console. log('密码', this.password)
    }
  }
}
</script>

image-20211114144457215

单选/多选的绑定

<template>
  <div class="hello">
    <label for="">
      <input type="radio" value="男" v-model="sex"></label>
    <label for="">
      <input type="radio" value="女" v-model="sex"></label>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      sex: '男'
    }
  },
  methods: {

  }
}
</script>

image-20211114145010344

<template>
  <div class="hello">
    <label for="">
      <input type="radio" value="男" v-model="sex"></label>
    <label for="">
      <input type="radio" value="女" v-model="sex"></label>
    <br>
    <select v-model="hobby" multiple>
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      sex: '男',
      hobby: []
    }
  },
  methods: {

  }
}
</script>

image-20211114145748189

修饰符

trim: 自动过滤首尾输入的空白

number: 自动转为数值类型

v-on

DOM事件监听

基本语法

<button v-on:click="counter+=1">ADD1</button>
<button @:click="counter+=1">ADD1</button>
<template>
  <div class="hello">
    <h1>表单练习</h1>
    <p>当前的数字是: {{ count }}</p>
    <input type="button" value="加一" v-on:click="count+=1">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      count: 0
    }
  }
}
</script>

image-20211114113731846

调用方法

<template>
  <div class="hello">
    <h1>表单练习</h1>
    <p>当前的数字是: {{ count }}</p>
    <input type="button" value="加一" v-on:click="count+=1">
    <input type="button" value="加二乘三" v-on:click="calc">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      count: 0
    }
  },
  methods: {
    calc() {
      this.count=(this.count + 2 )*3
    }
  }
}
</script>

image-20211114114028896

带参数的方法

<template>
  <div class="hello">
    <h1>表单练习</h1>
    <p>当前的数字是: {{ count }}</p>
    <input type="button" value="加一" v-on:click="count+=1">
    <input type="button" value="加二乘三" v-on:click="calc">
    <ul>
      <li v-for="item in stuList" :key="item.id" @click="addScore(item)">
        {{ item.name }} : {{ item.score }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      count: 0,
      stuList: [
        {id: 1, score: 0, name: 'A'},
        {id: 2, score: 0, name: 'B'},
        {id: 3, score: 0, name: 'C'}
      ]
    }
  },
  methods: {
    calc() {
      this.count=(this.count + 2 )*3
    },
    addScore(stu) {
      stu.score=stu.score + 1
    }
  }
}
</script>

image-20211114114603085

鼠标事件修饰符

  • 阻止事件冒泡
<a v-on:click.stop="doThis"></a>
<template>
  <div class="hello">
    <h1>表单练习</h1>
    <p>当前的数字是: {{ count }}</p>
    <input type="button" value="加一" v-on:click="count+=1">
    <input type="button" value="加二乘三" v-on:click="calc">
    <ul>
      <li v-for="item in stuList" :key="item.id" @click="addScore(item)">
        {{ item.name }} : {{ item.score }}
      </li>
    </ul>
    <h3>事件冒泡</h3>
    <div class="panel" @click="clickDiv">
      <p @click="clickP">00000</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      count: 0,
      stuList: [
        {id: 1, score: 0, name: 'A'},
        {id: 2, score: 0, name: 'B'},
        {id: 3, score: 0, name: 'C'}
      ]
    }
  },
  methods: {
    calc() {
      this.count=(this.count + 2 )*3
    },
    addScore(stu) {
      stu.score=stu.score + 1
    },
    clickDiv() {
      window.alert('clickDiv')
    },
    clickP() {
      window.alert('clickP')
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
.text-danger {
  color: #f00
}
.panel {
  background-color: rgba(151, 177, 231, 0.918);
  padding: 50px;
  p {
    background-color: #fff;
    padding: 20px;
  }
}
</style>

image-20211114120706934

image-20211114120718567

提示两次

阻止冒泡事件后

    <h3>事件冒泡</h3>
    <div class="panel" @click="clickDiv">
      <p @click.stop="clickP">00000</p>
    </div>

image-20211114120915643

只提示一次 不会弹出父元素的提示

  • 阻止默认行为
<a v-on:click.prevent="doThis"></a>
    <h3>默认行为</h3>
    <a href="http://baidu.com" @click.prevent="clickP">0000</a>

image-20211114123134995

只弹提示窗口

不跳转到url

  • 点击事件只触发一次

    <a v-on:click.once="doThis"></a>
    
        <h3>只触发一次</h3>
        <p @click.once="clickP">0000</p>
    

    image-20211114123455894

    第一次点击弹出提示窗口 第一次之后失效

键盘事件

<template>
  <div class="hello">

    <h3>键盘事件</h3>
    <input type="text" @keyup="submit">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {

  },
  methods: {
    submit() {
      window.alert('内容变化')
    }
  }
}
</script>

image-20211114142645425

键盘抬起时就弹提示框

键盘事件修饰符

监听回车键
<input v-on:keyup.enter="submit">
监听删除/退格键
<input v-on:keyup.delete="submit">

当按下对应键时调用方法

v-if / v-else

<div v-if="score >= 90">A</div>
<div v-else-if="score >= 80">B</div>
<div v-else-if="score >= 60">C</div>
<div v-else >D</div>
<template>
  <div class="hello">
    <h1>第一个全局组件</h1>
    <div v-if="score >= 90">A</div>
    <div v-else-if="score >= 80">B</div>
    <div v-else-if="score >= 60">C</div>
    <div v-else >D</div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      score: 96
    }
  }
}
</script>

效果:

image-20211114104225772

v-for

基本语法

<li v-for="item in items":key="item.id">
<div v-for="item of items":key="item.id"></div>

key的作用

渲染性能优化(修改DOM还是替换DOM)

<template>
  <div class="hello">
    <h1>第一个全局组件</h1>
    <div v-if="score >= 90">A</div>
    <div v-else-if="score >= 80">B</div>
    <div v-else-if="score >= 60">C</div>
    <div v-else >D</div>
    <h3 class="text-danger" v-show="hError">错误</h3>
    <ul>
      <li v-for="item in aList" :key="item">{{ item }}</li>
    </ul>
    <ul>
      <li v-for="item of aList" :key="item">{{ item }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      score: 96,
      hError: true,
      aList: ['北京','上海','广州']
    }
  }
}
</script>

效果:

image-20211114110827085

渲染数组:

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

效果:

image-20211114111234992

渲染对象:

<div v-for="(value,key,index) in object">
{{index}}.{{key}}:{{value}}
</div>
<template>
  <div class="hello">
    <h1>第一个全局组件</h1>
    <div v-if="score >= 90">A</div>
    <div v-else-if="score >= 80">B</div>
    <div v-else-if="score >= 60">C</div>
    <div v-else >D</div>
    <h3 class="text-danger" v-show="hError">错误</h3>
    <ul>
      <li v-for="(item,index) in aList" :key="index">{{index}}-{{ item }}</li>
    </ul>
    <h3>渲染对象</h3>
    <ul>
      <li v-for="(value,key,index) in userInfo" :key="index">{{index}}-{{key}}-{{value}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      score: 96,
      hError: true,
      aList: ['北京','上海','广州'],
      userInfo: {
        username: 'abc',
        nickname: 'A',
        age: 20
      }
    }
  }
}
</script>

image-20211114112129926

v-show

原理:通过切换css的display属性来控制元素的显示与隐藏

<h1 v-show:"hError">错误</h1>

<template>
  <div class="hello">
    <h1>第一个全局组件</h1>
    <div v-if="score >= 90">A</div>
    <div v-else-if="score >= 80">B</div>
    <div v-else-if="score >= 60">C</div>
    <div v-else >D</div>
    <h3 class="text-danger" v-show="hError">错误</h3>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      score: 96,
      hError: true
    }
  }
}
</script>

效果:

image-20211114110210462