1、css选择器优先级关系 !important > 内联样式 > ID选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 标签选择器 = 伪元素选择器 > 通配符选择器
!important是顶级选择器,不管写在哪甚至都可以无视JavaScript的样式设置!
2、css浏览器兼容性问题的解决方法
- 浏览器CSS样式初始化(比如:
*{margin: 0;padding: 0;}
)(这里推荐一个第三方库:Normalize.css) - 浏览器私有属性设置 —— 浏览器前缀(比如:-webkit-、-moz-、-ms-、-o)
- CSS hack —— 针对不同格式写不同版本的样式 语法:
<!--[if <keywords>? IE <version>?]>
//这里可写HTML、css、js代码
<![endif]-->
(keywords:gt、fte、lt、lte)(version:6/7/8:IE版本)
- 自动化插件 —— 如第二条每次光补全前缀可能就“一大坨”,用自动化插件可以自动补全兼容性代码,推荐:Autoprefixer
3、HTML5比HTML增加了哪些内容? 。。。
4、vue3比vue2在响应式的实现上有什么区别? vue2采用的是defineProperty去定义get,set;而vue3改用proxy,这也代表了vue放弃了兼容ie
5、像vue-router、vuex都是作为vue插件使用的,请说一下他们是如何在vue中生效的 通过vue插件系统,用vue.mixin混入到全局,在每个组件的生命周期的某个阶段注入组件实例
6、请说一下vue的设计架构 vue2采用的是典型的混入式架构,类似于express和jQuery,各部分分模块开发,再通过一个mixin去混入到最终暴露到全局的类上。
7、vue-cli3.x中,设置Mock(前端模拟数据) 在vue.config.js文件中的module.exports中,有属性(3.x中多半是自行手写):
configureWebpack:{
devServer:{
before(app){
//...语法和node(express)相同
}
}
}
8、vue-cli3.x配置前后端联调 同样在vue.config.js文件中的module.exports中,有属性:
devServer:{
proxy:{
'路由':{
target:'监听端口,如:http://localhost:8081',
ws:true,
changeOrgin:true //开启虚拟服务器
}
}
}
和前面那个问题不同,这里的devServer是独立的一个属性。
9、vue-cli配置目录别名 vue-cli2.x中如何配置目录别名:
//build>webpack.base.conf.js->resolve->alias
//添加如:
'styles':resolve('src/assets/styles')
vue-cli3.x中如何配置目录别名:
//vue.config.js
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir);
}
//module中添加格式
module.exports = {
lintOnSave: true,
chainWebpack: (config) => {
config.resolve.alias
.set('@', resolve('src'))
.set('@assets',resolve('src/assets'))
// 这里只写了两个个,你可以自己再加,按这种格式.set('', resolve(''))
}
};
然后我们就可以去使用,如:
import '~styles/xxx'
10、vue项目升级
vue add vue-next
11、vue3.0问题整理 Composition-API:函数式编程·初窥
在vue3.0的项目中,原先的data、computed...生命周期之流都消失不见,换成了一个函数:setup(){}
里面的函数变量 —— 依赖回调函数工作。
为了复用性更好,vue3.0将比如vuex、computed等做了封装,也就是说:需要先行引入!
从笔者的项目中找出代码片段供大家参考:
import xxx from 'xxx'
import {watch} from 'vue'
import {useStore} from 'vuex'
import {ref, reactive, computed} from 'vue' //vue3.x采用“引入对象”的方式
import {useRoute, useRouter} from 'vue-router'
export default{
name:'xxx',
components:{
xxx
},
setup(){
//data变成了对象变量——且只有引入reactive才能具有“响应式”
const data=reactive({ //1.
xxx:xxx
})
let xxx=ref(xxx) //2.
//使用vuex必须使用封装好的函数
const store=useStore();
//使用computed属性换成了computed函数
const yyy=computed(()=>{ //回调函数返回值直接被接收(不用return)
store.state.zzz;
})
const route=useRoute() //vue3.x获取动态路由传参 .params.id
const router=useRouter() //vue3.x跳转路由 .push('')
//watch第二个参数是回调函数,其接收两个值:原数据和新数据
watch(监听对象,(letter,prevLetter)=>{
})
//2.x里靠this.调用的methods里的函数的书写方式也改变了(原写法:xxx(){})(更像原生了哈哈哈)
function kkk(){ //引用或导出时直接写函数名即可
}
onMounted(()=>{
})
onActivited(()=>{
})
return { data, yyy, kkk } //对象的返回方法 接上面1.
return { xxx } //普通变量的返回方法 接上面2.
}
}
vue3.0在模板里(标签/组件)也做了改动:
- 因为上面“暴露了”data(变量都在data对象内),所以JS中使用变量需要加上“
data.
” {{}}
里不允许使用this.
了,在函数中用data的数据也不用加this了- vue中的生命周期函数都变成了以回调为主体
- reactive最好只作用于对象,当然,vue3.x也可以不用data对象变量 —— 直接const/let数据,然后将其暴露出去。但是这有一个问题:不是响应式,数据被改变后不能更新到模板里。vue3.x给出了一个解决方案:
ref()
,在模板中也就可以直接使用了(不过这样在JS中重新给变量赋值时就要用xxx.value=
了) - 生命周期destroyed因为和mounted作用相对,所以在vue3.x中直接将其改成了
onUnmounted(()=>{})
函数 - 如果要用到props传来的数据,则setup()内可接收一参数:props,并用它代替2.x中的“this.”
- 如果函数在模板里也有使用(比如:@click),则函数名也要“导出”
vue3.x还有一个重大的改变:允许“同一个功能”放在一起,比如:
<script>
export default {
setup(){
const {letter, handleChange}=useLetter();
//...
return {letter, handleChange}
}
}
//封装到一个函数中
function useLetter(){
const letter=ref('') //letter默认是空'',所以ref里是''
function handleChange(selected){
letter.value=selected
}
return {letter, handleChange}
}
</script>
这样后面维护起来或者找错时就非常方便了。
3.0中对于“向外触发事件”怎么办?
//2.x语法:
this.$emit('xxx',xxx);
在3.0的setup函数中,除了上面说的参数props,还可以接收一个参数:“context”,你可以理解为“上下文对象”,其作用相当于this:
//3.x语法
context.emit('xxx',xxx);
3.0中$refs也不能直接用了:你需要在模板ref里写一个箭头函数,用暴露出去的变量接收ref值:
<div :ref="elem => elems[key] = elem"></div>
//elems[]里面包的才是“真正的ref”!
const { ref } from 'vue'
//setup(){}中:
const elems=ref({})
//...
elems.value[xxx]
return { elems }
或者:
<div ref="wrapper"></div>
const wrapper=ref(null)
//直接就可以用wrapper代替2.x中的“this.$refs.wrapper”了
return { wrapper }
还有一点需要注意:watch的第一个参数只能是ref 、reactive或是包含他们的数组,但如果你需要监听某响应式对象里面的一个数据怎么办? vue中可以使用箭头函数生成【返回数据】,因为经过了函数,所以返回的数据也就是“响应式”的了:
const { watch } from 'vue'
//(参数)props是一个响应式对象,但是props.obj不是,我们可以用箭头函数将其作为返回值来构造一个响应式变量
watch(()=>props.obj,(旧值,新值)=>{
})
12、微信小程序中“滚动到可视区域”
与vue:this.$el.querySelector("xxx").scrollIntoView(false)
、
当scrollIntoView参数为bool且为true时,元素的顶部将对齐到可滚动祖先的可见区域的顶部。这也是默认值。 反之,为false时,元素的底部将与可滚动祖先的可见区域的底部对齐。
原生JS:
const sTop=document.documentElement.scrollTop || document.body.scrollTop; //浏览器可滚动高度
const sHeight=document.documentElement.scrollHeight; //文档真实高度
const cHeight=document.documentElement.clientHeight; //窗口可视高度
if(sHeight == sTop + cHeight){
//...
}
或者
var top=obj.getBoundingClientRect().top; //元素顶端到可见区域顶部的距离
var sHeight=document.documentElement.clientHeight;
var eHeight=obj.offsetHeight;
if(top <= sHeight - eHeight){
//...
}
微信小程序中有scroll-view组件,里面监听了scroll-top属性,通常有:
//wxml
<scroll-view scroll-top="{{scrollTop}}"></scroll-view>
//js
rolling_bottom:function(){
var s=0
var list=wx.createSelectorQuery().selectAll('xxx').boundingClientRect(rects=>{
rects.forEach(rect=>{
this.setData({
scrollTop:rect.bottom
})
})
}).exec()
},
在上面代码中,第7行利用小程序提供的查找节点的API,来查找所有符合要求的class/id的节点元素;第8-14行遍历元素,将rect.bottom节点的下边界坐标赋值给scroll-view组件的scrollTop属性
当然,这样的话也可以用scroll-view组件自带的scroll-into-view
属性。
也可以只用原生的view组件:
wx.createSelectorQuery().select('整个页面(最外层view)的class/id名').boundingClientRect(function(rect){
wx.pageScrollTo({ //微信小程序页面滚动API
duration: 300,
scrollTop: rect.height //这里用rect.bottom或者rect.height都行
})
}).exec()
一般用在setData的回调函数中
13、CSS清除浮动的方式
给指定元素加class:.clearfix
.clearfix::after{
content:"";
display:block;
clear:both;
}
14、微信小程序中button默认样式怎么破? 一般来说,对于button样式的去除,可以用:
border: none;
outline: none;
list-style: none;
但是在微信小程序中这样用的效果微乎其微,而且无论如何button的width也去不掉 —— 猜测可能button是小程序原生组件的缘故。 那么,若要在小程序中【真正的】自定义button样式,必须通过在wxml中加style的方式:
style="width: unset"