Vue全家桶:vue2+vue3全部搞懂:第二篇,V指令动态改变数据、触发事件

前提,建议先学会前端几大基础:HTML、CSS、JS、Ajax,不然不好懂

这一专栏知识将一次性将vue、vue2、vue3全部讲明白

一套V指令搞明白

什么是V指令?就是Vue特有功能,一个V指令能代替JavaScript的事件函数、绑定DOM元素后在修改属性、绑定DOM元素后再修改样式、遍历数组......下面直接开学

一、v-text和v-html指令

简单理解:

v-text怎么用?

【v-text】 = JavaScript里的【document.querySelector('选择器')..innerText = '......'】

在标签里设置了就可以改变里面的【文本内容】,其实也跟在标签里{{ data的成员 }}的效果是一样的

<div id="app">
    <h2 v-text="message">{{ add }}</h2> <!-- 这样v指令后,里面所有内容跟着Vue里面改动而变化,但是标签里的内容会被覆盖 -->
    <h2>{{ message }} {{ add }}</h2> <!-- 这样{{}}形式就能把里面内容都显示,这叫“差值表达式” -->
    <h2 v-text="message + '贼屌,碉堡了'"></h2> <!-- 当然这样也可以 -->
    <h2>{{ message + "是傻逼" }}</h2> <!-- 这样也行 -->
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            message: '岑梓铭',
            add: '牛逼'
        }
    })
</script>

v-html怎么用?

【v-html】 = JavaScript里的【document.querySelector('选择器').innerHTML = '......'】

在标签里设置了,就可以解析这个变量代表的HTML标签字符串,用【v-text】只能把<a>、<div>这些当成文本解析出来

<div id="app">
    <p v-text="content"></p> <!-- 区别就是v-text指令解析的是字符串 -->
    <p v-html="content"></p> <!-- v-html解析的是HTML标签代码 -->
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            content: '<a href="https://www.bilibili.com/video/BV1kC4y1E73B/?spm_id_from=333.337.search-card.all.click&vd_source=a14033a9dc67d26cdf6d03be90667434">我是HTML里的超链接</a>'
        }
    })
</script>

二、v-on就是触发事件

怎么用?

