前端福利练习题

 

一、什么是vue

vue是一套用于构建用户页面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

二、与原生JS的区别

我们可以通过一个小案例来演示

案例:把输入框中的信息实时显示在span标签中

  • 原生JS

    <body>
        <input id='txt' type="text">
        <span id='con'></span>
    </body>
    <script>
        document.querySelector('#txt').addEventListener('keyup', function () {
            document.querySelector('#con').innerHTML = this.value
        })
    </script>
  • Vue

    <body>
        <div id="app">
            <input id='txt' type="text" v-model="msg">
            <span id='con'>{{msg}}</span>
        </div>
    </body>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        let app = new Vue({
            el: "#app",
            data: {
                msg: ""
            }
        })
    </script>
    
     

    区别:其中明显的区别就是省去了对DOM元素的操作

  • 总结:

    1. 创建DOM元素,使其成为Vue实例的挂载点,Vue实例中的所有数据这能在挂载点中使用

      <div id=app>
      </div>
      
       
      • 1
      • 2
    2. 通过new Vue来创建实例对象

    3. el属性指定当前Vue实例的挂载点

    4. data中是模型数据,这些数据依赖于当前Vue的实例,可以通过控制台输入app.msg来查看数据

    5. 可以通过插值表达式使用data中的数据

三、数据绑定

数据绑定就是将Vue实例中的data属性中的数据显示在挂载点中

1、内容绑定

将data中的数据显示成内容

<div id='app'>
    <p>{{msg}}</p>
</div>
 

若想显示html标签只要是标签中用v-html即可

<div id='app'>
    <p v-html>{{msg}}</p>
</div>
 

2、属性绑定

将data中的数据作为某个元素的属性值

使用v-bind即可,属性可以是内置的,也可以自定义的,简写方式:

<p v-bind:id="id" :class="class">{{msg}}</p>
 
  • 1

3、表单标签的值

可以使用v-model指令在表单标签中使用双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素

1、文本框和文本域

<input type:'text' v-model="msg"></input>
<textarea v-model:'msg'><textarea>
 

2、复选框

<div id='app'>
	<lable for:'swim'><lable>
    <input type='checkbox' id=swim v-model='isSwim'/>
    <label for="read">阅读</label>
    <input type="checkbox" id="read" v-model="isRead">
    <label for="play">游戏</label>
    <input type="checkbox" id="play" v-model="isPlay">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
 	let app = new Vue({
        el:"#app",
        data:{
            isSwim:true,
            isRead:true,
            isPlay:false
        }
    })       
 </script>
 

单选框

