vue复习
1.试述前端开发技术发展变化历程,理解推动技术发展动力以及对软件开发职业的启发。
2.当前前端开发技术主要特征有哪些?
前后端分离开发:
前端专注页面展示效果与用户使用体验,后端专注为前端提供数据和服务。
工程化特征:模块化、组件化、规范化、自动化
模块化:采用分治思想,将大文件拆分成小文件,每个小文件只负责一个功能,降低复杂度,提高复用率。针对js部分。
组件化:组件化是对交互界面的拆分,是包含html、css、js的功能相对完备的结构单元,提现分治、封装、复用的思想,(分治:将大页面分为小组件,降低复杂度,提高可维护性;封装:组件内部实现逻辑不用关心,组件内变化也不会影响到全局;复用:避免大量重复代码)
规范化:提升效率,降低沟通成本。
自动化:自动化的工具,提升效率,有包管理工具(npm 和yarn)、自动化构建工具(webpack、grunt,gulp)、规范化工具(eslint和stylelint)
MVVM模式:
响应式布局:
布局响应式和数据响应式
3.常用的技术框架和ui框架都有哪些?这些框架在前端开发框架的作用。
4.块级元素和行内元素的特点有哪些?分别列出在html中不少于5个行元素和行内元素。
5. 在css中常用选择器有哪些?
标签选择器、id选择器(#para1{textGalign:center;color:red;})、class选择器(.center{textGalign:center;})、后代选择器(.container .p-font{color:red})、伪类选择器
6. 在css中常用计量单位都有哪些?响应式界面布局编程中如何使用?
响应式不要用px就可以了
7. 试描述less的主要特征及使用less能带来什么好处?
less是预处理语言和扩充了css,通过编译器将其转换成css文件,再交给浏览器使用,增加了变量、嵌套、混入、函数、继承等功能。
好处:提高效率、代码复用、易于维护、动态样式生成。
8.举例说明什么是JavaScript变量的作用域。
变量的作用域就是变量在代码中可使用的范围,全局、局部、块级作用域。
9.什么是原型链以及原型链的作用?
function Person(name, age) {this.name = name;this.age = age;this.sayHello = function() {console.log(`hello my name is ${this.name}`);}
}function Teacher() {this.giveLessons = function() {console.log("授课");}
}Teacher.prototype = new Person("winkle", 40);function MusicTeacher() {this.musicPlay = function() {console.log("弹钢琴");}
}MusicTeacher.prototype = new Teacher();// 创建MusicTeacher实例
var obj = new MusicTeacher();// 调用方法并观察控制台输出
obj.giveLessons(); // 输出: 授课
obj.sayHello(); // 输出: hello my name is winkle
obj.musicPlay(); // 输出: 弹钢琴
Teacher.prototype = new Person("winkle", 40); //创建了一个新的Person
实例,name
为"winkle"
,age
为40 //
将这个实例赋值给Teacher
的prototype
属性。这意味着所有通过Teacher
构造函数创建的对象都会继承这个Person
实例的属性和方法(包括sayHello
)
MusicTeacher.prototype = new Teacher();
这行代码创建了一个新的Teacher
实例,并将其赋值给MusicTeacher
的prototype
属性。由于Teacher
的原型已经被设置为一个Person
实例,因此通过MusicTeacher
创建的对象将继承Teacher
和Person
的属性和方法。
var obj = new MusicTeacher();
这行代码创建了一个新的MusicTeacher
实例。
console.log(obj)
打印出obj
对象,可以看到它包含了MusicTeacher
、Teacher
和Person
的属性和方法。obj.giveLessons()
调用giveLessons
方法,打印出"授课"
。obj.sayHello()
调用sayHello
方法,打印出"hello my name is winkle"
,因为Teacher
的原型是设置为具有"winkle"
名字的Person
实例。
10.什么是异步编程,异步编程实现方式是什么?
. /* 定义一个异步任务 * /2.function getData(success, error) {3. var flag= false4. {/* 此处编写异步任务代码 , 如 : 等待后台读取数据 , 如果获取成功 flag= true * /5. flag = true6. }7. if (flag) {8. success() // 执行函数 success9. } else {10. error() // 执行函数 error11. }12.}13.14./* 成功后的数据处理 * /15.function fn1() {16. console.log(" 执行了成功时的回调函数 ")17.}18./* 失败后资源的释放等问题 * /19.function fn2() {20. console.log(" 执行了失败时的回调函数 ")21.}22./* 执行任务 , 根据结果执行函数 fn1 或 fn2 * /23.getData(fn1, fn2)
回调函数与普通的函数没有任何区别,主要是回调函数总是作为一个函数的参数出现, 待处理完成后在调用
11.使用JavaScript编写一个发布订阅程序。
12.什么是回调地狱,promise如何解决回调问题的?
1.new Promise(resolve = > {2. setTimeout(() = > {3. resolve(10) //1000MS 后 第一个 PROMISE 实例状态是成功 VALUE:104. }, 1000)5.}). then(res = > {6. console.log(` 成功 : ${res}`) /* 成功 :10' * /7. return res * 5 /* 传递数据 * /8.}, reason = > {9. console.log(` 失败 : ${reason}`)10. return reason * 1011.}).then(res = > {12. console.log(` 成功 : ${res}`)13. return res * 514.}, reason = > {15. console.log(` 失败 : ${reason}`)16. return reason * 10;17.})
13.在es6中模块化导出中export和export default两个关键字有什么区别,使用import导入时有哪些注意事项?
1.export关键字可以导出模块中的函数、变量、常量、对象,
2.
通常将 export 关键字放在 JavaScript 文件的尾部 , 一次可以导出多项内容;export 关键字不能使用在块作用域中 , 否则报错 ;命名式导出可以导出多个成员, 默认导出则仅能导出一个成员 .命名式导出可以出现多次 , 而默认导出一个模块却仅能使用一次
命名式导入一次可以导入多个成员 , 引入的成员名称要与导出的成员名称相同.默认导入仅能导入一个成员 , 使用 import 引入时无需了解导出模块的细节;导入关键字 import 必须放在文件的最开始 , 且前面不允许有其他逻辑代码, 这和其他所有编程语言风格是一致 .
14.试述html、css和JavaScript在编码中的常用规范。
15.简述vue的特点是什么?
渐进式框架
16.什么是vue模板和vue模板语法?
17.什么是vue模板语法,在vue模板语法中主要使用形式有哪些?
18.什么是属性绑定,进行属性绑定时有哪些注意事项?
1.单个属性绑定
2.多个属性帮绑定v-bind="对象"
1.< div id= "app">2. < input v G bind= "inputAtt" />3.< /div>4.5.< script>6. const {7.8. createApp9. } = Vue10.11. let app = createApp({12. data() {13. return {14. inputAtt: {15. type: 'text',16. name: 'userName',17. value: '绑定多个属性'18. }19. }20. }21. })22. app.mount('#app')23.< /script>
3.绑定表达式
样式绑定
19.条件渲染中v-if指令和v-show指令有什么区别?为什么要设置key?
20.常见的表单类型有哪些?使用v-model指令如何绑定?
21.按照第6节综合示例的要求,完成表单数据采集。
22.过渡与动画
<template><div align="center" style="margin-top: 100px;"><button @click="show = !show">测试</button><transition><div v-if="show"><p>这是一段文字</p></div></transition></div>
</template><script>
export default {name: 'transitionTest',data() {return {show: true}}
}
</script><style scoped>
.v-enter-active, .v-leave-active {transition: all 0.5s;
}
.v-enter {transform: translateY(50px);opacity: 0;
}
.v-leave-to { /* 或者使用 .v-leave-active 如果您的意图是定义过渡期间的样式 */transform: translateY(-50px); /* 假设您想要在离开时向上移动文本 */opacity: 0; /* 离开时完全透明 */
}
</style>
23.为什么要限制使用v-on指令绑定代码片段?
<div id="app"><input type="button" value="事件监听" v-on:click="calcValue2($event)" /><input type="button" value="简写" @click="calcValue2($event)" />
</div><script src="../utils/vuejs.js"></script>
<script>const { createApp } = Vue;let app = createApp({methods: {calcValue2(event) {alert('Hello ' + event.target.tagName + '! ');}}});app.mount('#app');
</script>
点击任何一个按钮时,都会弹出一个警告框,显示“Hello BUTTON! ”,其中BUTTON
是按钮元素的标签名。
<div id="app"><input type="button" value="方法传参" @click="hello('winkle')" />
</div><script src="../utils/vuejs.js"></script>
<script>const { createApp } = Vue;let app = createApp({methods: {hello(name) { // 修正了方法定义的大括号alert(`${name} say hello`);}}});app.mount('#app');
</script>
24.什么是事件冒泡现象,vue为了处理冒泡现象提供了哪些修饰符?
<div class="outter" @click="outterClick"><div class="inner" @click.self="divClick"><input type="button" value="self 按钮" @click="btnClick" /></div>
</div><div class="outter" @click="outterClick"><div class="inner" @click="divClick"> <!-- 移除了.self修饰符,因为您可能想要正常触发div的点击事件 --><input type="button" value="stop 按钮" @click.stop="btnClick" /></div>
</div><script>
const { createApp } = Vue;
let app = createApp({methods: {outterClick() {alert('Outer div clicked!');},divClick() {alert('Inner div clicked!');},btnClick() {alert('Button clicked!');}}
});
app.mount(document.body);
</script>
当点击self按钮时,执行按钮的单击事件,再执行外部dom绑定的事件;点击stop按钮时,仅执行了按钮的单击事件.
25.在vue生命周期中,有哪些钩子函数,其执行时机是什么?
<div id="app"></div><script>
// 假设Vue已经通过CDN或NPM等方式被正确引入
const { createApp } = Vue;let app = createApp({data() {return {message: '' // 用于存储从服务器获取的数据};},created() {alert('created ==== 2'); // 当实例被创建后调用// 通常不会在这里进行异步数据获取,因为DOM还未挂载},beforeMount() {alert('beforeMount ==== 3'); // 在挂载开始之前被调用// 这里的DOM元素还未被替换},mounted() {alert('mounted ==== 4'); // 在挂载完成后被调用// 此时可以进行异步数据获取,因为DOM已经可用this.fetchData();},beforeUpdate() {alert('beforeUpdate ==== 5'); // 在数据更新之前调用},updated() {alert('updated ==== 6'); // 在由于数据变化导致的虚拟DOM重新渲染和打补丁之后调用},beforeUnmount() { // Vue 3中,beforeDestroy已更名为beforeUnmountalert('beforeUnmount ==== 7'); // 在卸载组件实例之前调用},unmounted() { // Vue 3中,destroyed已更名为unmountedalert('unmounted ==== 8'); // 在卸载组件实例后调用},methods: {fetchData() {// 模拟异步数据获取,例如通过API调用setTimeout(() => {this.message = '数据已成功加载!';// 这里可以添加其他逻辑,比如更新DOM或触发其他事件}, 2000); // 模拟2秒的延迟}}
});app.mount('#app');
</script>
26.钩子函数mounted和created都可以获取后端提供的数据,二者有什么区别?
27.什么是深度监听?为什么要设置深度监听?
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue Example</title><!-- 引入Vue库 --><script src="https://unpkg.com/vue@next"></script>
</head>
<body><div id="app"><input type="number" v-model="n"></div><script>// 使用Vue的createApp方法创建一个新的Vue应用const { createApp } = Vue;let app = createApp({data() {return {n: 0 // 初始化数据n为0};},watch: {// 监听n的变化n(newValue, oldValue) {let msg = `n的值由${oldValue}变为${newValue}`;alert(msg); // 当n变化时,弹出警告框显示变化信息}}});// 将Vue应用挂载到id为app的DOM元素上app.mount('#app');</script>
</body>
</html>
在输入框中输入数字时,每次输入值变化,都会弹出一个警告框,显示n
的值从什么变为了什么
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue Example</title><!-- 引入Vue库 --><script src="https://unpkg.com/vue@next"></script>
</head>
<body><div id="app"><!-- 使用v-for指令循环渲染城市列表 --><p v-for="item in citys">{{ item }}</p><!-- 点击按钮调用changeCitys方法改变数组中的值 --><button @click="changeCitys">改变数组中的值</button></div><script>const { createApp } = Vue;let app = createApp({data() {return {citys: ['西安', '北京', '上海'] // 初始化城市列表};},watch: {// 监听citys数组的变化citys: {deep: true, // 深度监听数组内部的变化handler: function(newValue, oldValue) {// 注意这里应该使用citys而不是nlet msg = `citys的值由${JSON.stringify(oldValue)}变为${JSON.stringify(newValue)}`;alert(msg); // 当citys变化时,弹出警告框显示变化信息}}},methods: {changeCitys: function() {// 改变数组中的第一个元素this.citys[0] = '郑州';}}});// 将Vue应用挂载到id为app的DOM元素上app.mount('#app');</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue Example</title><!-- 引入Vue库 --><script src="https://unpkg.com/vue@next"></script>
</head>
<body><div id="app"><!-- 使用v-model指令绑定输入框的值到person.name --><input v-model="person.name" /></div><script>const { createApp } = Vue;let app = createApp({data() {return {person: { name: '张三', age: 18, sex: '女' } // 初始化person对象};},watch: {// 监听person对象的变化,需要深度监听person: {deep: true, // 深度监听对象内部属性的变化handler: function(newValue, oldValue) {// 注意这里应该使用person而不是nlet msg = `person的值由${JSON.stringify(oldValue)}变为${JSON.stringify(newValue)}`;alert(msg); // 当person变化时,弹出警告框显示变化信息}}}});// 将Vue应用挂载到id为app的DOM元素上app.mount('#app');</script>
</body>
</html>
将会看到一个包含输入框的网页。当您在输入框中输入内容时,person.name
的值会实时更新,并且每次更新都会触发watch
监听器,弹出一个警告框显示person
对象的旧值和新值。上例中当对象中任何一个属性发生变化时,都可以被监听到,但是同数组 监听相同,是无法获取更改前的值.这种对象监听方式通常在关闭窗口时使用,检测数据是否被修改,如果修改,则提示保存信息.
28.属性监听和计算属性区别是什么?
属性监听(watch) | 计算属性(computed) | |
---|---|---|
定义 | 监视数据属性的变化,并在变化时执行回调函数 | 基于其他数据属性动态计算并返回一个新的值 |
触发时机 | 数据变化时立即触发 | 依赖的数据变化时触发,但结果会被缓存 |
执行逻辑 | 可以执行异步操作或复杂逻辑 | 通常用于同步计算,结果会被缓存 |
适用场景 | 需要对数据变化进行响应并执行副作用时 | 需要基于其他数据计算新值时 |
性能 | 每次数据变化都会触发,可能影响性能 | 由于缓存机制,性能更优 |
获取变化前后的值 | 可以获取数据变化前后的值 | 只能获取当前的值,不能获取之前的值 |
多属性监听 | 可以监听单个或多个属性的变化 | 一个计算属性可以依赖多个数据源 |
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue 3 Example</title>
</head>
<body><div id="app"><p>{{ msg }}</p><p>{{ reversedMessage }}</p></div><script>const { createApp } = Vue;let app = createApp({data() {return {msg: 'hello',};},computed: {reversedMessage() {return this.msg.split('').reverse().join('');}}}).mount('#app');</script>
</body>
</html>
29.在哪些场景使用计算属性,哪些场景使用属性监听?
解释1:Vue.js组件的生命周期可以大致分为以下几个阶段:
- 创建阶段:在这个阶段,组件实例被创建,并且
data
和props
被初始化。beforeCreate
和created
这两个钩子函数在这个阶段被调用。beforeCreate
:在这个阶段,组件实例还没有被完全初始化,data
和methods
等选项都还没有被设置到实例上,因此在这个阶段无法访问到它们。created
:在这个阶段,组件实例已经被完全初始化,data
和props
已经被设置到实例上,并且可以访问到。但是,在这个阶段,组件的模板还没有被渲染,也没有挂载到DOM上。
- 挂载阶段:在这个阶段,组件的模板被渲染成虚拟DOM,然后虚拟DOM被挂载到真实的DOM上。
beforeMount
和mounted
这两个钩子函数在这个阶段被调用。beforeMount
:在这个阶段,模板已经被渲染成虚拟DOM,但是还没有挂载到真实的DOM上。mounted
:在这个阶段,组件已经被挂载到真实的DOM上,可以进行DOM操作。
- 更新阶段:当组件的
data
、props
或计算属性等发生变化时,组件会重新渲染。beforeUpdate
和updated
这两个钩子函数在这个阶段被调用。beforeUpdate
:在这个阶段,组件的虚拟DOM已经更新,但是还没有应用到真实的DOM上。updated
:在这个阶段,组件的虚拟DOM已经应用到真实的DOM上,DOM已经更新。
- 销毁阶段:当组件被销毁时,
beforeDestroy
和destroyed
这两个钩子函数被调用。beforeDestroy
:在这个阶段,组件实例仍然完全可用,但是在这个阶段之后,组件将被卸载。destroyed
:在这个阶段,组件已经被完全销毁,所有的事件监听器和子实例也都被移除。
因此,在created
钩子函数中,您可以安全地访问和使用data
和props
中定义的数据,因为它们已经在这个阶段之前被初始化和设置了。
解释2:您提到的内容是关于Vue.js中watch
选项的immediate
属性的正确描述。在Vue.js中,当你使用watch
来监听一个数据属性的变化时,默认情况下,这个监听器会在该属性第一次变化时触发,而不是在组件实例创建和数据初始化时立即触发。虽然immediate
属性可以让监听器在数据初始化时立即执行,但它并不会改变监听器的基本行为——它仍然只会在监听的数据属性发生变化时执行(除非设置了immediate: true
,这样它会在初始化时也执行一次)。此外,如果监听的是一个计算属性或者是一个深度监听(使用了deep: true
),immediate
属性的行为也是类似的。
30.试述前端开发中常用自动化工具的作用。
单页面应用开发过程中,需要使用的自动化工具包括:包管理工具(npm)、自动化构建工具(webpack)、代码格式化工具(eslint)等。
npm使用该工具, 开发者可以很方便地下载、安装、上传及管理应用包
npminstallwebpack-s-dev
31.执行npm工具常用命令,观察并分析package.json中文件的变化。
完成node安装,即可完成npm 的安装.
{"name": "项目名称","version": "1.0.0","description": "项目简介","author": "作者","private": true,"scripts": {/* scripts作用是将长命令转换成短命令, 使用key代替value */"dev": "webpack-dev-server","start": "npm run dev"},"dependencies": {/* 运行依赖项 */"babel-polyfill": "^6.26.0"},"devDependencies": {/* 开发依赖项 */"axios": "^0.18.1"},"engines": {"node": ">=6.0.0","npm": ">=3.0.0"},"browserslist": ["> 1%","last 2 versions","not ie <= 8"]
}
const path = require('path');module.exports = {// 模式,'development' 或 'production',用于启用Webpack的内置优化mode: 'development', // 注意这里修正了拼写错误,从 'delelopment' 改为 'development'// 入口文件entry: path.join(__dirname, 'src', 'index.js'),// 输出文件output: {// 文件路径,使用path.join可以确保在不同操作系统上路径的正确性path: path.join(__dirname, 'dist'),// 文件名filename: 'bundle.js'}
};
1.const Webpack = require('Webpack')2.module.exports = {3. // 入口文件 、 出口文件 、 插件配置4. devServer: {5. port : 8081, // 端口号6. static:path.join(__dirname,'src'), // 资源目录7. hot:true8. }9.}
32.使用vue-cli脚手架创建项目,并分析创建程序的目录结构及文件。
<template><div id="app"><img src="./assets/logo.png" alt="Logo"><router-view></router-view></div>
</template><script>
export default {name: 'App'
}
</script><!-- 如果有样式,可以在这里添加 -->
<style scoped>
/* 您的样式代码 */
</style>
// 引入 createApp 函数,用于创建 vue 实例
import { createApp } from 'vue';// 引入根组件 App
import App from './App.vue';// 引入路由配置
import router from './router';// 引入 Pinia 状态管理
import { createPinia } from 'pinia';// 创建 Vue 实例
const app = createApp(App);// 使用路由
app.use(router);// 创建 Pinia 实例并使用
const pinia = createPinia();
app.use(pinia);// 挂载 Vue 应用到 DOM 中的 #app 元素
app.mount('#app');
33.使用vite创建项目,并分析创建程序的目录结构及文件。
34.简述vue程序需要遵循的规范和标准。
35.由软件开发的分治思想和面向对象封装性的特征,分析前端组件式开发的必要性。
36.按照下图要求编写租房列表组件,并以此为例说明组件常用的通信方式有哪些?
37.使用插槽设计一个网站的footer,然后说明什么是匿名插槽和具名插槽。
38. 试描述vue组件开发中应该遵循哪些命名规范?