【v-on】=JavaScript里的【document.querySelector('选择器').on事件】或者          【document.querySelector('选择器').addListener('事件',function(){...}】

传统JavaScript绑定事件不就是

let xxx = document.querySelector('选择器')

xxx.on事件 = function(){
    //触发事件要干什么
}

//或者
xxx.addListener('事件',function(){
    //触发事件要干什么
})

现在【v-on】指令简化它们,【v-on:事件 = Vue的methods里的函数】就可以绑定事件以及对应的要做什么事了

甚至更简单点,【@事件 = Vue的methods里的函数】

例子

<div id="app">
    <input type="button" value="点击事件" v-on:click="method1">
    <input type="button" value="鼠标经过事件" v-on:mouseenter="method2">
    <input type="button" value="双击事件" v-on:dblclick="method3">
    <!-- 注意双击事件是dblclick,别漏了db后面的l -->

    <!-- 另外,为了方便代码书写vue还提供了更简洁的形式:@事件 -->
    <h2 @click="changeFood"> {{ food }} </h2>
</div>


<script>
    let count = 0;
    new Vue({
        el: '#app',
        methods: {
            method1: function(){
                alert('点击了一次')
            },
            method2: function(){
                document.write("鼠标经过,老子出来了")
            },
            method3: function(){
                alert("双击666")
            },
            changeFood: function(){
                if(count === 0){
                    this.food = "啥也没得吃"
                    count = 1
                }else{
                    this.food += '不换哈哈哈哈'
                } 
            }
        },
        data: {
            food: '今晚吃狗屎,点一下能换菜'
        }
    })
</script>

事件函数传参数

v-on指令绑定的事件的函数,还可以直接传参,怎么传的格式参照下面例子

例子:

<div id="text">
    <button @click="sayHi('老铁','666')">点一下输出打招呼语</button>
</div>

<script>
    new Vue({
        el: '#text',
        methods: {
            //只需要在function括号()里设对应的形参就行
            sayHi: function(p1,p2){
                alert(p1+','+p2)
            }
        }
    })
</script>

补充

【.】是修饰符,当出现【事件.xxx】这种形式的时候意思是可以直接引用这个事件他的属性、方法函数,这里列举一些常见的

【keyup鼠标弹起】或者【keydown鼠标摁下】事件的修饰符:

1、.enter => // enter键

2、.tab => // tab键

3、.delete (捕获“删除”和“退格”按键) => // 删除键

4、.esc => // 取消键

5、.space => // 空格键

6、.up => // 上

7、.down => // 下

8、.left => // 左

9、.right => // 右

10、.keyCode => //监听特定键盘按下

【click鼠标点击】修饰符:

1、click.left  => 左键点击

2、click.right  => 右键点击

3、click.middle  => 中键点击

【通用的事件修饰符】:

1、事件.stop    =>  阻止了事件冒泡 ,相当于调用了event.stopPropagation (避免父容器也受影响触发事件)

2、事件.prevent    =>  阻止了事件的默认行为,相当于调用了event.preventDefault方法(比如<a>链接默认点击了就跳转到对应的页面,这里不让他跳转)

3、事件.once    =>  绑定了事件以后只能触发一次,第二次就不会触发 

一些例子:

<div id="text">
    <a url="https://www.baidu.com/?tn=15007414_3_dg" @click.prvent="DoNothing">点一下跳转页面</button>
    <!-- 设置了@click.prvent就是阻止a超链接点击后跳转页面 -->
    <input type="text" id="text" @keyup.enter="congratulation"> 
    <!-- 设置了@keyup.enter就是摁回车键才触发事件 -->
</div>

<script>
    new Vue({
        el: '#text',
        methods: {
            DoNothing: function(p1,p2){
                alert('没用了,我设置了不让跳转')
            },
            congratulation: function(){
                alert("新年快乐!!!")
            }
        }
    })
</script>

三、v-if和v-show:条件渲染

【v-if】和【v-show】是一样的效果,简单理解他就是if-else判断,判断为“真”就显示,判断为“假”就不显示这个HTML的DOM元素,就它当没了。

【v-if】和【v-show】等于的值只能是【true或false】,但是不是说只能写【v-if = "true"】、【v-show = "true"】这样,这里【true或false】可以用Vue里的data的变量代替,而且变量不需要{{ }}括起来

例子:

<div id="app">
    <input type="button" value="点击事件" @click="changeState">
    <img src="../给别人的生日代码/img/背景图片1.jpeg" alt="" v-show="isShow"> 
    <!-- v-show的参数是true和false,直接用布尔值会固定死,可以用vue的变量或者表达式来代替固定布尔值 -->

    <h2 v-if="isShow">JDHCBWJHCIB</h2>
    <!-- 一样效果 -->
</div>
<script>
    new Vue({
        el: '#app',
        methods: {
            changeState: function(){
                this.isShow = !this.isShow //每次点击事件后isShow就变成相反的布尔值
            }
        },
        data: {
            isShow: false
        }
    })
</script>

四、v-bind改变【属性】和【类名】

【v-bind:class = " 新类名 or 三元表达式 or 对象表达式"】就可以改变类名,然后就可以使用css里对应类名的样式了

比如在css里设置了一个叫.active的类名的样式

.active{
            display: none;
        }

【v-bind:class = " 新类名"】直接获得.active的类名的样式

<h2 @click="disappear">点一下就不见</h2>
<img src="../岑家购/img/岑家购LOGO.png" v-bind:class="active">

【v-bind:class = " 三元表达式 "】根据条件判断,什么时候用.active的样式,什么时候不用

<h2 @click="disappear">点一下就不见</h2>
<img src="../岑家购/img/岑家购LOGO.png" v-bind:class=" isActive?'active':'' ">
<!-- isActive?'active':''意思就是在Vue里的data设置一个变量isActive,
在某个函数(disappear)里设置isActive的值是true还是false,
true时就获得类名active,false时就是什么类名也没有,''空字符串就是啥也没有 -->

【v-bind:class = " 对象表达式 "】推荐

<h2 @click="disappear">点一下就不见</h2>
<img src="../岑家购/img/岑家购LOGO.png" v-bind:class="{active:isActive}">
<!-- 当在Vue里的isActive为true,active就获得被作为类名给到标签,否则就啥也没有 -->

【v-bind:属性 = " ......"】可以直接修改属性

例子:

<h2 @click="change">点一下就更换</h2> 
<img v-bind:src="imgSrc">
<!-- imgSrc是Vue里data的一个变量,里面记录着不同的路径 -->

还有【v-bind可以省略】

<h2 @click="change">点一下就更换</h2> 
<img :src="imgSrc">
<!-- 跟v-bind:src="imgSrc"效果一样 -->

补充一下v-bind的修饰符:

.props

props设置自定义标签属性,避免暴露数据,防止污染HTML结构

<input id="uid" title="title1" value="1" :index.prop="index">

五、v-for遍历数组

【v-for】可以直接遍历Vue里data的某个数组,然后数组有几个,绑定了【v-for】的标签元素就有一个(这样一来多个DOM元素在HTML里就只需要写一个就够了)

例子:这里虽然只有一个<li>标签,但是会跟着arr数组显示6个<li>

<div id="app">
    <ul>
        <!-- 这里item是自定义的,代表数组的每个成员 -->
        <!-- 这里in不可以自定义,必须按格式写 -->
        <!-- 这里arr就是Vue的data里设置的数组的名字 -->
        <li v-for="item in arr">
            遍历数组里的:{{ i }}
        </li>
    </ul>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            arr: ['第一个','第二个','第三个','第四个','第五个','第六个'],
    })
