Vue之指令

1、指令介绍

  指令的英文:directive,vue指令的作用是通过带有v-的特殊属性,实现对dom的响应式加载
  
在vue中提供了一些对于页面 + 数据的更为方便的输出,这些操作就叫做指令, 以v-xxx表示
类似于html页面中的属性 `<div v-xxx ></div>

比如在angular中 以ng-xxx开头的就叫做指令
在vue中 以v-xxx开头的就叫做指令
指令中封装了一些DOM行为, 结合属性作为一个暗号, 暗号有对应的值,根据不同的值,框架会进行相关DOM操作的绑定

2、文本指令

1、v-text

  作用:向其所在的节点中渲染文本内容,不能解析标签
与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。即双大括号可进行部分内容的替换,而v-text不行
<div id="app">
  <p>{{ message }}哈哈哈</p>
  <h2 v-text='message'>哈哈哈</h2>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
</script>

输出: 
Hello Vue.js!哈哈哈
Hello Vue.js!

2、v-html

v-html
	可以解析字符中的标签

注意和格式:  
 作用:向指定节点中渲染包含html结构的内容。
与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以识别html结构。
严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!

3、总结v-text和v-html

v-html指令的作用是:设置元素的innerHTML
内容有html结构会被解析为标签
v-text指令无论内容是什么,只会解析为文本
解析文本使用v-text,需要解析html结构使用v-html

3、事件指令

事件指令大致内容有  
		# 1 点击事件,双击事件,拖动事件,得到焦点,失去焦点等

Vue指令 V-on 修饰符
  · 目的:在事件后面修饰符名,给事件带来更强大的功能(为元素绑定事件)
   · 语法:事件名"methods函数
     . stop:阻止事件冒泡
     . prevent:阻止默认行为
     . once 程序运行期间,只触发一次事件处理函数
	· 简写: @click="methods函数"  
  · 事件绑定的方法写成函数调用的形式,可以传入自定义参数
  · 定义方法时需要定义形参来接收传入的实参
  · 事件的后面加上 .修饰符 可以对事件进行限制
  · .enter可以限制出发的按键为回车

1、es6的对象写法

// es6 的对象写法
var hobby=['抽烟','烫头']
var obj={
    'name':'quan',
    age:19,
    hobby,
    showName() {
        console.log(this.name)
    }
}
console.log(obj)
obj.showName()

2、函数的使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue/vue.js"></script>
    <style>
        img {
            height: 300px;
            width: 200px;
        }
    </style>
</head>
<body>
<div id="app">
    <img src="https://wx1.sinaimg.cn/mw690/001X1s9jly1hoyqlz7ng3j60u0190dmr02.jpg" alt="" v-show="isShow">
    <hr>
    <button @click="handleShow">点我消失出现</button>

    <h1>事件指令--函数有参数</h1>
    <button @click="handleFunc1">不传参数-函数有参数</button>
    <br>
    <button @click="handleFunc1(isShow)">传参数-函数有参数</button>
    <br>
    <button @click="handleFunc1($event)">传参数-函数有参数-把事件对象传入</button>
    <br>
    <button @click="handleFunc2">多个参数-少传不加括号</button>
    <br>
    <button @click="handleFunc2()">多个参数-少传-加括号event不会自动传入</button>
    <br>
    <button @click="handleFunc2(1,2,3,4,5,6,)">多个参数-多传</button>
    <br>
    <button @click="handleFunc2(1,$event)">多个参数-event作为第二个参数</button>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            isShow: true
        },
        methods: {
            handleShow () {
                this.isShow=!this.isShow
            },
            handleFunc1(event){
                //1 如果在事件中触发函数,没有传参数,会自动把 事件对象传入
                console.log(event)
            },
            handleFunc2(a,b,c){
                console.log(a)
                console.log(b)
                console.log(c)
            }
        }
    })

    // es6 的对象写法
    var hobby=['抽烟','烫头']
    var obj={
        'name':'quan',
        age:19,
        hobby,
        showName() {
            console.log(this.name)
        }
    }
    console.log(obj)
    obj.showName()
</script>
</html>

4、属性指令

# 1 标签上有属性
	img   src
  a     href
# 2 属性指令作用:是使用变量动态设置属性的值

# 3 使用
	v-bind:属性名='变量'
  简写:
    		:属性名='变量'
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue/vue.js"></script>
</head>
<body>
<div id="app">
    <img :src="url">
    <hr>
    <button @click="handleChange">点击切换美女</button>
    <button @click="handleChoose">点击开始选美女</button>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            url: 'https://wx1.sinaimg.cn/mw690/001X1s9jly1hoyqlz7ng3j60u0190dmr02.jpg',
            t: null
        },
        methods: {
            handleChange() {
                this.url = 'https://wx4.sinaimg.cn/mw690/006Bdvtlgy1hp23p5qgz8j32ns3zk7wl.jpg'
            },
            handleChoose() {
                if (this.t != null) {
                    // 停止定时器
                    clearInterval(this.t)
                    this.t = null
                } else {
                    // 启动定时器
                    // 1 使用定时器--
                    var url_list = [
                        'https://wx1.sinaimg.cn/mw690/5dd7fe32ly1hp1yewmnucj22kl3uwnpf.jpg',
                        'https://wx1.sinaimg.cn/mw690/5dd7fe32ly1hp1yesycekj22kl3uwb2c.jpg',
                        'https://wx3.sinaimg.cn/mw690/9e948579ly1hoziysq9crj20sg0o575v.jpg',
                        'https://wx3.sinaimg.cn/mw690/005B1pXNgy1hp24sqpq2sj31jk2297kh.jpg'
                    ]
                    console.log('函数外:', this)
                    var _this = this
                    var count = 0
                    this.t = setInterval(function () {
                        if (count > 3) {
                            count = 0
                        }
                        console.log('函数内:', this)
                        _this.url = url_list[count]
                        count += 1
                    }, 1000)
                }
            }
        }
    })
</script>
</html>

5、补充style和class

# 1 style和class 也是属性,比较特殊

# 2 class 可以绑定 字符串,数组,对象
	字符串: 'div1 div2'---》字符串替换控制样式
    数组:['div1','div2']--->追加数组,删除数组控制样式
    对象:{div1: true, div2: true, div3: true, div4: false}--》通过true和false控制样式
    
# 3 style 可以绑定 字符串,数组,对象
	字符串'background-color: green;height: 300px;width: 300px'---》字符串替换控制样式
    数组:[{'background-color': 'green'}, {height: '300px'}, {width: '300px'}]--->追加数组,删除数组控制样式
    对象:{backgroundColor: 'green', height: '330px', width: '300px'} --》通过根据key修改value控制样式

    
    
# 4 坑:以后如果改了对象,或数组,发现页面没有变化,实际上值被真正的改了
	Vue.set(this.style_list,3,{'margin':'auto'})
    
# 5 哪个操作会触发响应式?哪个不会?
		不用记----》以后有问题--》使用Vue.set

6、条件渲染

1、v-show

v-show: 只是调整了display:none; , 其DOM结构还存在。
v-show 作用: 根据真假切换元素的显示状态
原理: 修改元素的display,实现显示隐藏
指令后面的内容,最终都会解析为布尔值
值为true元素显示,值为false元素隐藏
数据改变后,对应的元素显示的状态会同步更新
<div id="app">
  <h2 v-show="isShow">{{ message }}</h2>
  <input type="button" value="切换显示状态" @click="ChangeIsShow">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app=new Vue({
  el: '#app',
  data: {
    message: 'v-show指令!',
	isShow: false
  },
  methods: {
    ChangeIsShow:function(){
		this.isShow=!this.isShow;
	} 
  },
})
</script>


结果: 出现“切换显示状态”按钮,点击出现,再次点击即可消失

2、v-if

 v-if  v-else-if   v-else
  v-if:
  作用:根据表达值的真假,切换元素的显示和隐藏(移除或添加dom元素),用法与v-show类似。
	本质是通过操作dom元素来切换显示状态
  表达式的值为true,元素存在于dom树中,为false时从dom树移除
  频繁的切换v-show,反之使用v-if,前者的切换消耗小
  
  
  注:
  v-if 如果值为false,会留下一个<!---->作为标记,万一未来v-if的值是true了,就在这里插入元素
 如果有if和else就不需要单独留坑了
 如果全用上  v-if 相邻v-else-if 相邻 v-else 否则 v-else-if可以不用
 v-if和v-else-if都有等于对应的值,而v-else直接写
 v-if家族都是对元素进行插入和移除的操作

<body>
<div id="app">
    <h1>条件判断</h1>
<!--    <h2>分数:{{score}}</h2>-->
    输入分数:
    <input type="text" v-model="score">
    <h3 v-if="score>90&&score<100">优秀</h3>
    <h3 v-else-if="score>80&&score<90">良好</h3>
    <h3 v-else-if="score>70&&score<80">一般</h3>
    <h3 v-else-if="score>60&&score<70">及格</h3>
    <h3 v-else>不及格</h3>
</div>
</body>
<script>
    var vm = new Vue({
        el : '#app',
        data:{
            score:100,
        }
    })
</script>
</html>


该代码会根据输入的数字判断属于在哪个区间并给出当前区间对应的值(优秀/良好/一般/及格/不及格)

7、列表渲染v-for

1、基本使用

v-for 作用时根据数据生成列表结构/也可以理解为遍历
数组经常和v-for结合使用
· 基本语法 v-for="item in arr" ----》理解为 (item,index) in 数据
· 对象的操作 v-for="item in obj"
· 如果是数组没有id
v-for="(item,index) in arr" :class="index"


各中v-for的属性顺序(了解)
· 数组 item,index
· 对象 value,key,index
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="./vue/vue.js"></script>
    <style>
    </style>
</head>
<body>
<div id="app">
    <div class="row justify-content-center">
        <div class="col-6">
            <div class="text-center">
                <button class="btn btn-danger" @click="handleLoad">加载购物车</button>
            </div>
            <table class="table">
                <thead>
                <tr>
                    <th scope="col">商品id</th>
                    <th scope="col">名字</th>
                    <th scope="col">价格</th>
                    <th scope="col">数量</th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="(item,index) in good_list" :class="index%2==0?'table-danger':'table-primary'">

                    <td>{{index}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.price}}</td>
                    <td>{{item.count}}</td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            good_list: []

        }, methods: {
            handleLoad() {
                this.good_list = [
                    {id: 1001, name: '钢笔', price: '29999', count: 8},
                    {id: 1002, name: '钱包', price: '1299', count: 3},
                    {id: 1003, name: '鼠标', price: '99', count: 3},
                    {id: 1004, name: '书包', price: '88', count: 6},
                    {id: 1005, name: '显示器', price: '1299', count: 38},
                ]
            }
        }
    })
</script>
</html>

显示购物车

2、v-for可以循环的变量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>循环数字--item从1开始,index从0开始</h1>
    <p v-for="(item,index) in num">{{index}}</p>
    <h1>循环数组</h1>
    <div>
        <span v-for="(item,index) in hobby">{{item}} <span v-if="index!=hobby.length-1">|</span></span>

    </div>

    <h1>循环对象</h1>
    <p v-for="(value,key) in userinfo"> {{key}}:{{value}}</p>

    <h1>循环字符串</h1>
    <p v-for="item in 'quan is handsome'">{{item}}</p>

</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            num:10,
            hobby:['抽烟','喝酒','烫头'],
            userinfo:{name:'quan',age:19,height:180}
        }
    })
</script>
</html>

3、 key值的解释

1、以后写v-for 都要在标签上加 :key="key" , key必须唯一
2、 这样做的好处: 提高虚拟dom的替换效率

6.7、数据的双向绑定

# 1 针对 input 标签--》页面中输入值--》js中有对应变量

# 2 数据单向绑定:变量变---》页面变;页面变--》变量不会变
# 3 数据双响绑定:相互影响

双向绑定实现是在后端console验证,可以通过输入vm.name或者vm.name2获取值针对v-model可以直接赋值修改
单向修改会报错
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>数据单向绑定</h1>
    <input type="text" :value="name">
    <h1>数据双向绑定</h1>
    <input type="text" v-model="name2">
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            name: 'quan',
            name2:'彭于晏'
        }
    })
</script>
</html>

数据双向绑定: v-model只能应用在表单类元素(如:input、select等)
数据单向绑定: v-bind是为标签里的某个属性绑定值用的

8、事件处理

1、input标签的事件处理
		input	当输入框进行输入的时候 触发的事件
    change	当元素的值发生改变时 触发的事件
    blur	当输入框失去焦点的时候 触发的事件
    focus   当获得焦点的时候 触发的事件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.2/vue.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
    <h1>input事件</h1>
    <input type="text" v-model="name1" @input="handleInput">--->{{name1}}   #通过event.data实时输出我前端输入的数据(一个一个输出)
    <h1>change事件</h1>
    <input type="text" v-model="name2" @change="handleChange"> --->{{name2}}  # 只要发生变化就会上报数据(回车提交数据时)

    <h1>blur事件</h1>
    <input type="text" v-model="name3" @blur="handleBlur"> --->{{name3}}   当点击到其他地方的时候就会上报数据(失去焦点)

    <h1>focus事件</h1>
    <input type="text" v-model="name4" @focus="handleFocus"> --->{{name4}}   当点击输入框,数据清空(得到焦点)
</div>
</body>
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            name1:'',
            name2:'',
            name3:'',
            name4:'asdasdasd'
        },
        methods:{
            handleInput(event){
                console.log(event.data)
            },
            handleChange(){
                console.log('handlechange')  //这里就是打印‘’内的信息给console表示我数据已经输入了
            },
            handleBlur(){
                console.log('handleBlur')
            },
            handleFocus(){
                console.log('Focus')
                this.name4=''
            }
        }
    })
</script>
</html>

1、过滤案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>过滤案例</h1>
    <input type="text" v-model="myText" @input="handleInput">
    <hr>
    <ul>
        <li v-for="item in newdataList">{{item}}</li>
    </ul>

</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            myText: '',
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf', 'atome', 'atomem'],
            newdataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf', 'atome', 'atomem'],
        },
        methods: {
            // handleInput(event) {
            //     // 1 只要输入值--》myText就是输入的值
            //     // 2 通过myText对 dataList 进行过滤,只保留包含 myText  选项
            //     var _this=this
            //     this.newdataList=this.dataList.filter(function (item){
            //         if(item.indexOf(_this.myText)>=0){
            //             return true
            //         }else {
            //             return false
            //         }
            //
            //     })
            // },


            handleInput(event) {
                var _this = this
                this.newdataList = this.dataList.filter(function (item) {
                    return item.indexOf(_this.myText) >= 0
                })
            },

            handleInput(event) {
                this.newdataList = this.dataList.filter((item) => item.indexOf(this.myText) >= 0)
            },
        }


    })


    // 1 补充:数组过滤
    // var dataList = ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf', 'atome', 'atomem']
    // dataList = dataList.filter(function (item) {
    //     if(item.length>=3){
    //         return true
    //     }else {
    //         return false
    //     }
    //
    // })
    // console.log(dataList)

    // 2 补充,判断子字符串是否在字符串中
    // var myText='at'
    // var item='iatom'
    // var i=item.indexOf(myText)  // 只要返回值大于等于0,表示子字符串在字符串内部
    // console.log(i)

    // 3 过滤,只保留myText
    var myText = 'at'
    var dataList = ['a', 'at', 'atom', 'oaatom', 'be', 'beyond', 'cs', 'csrf', 'atome', 'atomem']
    dataList = dataList.filter(function (item) {
        if (item.indexOf(myText) >= 0) {
            return true
        } else {
            return false
        }

    })
    console.log(dataList)

</script>
</html>

<!-----
过滤思路:
输入框
过滤列表

通过获取输入框的内容和过滤列表的内容
然后对这两个内容进行比对过滤,还需要满足输入框内容更新,然后继续比对

现在的思路:
定义空输入框
定一个列表为原列表
然后针对这个原列表进行处理(直接与输入的内容进行比对) ---》computed 内容处理
将这个处理的过程返回的值指向要处理的列表对象(就是没处理的时候就是一个要筛选的列表,输入内容时就会根据输入的内容进行过滤)
return这段具体执行: 通过找原数据,跟输入的数据比对
然后在这个原列表中获取数据
--->

升级后的过滤版本代码展示:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.2/vue.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <h1>过滤</h1>
<div id="app">
<input type="text" v-model="inpList">

  <ul>
    <li v-for="item in filterList">{{item}}</li>
  </ul>
</div>
</body>
<script>
  var vm = new Vue({
    el:'#app',
    data:{
      inpList:'',
      DataList:['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf', 'atome', 'atomem'],

    },
    computed: {
      filterList(){
        return this.DataList.filter(item=>item.indexOf(this.inpList)>=0)
      }
    }

  })

</script>
</html>
posted @ 2024-04-27 20:03  Unfool  阅读(67)  评论(0)    收藏  举报