vue面试题(day04)
vue面试题
- vue插槽?
- vue3中如何获取refs,dom对象的方式?
- vue3中生命周期的和vue2中的区别?
- 说说vue中的diff算法?
- 说说 Vue 中 CSS scoped 的原理?
- vue3中怎么设置全局变量?
- Vue中给对象添加新属性时,界面不刷新怎么办?
- 谈谈对Vue中双向绑定的理解?
- 为什么vue2和vue3语法不可以混用?
- vue3中setup函数如何进行组件通讯?
vue插槽?
slot又名插槽,是vue的内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而在一个标签元素是否显示,以及怎么显示是父组件决定的。slot又分为三类,默认插槽,具名插槽,作用域插槽。
默认插槽:又称匿名插槽,当slot没有指定name属性值的时候,一个组件内只能有一个匿名插槽。
首先在父组件中引入子组件,并在引入的子组件标签内插入需要的html元素,在子组件中把需要用插槽的地方用<slot>标签替代
具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽。
父组件
<template v-slot:名称>
内容
</template>
子组件
<slot name="name名称"></slot>
作用域插槽:默认插槽,剧名插槽的一个变体,可以是匿名插槽,也可以是具名插槽,作用域插槽
数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定,也就是说,作用域插槽的不同之处就在于,数据不在父组件身上,而是在子组件身上,且组件的结构和内容由父组件决定。作用域组件限定了组件内结构和数据的展示范围,以便在开发中我们可以根据一个组件而不断变换其中的内容和结构。
//子组件
<footer>
<ul>
<li v-for="(item,index) in data" :key="index">
<slot :item="item">
{{ item.hobby}}——{{ item.check}}
</slot>
</li>
</ul>
<span>{{ nums }}</span><button>+</button>
</footer>
//父组件
<template v-slot="{item}">
{{ item.hobby }}
</template>
vue3中如何获取refs,dom对象的方式?
方式一:setup函数方法内,获取单个ref属性绑定的dom元素:
// 先定义一个空的响应式数据ref定义的
// setup中返回该数据,你想获取哪个dom元素,在该元素上使用ref属性绑定该数据即可。
<template>
<h1 ref="box">Ref属性获取dom</h1>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
setup () {
let box = ref(null)
onMounted(function () {
console.log(box.value);
})
return {
box
}
}
}
</script>
方式二:获取多个ref属性绑定的dom元素。
使用ref绑定一个函数,在函数里把dom添加到数组里面
<template>
<h3 :ref="getlist" v-for="index in 3">我是一组元素{{index}}</h3>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
name: 'Ref',
setup () {
// 获取v-for遍历的元素
// 定义一个空数组,接收所有的LI
// 定义一个函数,往空数组push Dom
let listDom = []
const getlist = (el) => {
listDom.push(el)
}
console.log(listDom);
return {
getlist
}
}
}
</script>
总结:
单个元素: 先声明ref响应式数据,返回给模板使用,通过ref绑定数据
遍历的元素:先定义一个空数组,定一个函数获取元素,返回给模板使用,通过ref绑定这个函数
vue3中生命周期的和vue2中的区别?
点击查看详情
说说vue中的diff算法?
点击查看详情
说说 Vue 中 CSS scoped 的原理?
在vue文件中的style标签上,有一个特殊的属性:scoped。当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,也就是说,该样式只能适用于当前组件元素。通过该属性,可以使得组件之间的样式不互相污染。如果一个项目中的所有style标签全部加上了scoped,相当于实现了样式的模块化。
vue中的scoped属性的效果主要通过PostCSS转译实现
PostCSS给一个组件中的所有dom添加了一个独一无二的动态属性,然后,给CSS选择器额外添加一个对应的属性选择器来选择该组件中dom,这种做法使得样式只作用于含有该属性的dom——组件内部dom。
vue3中怎么设置全局变量?
在vue2中,我们知道vue2.x是使用Vue.prototype. x x x x = x x x 来定义全局变量,然后通过 t h i s . xxxx=xxx来定义全局变量,然后通过this. xxxx=xxx来定义全局变量,然后通过this.xxx来获取全局变量。
但是在vue3中,这种方法显然不行了。因为vue3中在setup里面我们是无法获取到this的。
vue3.0依赖注入的方式注册使用全局变量
在 main.js 中
const app = createApp(App)
// 配置全局变量 页面中使用 inject 接收
app.provide('global',{
store,
axios
})
app.use()进行使用
采用这种方法在全局变量的创建上会更加的方便 , 而且不用担心会出现像axios在使用globalProperties设置为全局对象后丢失
a
x
i
o
s
对象只剩
axios对象只剩
axios对象只剩http之类的问题。
vue3.0store仓库进行存放全局变量
创建store文件夹
store文件夹下创建index文件
state中定义状态或数据
const store = createStore({
state () {
return {
base:"",//基本数据
}
},
mutations: {
/*修改基础数*/
changeBase(state,base) {
state.base=base;
},
}
})
export default store;
.组件使用
store.commit("changeBase","test")//设置全局变量的值
let data=store.state.lnglat//取用全局变量的值
Vue中给对象添加新属性时,界面不刷新怎么办?
vue2的响应式原理使用的是对象代理去实现的,对象代理中有一个get和set方法,当我们访问对象的时候就会触发get方法,当我们对对象中的值进行修改时会触发set方法。但是当我们给对象添加一个新的属性时对象代理是检测不到的,所以就会出现直接给对象添加属性响应式不生效的问题。
所以在vue中可以使用this.$set(对象名,‘属性名’,属性值)的方法去给对象添加属性,或者使用Vue.set(对象名,‘属性名’,属性值)的方法进行添加,添加之后的属性就带有响应式了
谈谈对Vue中双向绑定的理解?
vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
VUE双向数据绑定,其核心是 Object.defineProperty()方法,给Vue中的数据绑定get和set方法,当获取数据的时候,调用get方法,修改data中的数据的时候调用set方法,通过watcher监听器去更新视图,完成数据的双向绑定。
1. 需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter这样的话,
给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化。
2. compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定
更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。
3.watcher订阅者是observer和compile之间通信的桥梁,主要做的事情是:1*.在自身实例化时往属性订阅器里面添加自己
2*.组件自身必须有一个update()方法.3*待属性变动dep.notice()通知时,能调用自身的update()方法,
并触发complie中绑定的回调,则功成身退。
4. MVVM作为数据绑定的入口,整合observer、compile和watcher三者,通过observer来监听自己的model数据变化,
通过compile来解析编译模板指令,最终利用watcher搭起来Observer和Compile之间的通信桥梁,达到数据变化,
视图更新,视图交互话变化,数据model变更的双向绑定效果。
为什么vue2和vue3语法不可以混用?
优先级:
出现重名自变量,会根据书写顺序进行页面的展示。
vue2中的data和vue3中的setup
vue3中setup函数如何进行组件通讯?
- setup语法糖方式通信:
父传子——defineProps
1.父组件使用子组件,在子组件标签里面,通过标签属性的方式进行数据传递
<template>
<children :list="list"></children>
</template>
2.在子组件引入import { defineProps } from 'vue'
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
</script>
defineProps方法定义变量名进行接收,template模板中进行使用。
子传父——defineEmits
父组件在子组件标签上通过v-on绑定自定义事件,子组件通过 const emits = defineEmits([‘事件名’])进行接收。
在子组件B中通过defineEmits注册一个事件名,然后在子组件B的方法中通过emit传递给父组件A。在组件A中,就可以为一些元素添加该事件名绑定事件方法。然后组件A在script setup中写这个事件方法,传递的参数就是子组件B在emit传递过来的值。这个值我们赋值给const的ref定义的数据,从而动态修改数据。
<template>
<div>
<input v-model="value" type="text" placeholder="请输入" />
<button @click="handleAdd"> 添加 </button>
</div>
</template>
<script setup>
import { ref, defineEmits } from 'vue'
const value = ref('')
const emits = defineEmits(['add'])
const handleAdd = () => {
emits('触发的方法', 传递的参数)
}
</script>
-
setup函数嵌套方式通信
父传子props父组件中使用子组件的标签 在 子组件 setup 方法内使用props 来接收父组件传过来的数据。 <template> <div> <Article :msg="name"></Article> </div> </template> <script> import Article from '@/components/Article.vue' export default { components: { Article }, setup() { return { name: '渐行渐远渐无书,水阔鱼沉何处问' } } }
子传父 content
<template>
<div>
{{msg}}
<button @click="sendToParent">子组件向父组件传递数据</button>
</div>
</template>
<script>
export default {
props:['msg'],
setup(props, content) {
console.log(props.msg)
function sendToParent() {
content.emit('change')
}
return {
sendToParent
}
}
}
</script>