</script>

如果需要用到下标的话就要【v-for="(自定义成员名 , 自定义下标名字) in arr"】这样写

<div id="app">
    <ul>
        <li v-for="(i,index) in arr">
            {{ index+1 }}、遍历数组里的:{{ i }}
        </li>
    </ul>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            arr: ['第一个','第二个','第三个','第四个','第五个','第六个'],
        }
    })
</script>

遍历对象数组的话,【自定义成员名.属性】就可以访问对象里的属性了

<div id="app">
    <button @click="add">增加数据</button>
    <button @click="reduse">减少数据</button>
    <h2 v-for="j in animal" v-bind:title="j.name">
        名字:{{ j.name }}   年龄:{{ j.age }}  类型:{{ j.type }}
    </h2>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            arr: ['第一个','第二个','第三个','第四个','第五个','第六个'],
            animal: [
                {name:'狗子',age:'18',type:'犬类'},
                {name:'猫子',age:'20',type:'猫类'},
                {name:'豹子',age:'3',type:'猫类'}
            ]
        },
        methods: {
            add: function(){
                //跟JavaScript的this一样,这里this指向这个Vue对象,this.xxx就直接是data里的某个变量成员
                //这里就是给对象数组增加数据
                this.animal.push({name:'默认',age:'?',type:'未知类'})
            },
            reduse: function(){
                //这里就是减少对象数组数据
                this.animal.shift()
            }
        }
    })
</script>

六、v-model表单与Vue数据双向流通

在标签里设置了【v-model = "xxx"】后,【表单输入的值value】和【在Vue的data里"xxx"的值】就绑定双向流通了,如果在表单里输入内容,value就会变,从而【在Vue的data里"xxx"的值】也会变;同理,如果改变了【在Vue的data里"xxx"的值】,那么【表单输入的值value】也会变。

例子:

<div id="app">
    <input type="text" v-model="message" @keyup.enter="damn">
    <!-- 加上v-model之后,此时在input里输入的新内容,value就会变,从而message的值也就变了 -->
    <h2>{{ message }}</h2>
    <!-- 既然这个message是Vue里data的值,那就可以用{{ }}绑定显示在别的元素上 -->
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            message: 'shit'
        },
        methods: {
            damn: function(){
                alert(this.message)
            }
        }
    })
</script>

这里补充一下v-model的修饰符:

1、.lazy