<div id="app">
	<label for="man">男</label>
    <input type="radio" id="man" value="man" v-model="gender">
    <label for="women">女</label>
    <input type="radio" id="women" value="women" v-model="gender">
   {{gender}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
 	let app = new Vue({
        el:"#app",
        data:{
           gender:''
        }
    })       
 </script>
 

下拉框

<div id="app">
    <select v-model="city">
      <option disabled value="">请选择</option>
      <option value="bj">北京</option>
      <option value="sh">上海</option>
    </select>
    {{city}}
  </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
 	let app = new Vue({
        el:"#app",
        data:{
        city:""
        }
    })       
 </script>
 

传递参数

<div id='app'>
	<button v-on:click="showInfo('hello')">按钮</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	let app = new Vue({
        el:"#app",
        data:{
            title:"元旦"
        },
        methods:{
            showInfo:function(message){
                console.log(message)
            }
        }
    })
</script>
 

四、事件处理

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

<div id=app>
    <button v-on:click='greet'></button>
</div>
 
var app = new Vue({
    el:'#app',
    data:{
        name:'holle Vue'
    },
    //在 methods 中定义方法
    methods:{
        greet:function(event){
            //this在方法中指向Vue实例
            alert(this.name + '!')
            if (event) {
        		alert(event.target.tagName)
        	}
    }
})
 

五、列表渲染

我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名

<div id='app'>
	<ul>
 		<li v-for="blog in blogs">{{blog}}</li>
    </ul>
    <ul>
        <li v-for="stu in stus">姓名:{{stu.name}} 年龄:{{stu.age}}</li>
    </ul>
</div>
 
var app = new Vue({
    el:"#app",
    data:{
        blogs:['三国演习','西游记','老夫子'],
        stus:[
            {name:'小明',age:18},
            {name:'小张',age:11},
            {name:'小王',age:12}
        ]
    }
})
 

从服务器中获取数据

<body>
    <div id="app">
      <ul>
        <li v-for="item in books">{{item.title}}</li>
      </ul>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      let app = new Vue({
        el: '#app',
        data: {
          books: [],
        },
        created: function () {
          fetch('data.json')
            .then((res) => {
              return res.json()
            })
            .then((res) => {
              this.books = res
            })
        },
      })
    </script>
 

六、条件渲染

1、v-if指令用于条件性的渲染一块内容

<div v-if=true>hello Vue</div>
 

2、也可以使用v-else添加一个else块

<div v-if=false>hello Vue</div>
<div v-else>hello world</div>
 

3、在<template>元素上使用v-if条件渲染分组

当需要切换多个元素的时候可以把v-if添加到template内,因为<template>元素是一个不可见元素,渲染的结果将不包含<template>元素

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>
 

4、v-if-else顾名思义就是充当v-if的else if块,可连续使用

<div v-if="score==100">
    满分
</div>
<div v-else-if="score>=80 && score<100">
    良好
</div>
<div v-else-if="score>=70 && score<=60">
    及格
</div>
<div v-else-if="score<60">
    不及格
</div>
<div v-else>
    请输入正确的成绩
</div>
 

5、v-show同样是根据条件展示元素

<div v-show="ok">hello</div>
 

 

v-if不同的是v-show的元素会始终被渲染并保留在DOM中。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

七、Class与Style绑定

我们可以使用v-bind来绑定类名或内联样式

绑定class,以动态的切换class,也可以与普通的class共存

<div class="static" v-bind:class="{active:isActive,'text-danger:hasError'}"></div>
 
data{
    isActive:true
    hasError:false
}
 

渲染结果为:

<div class='static active'></div>
 

绑定内敛级样式

语法v-bind:style

<div v-bind:style='{color:activeColor,fontSize:fontSize+'px'}'></div>
 
data:{
    activeColor:"red",
    fontSzie:13
}
 

也可以直接绑定到一个样式对象中,这样会使模板更清晰

<div v-bind:style="active"></div>
 
data:{
    active:{
        color:'red',
         fontSize:'30px'
    }
}
 

八、计算属性

当我们需要计算模板中的值时可以使用计算属性(computed)

<div id="#app">
    <p>{{message}}</p>
    <p>{{reverseMessage}}</p>
</div>
 
var app = new Vue({
    el:"#app",
    data:{
        message:"Hello"
    },
    computed:{
        reverMessage(){
            return this.message.split('').reverse().join('')
        }
    }
})
 

九、侦听器

侦听器可以观察和响应Vue实例上的数据变动

<div id="app">
    <div>
        问题:<input v-model="question">
    </div>
    
    <div>{{answer}}</div>
</div>
 
  var app = new Vue({
        el: "#app",
        data: {
            question: "",
            answer: [],
        },
        watch: {
            question(newValue) {
                this.getAnswer()
            }
        },
        methods: {
            getAnswer: function () {
                let that = this
                axios.get('http://localhost:3000/answer.php?q=' + this.question)
                    .then(function (response) {
                        that.answer = response.data
                    })
            }
        }
    })
 

php代码

<?php
    $question = $_GET['q'];
	$answer=[];
	switch($question){
        case "小":
        $answer=['小孩子','小姐姐','小鲜肉'];
        break;
        case "小鲜肉":
        $answer=['小鲜肉是什么','小鲜肉有什么用','小鲜肉可以吃吗'];
            break;
        case "小鲜肉演戏":
        $answer=["小鲜肉演戏太假","小鲜肉被封杀","小鲜肉不会做演员"];
        break;
    }
echo json_encode($answer);
?>
 

演示

nswer = response.data
})
}
}
})


php代码

```php
<?php
    $question = $_GET['q'];
	$answer=[];
	switch($question){
        case "小":
        $answer=['小孩子','小姐姐','小鲜肉'];
        break;
        case "小鲜肉":
        $answer=['小鲜肉是什么','小鲜肉有什么用','小鲜肉可以吃吗'];
            break;
        case "小鲜肉演戏":
        $answer=["小鲜肉演戏太假","小鲜肉被封杀","小鲜肉不会做演员"];
        break;
    }
echo json_encode($answer);
?>
 

演示

在这里插入图片描述

十、插槽

插槽内容

var el_div = {
    template:`
	<div><slot></slot></div>
	`
}
 
<div id=app>
	<el-div>
        <span>插槽内容</span>
    </el-div>
</div>
 

当组件渲染时,slot会被替换为<span>插槽内容</span>。插槽内可以包含任何模板代码

后备内容

有时为一个插槽设置具体的后备 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染。例如在一个 <submit-button> 组件中:

<button type="submit">
  <slot></slot>
</button>
 

我们可能希望这个 <button> 内绝大多数情况下都渲染文本“Submit”。为了将“Submit”作为后备内容,我们可以将它放在 <slot> 标签内:

<button type="submit">
  <slot>Submit</slot>
</button>
 

现在当我在一个父级组件中使用 <submit-button> 并且不提供任何插槽内容时:

<submit-button></submit-button>
 

后备内容“Submit”将会被渲染:

<button type="submit">
  Submit
</button>
 

在这里插入图片描述

但是如果我们提供内容:

<submit-button>
  Save
</submit-button>
 

则这个提供的内容将会被渲染从而取代后备内容:

<button type="submit">
  Save
</button>
 

在这里插入图片描述

具名插槽

有时我们需要多个插槽。例如对于一个带有如下模板的 <base-layout> 组件:

<div class="container">
  <header>
    <!-- 我们希望把页头放这里 -->
  </header>
  <main>
    <!-- 我们希望把主要内容放这里 -->
  </main>
  <footer>
    <!-- 我们希望把页脚放这里 -->
  </footer>
</div>
 

对于这样的情况,<slot> 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
 

一个不带 name<slot> 出口会带有隐含的名字“default”。

在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
 

现在 <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot<template> 中的内容都会被视为默认插槽的内容。

然而,如果你希望更明确一些,仍然可以在一个 <template> 中包裹默认插槽的内容:

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
 

任何一种写法都会渲染出:

<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>
 
------------------------------------