vue 生命周期 详解 - happy0 - 博客园 vue 生命周期 详解
vue.js面试题整理 - 竹木狼马 - 博客园 vue 面试题
https://www.jb51.net/article/129733.htm vue实现消息的无缝滚动效果的示例代码
https://blog.csdn.net/qq_43196107/article/details/89555436 vue动态修改页面的title
vue中动态加载图片路径的方法_Femi的博客欢迎大家-CSDN博客_elimage动态获取图片路径 vue中动态加载图片路径的方法(轮播图)
Vuejs快速获取input的值_lyyo_cd的博客-CSDN博客_vue 怎么获取input的值 Vuejs快速获取input的值
VUE的开发规范_HeMister的博客-CSDN博客_vue规范 VUE的开发规范
js按长度截取字符串,返回按长度分割成的字符串数组_lixiaoyan93的博客-CSDN博客_js按长度分割字符串 js按长度截取字符串,返回按长度分割成的字符串数组
vue中html、css、js 分离 vue将js和css单独拆分出来 - 简书
11-Vue自定义指令、Vue.directive注册全局指令、Vue自定义全局指令_解启超-CSDN博客_vue注册全局指令 Vue自定义指令、Vue.directive注册全局指令、Vue自定义全局指令
事件的写法 执行与不执行
//表示 需要手动触发
<el-dialog :before-close="handleClose">
</el-dialog>
//表示 弹窗加载自动触发
<el-dialog :before-close="handleClose()">
</el-dialog>
根据项目情况具体情况具体选择,需要传参一定加 (), 其他只要触发 可以@click="fn1"
Vue命名规则
1.views 下面的 vue文件夹用小写命名 -login
vue-单页面命名:views 下面的 vue 文件代表着页面的名字 推荐用小写 例如:index、details.vue 或者 model-publish.vue
其他非组件或类的,统一使用小写字母开头的(kebab-case)命名规范
2.vue-单文件(文件夹)组件命名: 推荐 单词首字母都大写(大驼峰) 例如:BaseTable.vue
components下的子文件夹名称统一大写开头(PascalCase)命名规范
vue开发使用的基本模板结构顺序
<template>
<div class="class-1">
<h2>{{msg}}</h2>
这是一个fry VueComponentTest
</div>
</template>
<script>
import xx from 'xx/xx/xx/xx';
export default {
name: "xxx-xxx",
components: {},
data() {
return {};
},
props: {
menuCode: {
type: String,
default: "",
},
},
created () {},
mounted () {},
activated() {},
updated() {},
destroyed () {}
computed: {},
watch: {},
methods: {},
};
</script>
<style lang="scss" scoped>
.class-1{
color: red;
}
</style>
可以在data定义变量的时候给变量初始赋值
data(){
return{
option: {
resNum: Vue.prototype.$config.VUE_APP_RESNUM, //应用资源编号 可以写死
accountId: localStorage.getItem('loginName'), //用户id
reportId: '', //暂时无用可为空
operationCode: '1645', //敏感操作代码
date: new Date().getFullYear()
},
}
}
以后调用接口 先判断接口是否成功 -- 成功的字段看具体项目 下面为code:200 表示接口调用,再写其他赋值代码逻辑操作
API.AddtoProject(params).then(response => {
if (response.code === 200) {
this.getList();
} else {
this.msgError(response.msg);
}
})
0 == "" 或者 0 == '' 两个都为true 以后写判断是否为空时用 === 全等!!!
code === 0 、 0 === ""
JS中返回为false的六个值
false、null、undefined、0、-0、NAN、""
console.log(new Boolean(false)) // 布尔值
console.log(new Boolean(null)) // null
console.log(new Boolean(undefined)) // undefined
console.log(new Boolean(0)) // 数字0
console.log(new Boolean(-0)) // 数字-0
console.log(new Boolean(NaN)) // 非数字
console.log(new Boolean('')) // 空字符串,中间有空格时、'-0'都返回true
打印结果↓
例子:组件传值
let refname = this.refname;
const chart = this.$refs[refname];
//本来是 this.$refs.this.refname 没有这种写法
this.$refs[this.refname],
components: {
kpiHeader: () => import("./components/header"),
}
vue模板里面直接调用methods里面的方法方式
<div id="app">
<p>{{ historyindexMethod(index) }}</p>
<span>{{ reverseMessage(message) }}</span>
</div>
methods: {
//表格序号
historyindexMethod(index) {
let curpage = this.historycurrPage; //单前页码,具体看组件取值
let limitpage = this.historypageSize; //每页条数,具体是组件取值
return index + 1 + (curpage - 1) * limitpage;
},
getpamentType(val) {
let pamentTypeName = ''
this.paymentType.filter(item => {
if (val.paymentType === item.dictValue) {
pamentTypeName = val.pamentTypeName
}
})
return pamentTypeName
}
}
Vue文件分离html js css
推荐:js、css直接复制过去就行(不需要<script>和<style>标签包裹了) 文件分离
<template>
<div>html</div>
</template>
<script src="./component.js"></script>
<style src="./component.css"></style>
第二种:
<template>
<div>html</div>
</template>
<script>
import login from "./login.js";
export default login;
</script>
<style lang="css" scoped>
@import './login.css'
</style>
局部引入公共css 或者main.js 引入 import './assets/styles/reset.css'
<style lang="css" scoped>
@import'../../assets/styles/commonstyles.css';
</style>
|| 运算符的高效用法
var t = (true || false) ? '1':'2';//先判断完括号的 推荐
var a = 1 || ''; //获取token的时候用法居多
console.log(a) // 1
var b = b || {};
console.log(b); //{} object
var c = null || []
console.log(c) // []
var x = '' || null;
console.log(x) //null
var y = y || null;
console.log(y) // null
var z = undefined || null;
console.log(z) //null
var o = [] || null
console.log(o) //[]
/*
(A||B)系统先判断A表达式的布尔值,是真是假。如果为真,直接返回A。如果为假,直接返回B(不会判断B是什么类型)。'' null undefined 假
判断一些变量,属性或者是传参是否存在,如果存在就直接用,不存在,就赋予一个空变量。
*/
filter map等配合return改变原数组
cancelcollectLike() {
let data = this.data.map((item, i) => {
if (item.selected) {
item.liked = false;
}
return item;//!!! 最重要return记得
});
this.data = data //更新数据
}
同时传入事件对象和自定义参数
<div id="app">
<button @click="tm($event,123)">ddddd</button>
</div>
JS代码
methods:{
tm:function(e,value){
console.log(e);
console.log(value);
}
vue动态修改页面的title
main.js 或者 router/index.js
router.beforeEach((to,from,next)=>{
if(to.meta.title){
document.title = to.meta.title
}
next()
})
假如异步了(例如Vuex 需要更新后的Vuex state),需要等到某个函数加载完成后(赋值后得到新的state),在进行赋值或者其他操作,我们就可以加个定时器 setTimeout(()=>{},1000) 间隔1秒就可以了。
页面直接调用 methods里面的方法形式:<p>{{fn1()}}</p>
解决:<td>{{(item.createTime || '').slice(0,10)}}</td> 因为加载顺序(生命周期)的问题导致先执行的时候为空,做个空数据就好了 (item.createTime || '')
vue开发----关于字符串去除空格的方法
str = str.replace(/\s*/g,''); // 去除字符串内所有的空格
str = str.replace(/^\s*|\s*$/g,''); // 去除字符串内两头的空格
str = str.replace(/^\s*/,''); // 去除字符串内左侧的空格
str = str.replace(/(\s*$)/g,''); // 去除字符串内右侧的空格
饿了么组件属性选择写法:
Attributes 属性 用: 冒号绑定 :clearable="false",也可以直接写clearable (有默认值的且为true) Options 选择 直接写 v-loading="loading" 不需要冒号绑定
let a = 1,
b = 2;
const a = 1,
b = 2;
阻止vue移动端滑动事件穿透:如果遮罩层也不需要响应滑动。直接在遮罩层上面使用vue的“阻止默认事件”:@touchmove.prevent
mode:'hash',//默认模式 地址栏后面加 #/
routes: []
mode:'history', //地址栏后没有 #/
routes: []
linkActiveClass:'menuactive',//选中导航加样式
routes: []
vue 方法放置顺序
components:{} 模板
props:[''], 父子组件传递信息
data(){ rerurn {} },
created(){},
mounted(){},
activited(){},
update(){},
beforeRouteUpdate (to, from, next) {
console.log(to.path);
console.log(to.query);
console.log("update");
next();
},
metods:{},
filter:{},
computed:{}
watch:{ "$route"(){}, shuju(){},}
@input事件:input事件在输入框输入的时候回实时响应并触发
// 有二级路由的话最开始的一个有(children)的二级路由不需要name
@change事件:change事件在input失去焦点才会考虑触发,它的缺点是无法实时响应。与blur事件有着相似的功能,但与blur事件不同的是,change事件在输入框的值未改变时并不会触发,当输入框的值和上一次的值不同,并且输入框失去焦点,就会触发change事件。
Vue enter 回车事件
created() {
this.keyupSubmit();
},
//回车搜索
methods: {
keyupSubmit() {
document.onkeydown = e => {
let _key = window.event.keyCode;
if (_key === 13) {
this.searchValue();
}
};
},
}
this.loadnum ++ 一直点一直加
<router-link tag="li" :to="'/detail/'+'item.id'"></router-link> 加上tag就把标签渲染成了 li标签 绑定to加跳转
var id = e.target.dataset.id 获取自定义属性值
如果获取到的值(如缓存、图片上传后端返回或其他后端数据)是这种,或者数据颜色为黑色,数据不能点击打开查看!!!,对象里面全是 "" 就要用JSON.parse 解析
{"ID":1,"UserName":"dj","Password":"123456","CreateTime":"2020-04-30T16:14:57.747"}
//JSON.stringify(obj);将JS对象转为JSON字符串。对象转JSON、数组转JSON、对象数组转JSON 一般发给后端
//JSON.parse(string);将字符串转为JSON对象格式。 json转js对象 一般解析获取后端数据
//当前是否存在index
if(this.n.includes(index))
要判断数组是否为空 应该用 array.length
数据处理
js中往数组中插入对象
var datas = [
{ "id":1 , "name":"Gates","age":34 },
{ "id":2 , "name":"Bush","age":22 },
];
var newArr = [];
function addArr() {
for (var i = 0; i <datas.length; i++) {
var obj = {};
obj.id = datas[i].id;
obj.name = datas[i].name;
//或者
var obj = {id:datas[i].id,name:datas[i].name}
newArr.push(obj);
}
console.log(newArr);
}
微信小程序数组[{},{}]对象转数组.forEach不可以操作对象
let arr = [{a:1},{a:2},{a:3}]
let newarr = []
arr.forEach((item,index)=>{
newarr.push(item.a)
})
console.log(newarr)//[1,2,3]
this.setData({
noticearr: newarr
})
对象转化为数组(forEach不可以操作对象)
let obj={
a:4,
b:5,
c:6
}
let newarr = []
for(let i in obj){
newarr.push(obj[i])
}
console.log(newarr)//[4,5,6]
let obj={
a:4,
b:5,
c:6,
d:{
a:4,
b:5,
c:6,
}
}
let newarr = []
for(let i in obj.d){
newarr.push(obj[i])
}
console.log(newarr)//4,5,6
免费的测试接口
http://www.tuling123.com/openapi/api
key: "c75ba576f50ddaa5fd2a87615d144ecf",
info: "先有鸡还是先有蛋"
<img src="@/assets/logo.png" alt="">
background: url('~@/assets/images/quanbg.png') no-repeat center;
<li v-for ="item in images" :key="i">
<img :src="item" alt="">
</li>
images: [
require('@/assets/images/icon_banner.png'),
require('@/assets/images/icon_banner.png'),
],
路径拼接::src=" baseUrl+imgurl "
created(){this.baseStatic = BaseApi.baseStatic;}
// 生命周期函数就是Vue实例在某一个时间点自动执行的函数
如果当前页面的css与前面页面的css命名冲突,就在当前页面style上加scoped <style scoped></style>
组件传值:组件上面采用烤串命名法
<blogPost :post-title="hello!"></blogPost>
组件中:props: ['postTitle'] 驼峰命名法
vue中import与@import的区别
script中的import是js的语法, 是在js中去引用css文件。
style中的@import是stylus的语法,是在css中引用css文件。@import url('./css/tyle.css')
1)assets:资源目录,放置一些图片或者公共js、公共css。这里的资源会被webpack构建;
2)components:组件目录,我们写的组件就放在这个目录里面;
3)router:前端路由,我们需要配置的路由路径写在index.js里面;
4)App.vue:根组件;
5)main.js:入口js文件;
6)新建pages 放页面 :页面命名 首字母大写 (页面引用注册 router index.js)
import Index from '@/pages/Index/Index'
{//首页
path: '/Index',
name: 'Index',
component: Index
},
5、static:静态资源目录,如图片、字体等。不会被webpack构建
6、index.html:首页入口文件,可以添加一些 meta 信息等
7、package.json:npm包配置文件,定义了项目的npm脚本,依赖包等信息
8、README.md:项目的说明文档,markdown 格式
9、.xxxx文件:这些是一些配置文件,包括语法配置,git配置等
Vue项目引用文件,省略后缀名原因如下
webpack配置文件中相关配置如下:
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
(引入css文件需要加.css后缀名)
例如: import './assets/css/reset.css'; //公用css
Vue3页面组成代码
<template>
<div class="order-box">
<nav-bar class="nav-bar">
<template v-slot:default>
定单列表
</template>
</nav-bar>
<van-tabs ref="tabs" @click="onChangeTab" class="order-tab">
<van-tab title="全部"></van-tab>
<van-tab title="待付款"></van-tab>
<van-tab title="已支付"></van-tab>
<van-tab title="发货"></van-tab>
<van-tab title="交易完成"></van-tab>
<van-tab title="过期"></van-tab>
</van-tabs>
<div class="content">
</div>
</van-list>
</van-pull-refresh>
</div>
</div>
</template>
<script>
import { reactive,ref, toRefs,onMounted } from 'vue';
import NavBar from "components/common/navbar/NavBar";
import { getOrderList } from 'network/order'
import { useRouter,useRoute } from 'vue-router';
export default {
name: 'Order',
components: {
NavBar
},
setup() {
/*
List 组件通过 loading 和 finished 两个变量控制加载状态,
当组件滚动到底部时,会触发 load 事件并将 loading 设置成 true。
此时可以发起异步操作并更新数据,数据更新完毕后,将 loading 设置成 false 即可。
若数据已全部加载完毕,则直接将 finished 设置成 true 即可。
*/
const router = useRouter()
const route = useRoute()
let tabs = ref(null);
const state = reactive({
loading: false,
finished: false,
refreshing: false,
list:[],
page:1,
totalPage:0,
status:0,
})
onMounted(()=>{
onRefresh(); // 初使化
})
const onLoad = () => {
if(!state.refreshing && state.page < state.totalPage) {
state.page = state.page + 1;
}
if(state.refreshing) {
state.list = [];
state.refreshing = false;
}
loadData();
}
const onRefresh = () => {
// 是否处于加载状态,加载过程中不触发load事件
state.refreshing = true
// 清空列表数据
state.finished = false
// 重新加载数据
// 将 loading 设置为 true,表示处于加载状态
state.loading = true
state.page = 1;
onLoad()
}
// tab 切换
const onChangeTab = (name) => {
state.status = name;
onRefresh();
}
// 到订单详情页
const goTo = (id)=>{
router.push({path:'/orderdetail', query:{id}});
}
return {
...toRefs(state),
onLoad,
onRefresh,
tabs,
onChangeTab,
goTo
}
}
}
</script>
<style lang="scss" scoped>
.order-tab {
margin-top: 44px;
position: fixed;
left: 0;
z-index: 1000;
width: 100%;
border-bottom: 1px solid #e9e9e9;
}
</style>
Vue2页面组成代码
<template>
<div class="class-1">
<h2>{{msg}}</h2>
这是一个fry VueComponentTest
</div>
</template>
<script>
import xx from 'xx/xx/xx/xx';
export default {
name: "xxx-xxx",
components: {},
data() {
return {};
},
created () {},
mounted () {},
activated() {},
updated() {},
destroyed () {}
computed: {},
watch: {},
methods: {},
};
</script>
<style lang="scss" scoped>
.class-1{
color: red;
}
</style>
static 放一些类库文件,而 assets 放置属于该项目的资源文件。
放在assets/css/reset.css 或者新建styles
在main.js中加入
import "./assets/css/reset.css"
import "./assets/css/border.css"
或者在:index.html 中直接加入
<meta name="viewport" content="width=device-width,initial-scale=1.0">
移动端适配直接写页面上
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script>
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
docEl.style.fontSize = 50 * (clientWidth / 375) + 'px';
console.log(docEl.style.fontSize)
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
</body>
(建议js在页面引入、css在main.js引入,图片资源在assets里面新建images文件夹存放)
而直接在组件中引入却可以,组件中引入也比较简单: @import "./assets/css/style.css";