.lazy修饰符在input框失去焦点时进行数据同步。

v-model是在input事件下对输入框的值与数据进行同步,也就是只要开始输入内容,value的值就会实时发生变化;但如果加上lazy修饰符后,就只有点击输入框以外的地方,输入框没有光标了后再同步value数据。

<div>
    <h3>lazy修饰符</h3>
    <!-- 1、lazy:当input失去焦点时数据进行绑定 -->
    <input type="text" v-model.lazy="name"> <br> 
    {{ name }}
</div>


2、.number

.number修饰符自动将用户输入的值转为【数值类型】,输入字符串转为有效的数字。

由于默认凡是从input输入的内容,value值均为字符串类型,但实际应用场景中需要向服务器提交的数据类型为number数值类型,这时就要对input中输入的值进行转换。

<div>
    <h3>number修饰符</h3>
    <!-- 2、number:限定input输入框中输入的内容为number类型,因为默认凡是input输入的内容都是字符串类型 -->
    <input type="number" v-model.number="age"> <br>
    {{ age }} - {{ typeof age }}
</div>


3、.trim

.trim修饰符可以自动过滤用户输入的首尾空白字符。

<div>
    <h3>trim修饰符</h3>
    <!-- 3、trim:可以去除所输内容两边的空格 -->
    <input type="text" v-model.trim="hobby"> <br>
    {{ hobby }}
</div>

然后v-model的原理其实就是结合了【v-bind:value = "xxx"】和【@事件 = "xxx = e.target.value"】

这里讲一下【@事件 = "xxx = $event.target.value"】这种形式是后面讲Vue工程化开发会用到的写法,【@事件=" 函数名 "】这里不再写要绑定的函数了,而是直接把“原来函数要做的事”直接写在【@事件="  "】即可;另外想获得事件event形参的话,要写成【$event】才行,e、event这些都不行

比如下面这个例子,在input输入框内输入时直接将输入数据和data的数据双向流通,这两种写法都是一样的:

下一篇讲:Vue引入axios库发送网络数据请求

  • 29
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,那就让我们来一步步实现一个简单的Vue小作品吧。我们可以实现一个简单的待办事项应用,用户可以添加待办事项、标记已完成的事项、删除待办事项等功能。这个应用将会用到Vue数据绑定、组件、路由等技术。我们先来安装VueVue CLI。 1. 安装VueVue CLI 首先,你需要在本地安装Node.js和npm。然后,在命令行中运行以下命令安装Vue CLI: ``` npm install -g @vue/cli ``` 安装完成后,你可以在命令行中运行以下命令创建一个新的Vue项目: ``` vue create my-todo-app ``` 根据提示选择你需要的配置,Vue CLI 将会自动生成一个基础的 Vue 项目。 2. 创建一个待办事项组件 接下来,我们要创建一个待办事项组件。在项目根目录下的 `src/components` 中创建一个新的文件 `TodoItem.vue`。在这个文件中,我们将创建一个单个待办事项的组件。 ```html <template> <div class="todo-item"> <input type="checkbox" v-model="todo.completed" @change="toggleCompleted"> <span :class="{ 'completed': todo.completed }">{{ todo.text }}</span> <button @click="$emit('remove')">删除</button> </div> </template> <script> export default { props: ['todo'], methods: { toggleCompleted() { this.$emit('toggle', this.todo.id); } } } </script> <style> .completed { text-decoration: line-through; } </style> ``` 在这个组件中,我们有一个单选框来标记待办事项是否已经完成,如果待办事项已经完成,它的文本将会有删除线。我们还有一个删除按钮来删除待办事项。 3. 创建一个待办事项列表组件 接下来,我们要创建一个待办事项列表组件,它将会用来显示所有的待办事项。在项目根目录下的 `src/components` 中创建一个新的文件 `TodoList.vue`: ```html <template> <div class="todo-list"> <div v-for="todo in filteredTodos" :key="todo.id"> <TodoItem :todo="todo" @toggle="toggleTodo" @remove="removeTodo"></TodoItem> </div> </div> </template> <script> import TodoItem from './TodoItem.vue'; export default { components: { TodoItem }, props: ['todos'], computed: { filteredTodos() { return this.todos.filter(todo => { return !this.showCompleted || todo.completed === false; }); } }, data() { return { showCompleted: false }; }, methods: { toggleTodo(id) { const todo = this.todos.find(todo => todo.id === id); todo.completed = !todo.completed; }, removeTodo() { this.$emit('remove'); } } } </script> <style> .todo-list { margin-top: 20px; } </style> ``` 在这个组件中,我们使用了 `v-for` 指令来循环渲染每一个待办事项。我们还引入了之前创建的待办事项组件 `TodoItem`。我们还有一个切换已完成待办事项的开关。 4. 创建一个添加待办事项的组件 现在,我们要创建一个添加待办事项的组件。在项目根目录下的 `src/components` 中创建一个新的文件 `AddTodo.vue`: ```html <template> <div class="add-todo"> <input type="text" v-model="newTodo" placeholder="添加新的待办事项"> <button @click="addTodo">添加</button> </div> </template> <script> export default { data() { return { newTodo: '' }; }, methods: { addTodo() { if (this.newTodo) { this.$emit('add', this.newTodo); this.newTodo = ''; } } } } </script> <style> .add-todo { margin-top: 20px; } </style> ``` 在这个组件中,我们有一个文本输入框和一个添加按钮。当用户点击添加按钮时,我们将会触发一个事件来添加新的待办事项。 5. 创建一个根组件 最后,我们要创建一个根组件,它将会包含所有的子组件,并且处理待办事项的数据和状态。在项目根目录下的 `src` 中创建一个新的文件 `App.vue`: ```html <template> <div class="app"> <h1>待办事项</h1> <AddTodo @add="addTodo"></AddTodo> <div v-if="todos.length"> <TodoList :todos="todos" @remove="removeTodo"></TodoList> <div> <label> <input type="checkbox" v-model="showCompleted"> 显示已完成 </label> </div> </div> <div v-else> 没有待办事项 </div> </div> </template> <script> import TodoList from './components/TodoList.vue'; import AddTodo from './components/AddTodo.vue'; export default { components: { TodoList, AddTodo }, data() { return { todos: [], showCompleted: false, nextId: 1 }; }, methods: { addTodo:text=> { this.todos.push({ id: this.nextId++, text, completed: false }); }, removeTodo() { this.todos = this.todos.filter(todo => !todo.completed); } } } </script> <style> .app { max-width: 600px; margin: 0 auto; padding: 20px; font-family: 'Arial'; } </style> ``` 在这个组件中,我们引入了之前创建的添加待办事项组件和待办事项列表组件。我们还有一个 `data` 对象来存储待办事项的数据和状态。我们还有一些方法来添加、删除和切换待办事项的状态。 6. 添加路由 最后,我们要添加路由来让用户能够访问我们的待办事项应用。在项目根目录下的 `src` 中创建一个新的文件 `router.js`: ```js import Vue from 'vue'; import VueRouter from 'vue-router'; import App from './App.vue'; Vue.use(VueRouter); const routes = [ { path: '/', name: 'home', component: App } ]; const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }); export default router; ``` 在这个文件中,我们首先引入了 VueVue Router,并使用 Vue.use 注册 Vue Router。我们还定义了一个路由对象,它将会指向我们的根组件。最后,我们创建了一个 VueRouter 实例,并把路由对象传递进去。 7. 启动应用 到这里,我们的待办事项应用已经完成了。现在,我们可以在命令行中运行以下命令启动应用: ``` npm run serve ``` 应用将会运行在 http://localhost:8080 上,你现在可以在浏览器中访问它了。如果你想要构建一个生产环境的应用,可以运行以下命令: ``` npm run build ``` 这个命令将会生成一个可以部署的静态文件,你可以将它部署到任何能够托管静态文件的地方。 以上是一个简单的待办事项应用的实现过程,它涉及到了 Vue 数据绑定、组件、路由等技术。当然,这只是一个简单的例子,你可以根据自己的需要添加更多的功能和交互效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值