首页
写过的文章
Search
1
mock的基本用法
718 阅读
2
js的数组常用方法
693 阅读
3
cnpm安装教程
565 阅读
4
能有效解决问题的提问方法2.0
554 阅读
5
Vue、git指令
490 阅读
默认分类
JavaScript
Vue
TypeScript
登录
Search
标签搜索
底部导航
tabbar
底部导航栏
vue3隐藏底部导航栏
vue3隐藏tabbar
网页
黑白
网页黑白
cnpm安装
cnpm
Z的故事
累计撰写
23
篇文章
累计收到
71
条评论
首页
栏目
默认分类
JavaScript
Vue
TypeScript
页面
写过的文章
搜索到
13
篇与
Vue
的结果
2022-09-16
Vue-Vant 移动端如何适配
移动端适配第一步:引入 flexible.js 文件打开终端,输入 npm i lib-flexible 就会生成一个 lib-flexible 文件夹将里面的 flexible.js 复制到项目 src 文件中即可。作用:用于设置 rem 基准值。或者直接复制下面的 flexible.js 文件内容即可(function(win, lib) { var doc = win.document; var docEl = doc.documentElement; var metaEl = doc.querySelector('meta[name="viewport"]'); var flexibleEl = doc.querySelector('meta[name="flexible"]'); var dpr = 0; var scale = 0; var tid; var flexible = lib.flexible || (lib.flexible = {}); if (metaEl) { console.warn('将根据已有的meta标签来设置缩放比例'); var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/); if (match) { scale = parseFloat(match[1]); dpr = parseInt(1 / scale); } } else if (flexibleEl) { var content = flexibleEl.getAttribute('content'); if (content) { var initialDpr = content.match(/initial\-dpr=([\d\.]+)/); var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/); if (initialDpr) { dpr = parseFloat(initialDpr[1]); scale = parseFloat((1 / dpr).toFixed(2)); } if (maximumDpr) { dpr = parseFloat(maximumDpr[1]); scale = parseFloat((1 / dpr).toFixed(2)); } } } if (!dpr && !scale) { var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; if (isIPhone) { // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其他设备下,仍旧使用1倍的方案 dpr = 1; } scale = 1 / dpr; } docEl.setAttribute('data-dpr', dpr); if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); } else { var wrap = doc.createElement('div'); wrap.appendChild(metaEl); doc.write(wrap.innerHTML); } } function refreshRem(){ var width = docEl.getBoundingClientRect().width; if (width / dpr > 540) { width = 540 * dpr; } var rem = width / 10; docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem; } win.addEventListener('resize', function() { clearTimeout(tid); tid = setTimeout(refreshRem, 300); }, false); win.addEventListener('pageshow', function(e) { if (e.persisted) { clearTimeout(tid); tid = setTimeout(refreshRem, 300); } }, false); if (doc.readyState === 'complete') { doc.body.style.fontSize = 12 * dpr + 'px'; } else { doc.addEventListener('DOMContentLoaded', function(e) { doc.body.style.fontSize = 12 * dpr + 'px'; }, false); } refreshRem(); flexible.dpr = win.dpr = dpr; flexible.refreshRem = refreshRem; flexible.rem2px = function(d) { var val = parseFloat(d) * this.rem; if (typeof d === 'string' && d.match(/rem$/)) { val += 'px'; } return val; } flexible.px2rem = function(d) { var val = parseFloat(d) / this.rem; if (typeof d === 'string' && d.match(/px$/)) { val += 'rem'; } return val; } })(window, window['lib'] || (window['lib'] = {})); 第二步:下载 postcss-pxtorem 插件在项目终端或者打开目录所在的cmd,输入插件npm i postcss-pxtorem作用: 是一款 PostCSS 插件,用于将 px 单位转化为 rem 单位.下载完成后,在项目根目录新建一个 postcss.config.js 文件,在文件中复制以下内容即可.// postcss.config.js module.exports = { plugins: { 'postcss-pxtorem': { rootValue: 37.5, propList: ['*'], }, }, }; 第三步:在 main.js 文件内引入 flexible.js 移动端适配文件,即可完成适配import './utils/flexible' // 移动端适配文件
2022年09月16日
363 阅读
0 评论
0 点赞
2022-09-09
vue2 与 vue3的区别(二)
数据双向绑定讲一下什么是数据双向绑定v-model(语法糖) 是Vue框架的一种内置的API指令,本质是一种语法糖写法。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理<input type="text" v-model="msg"/> // 等于下面代码 <input type="text" :value="msg" @input="msg = $event.target.value" />通过上面这两段代码片段可以看出来 v-model="msg" 是 :value="msg" @input="msg = $event.target.value"的缩写解析一下代码$event 当前触发的事件对象。$event.target 当前触发的事件对象的dom$event.target.value 当前dom的value值在@input方法中,value => msg在:value中:msg => value如此,形成了一个闭环,也就是所说的数据的双向绑定。那么就有人提问了, vue中的自定义组件能不能实现双向绑定<my-Input v-model="msg"></my-Input> //我们可以根据规则来拆解 <my-Input :value="msg" @input="msg = $event.target.value"></my-Input>解析还原一下组件封装的过程<template> <div> <input type="text" :value="value" @input="$emit('input', $event.target.value)"></input> </div> </template> <script> export default { props:{ value:String } } </script>看完以后突然恍然大悟, 这是父子组件的来回传值!!那么可以在思考一个问题就是代码里props的value里的值可不可以随便写一个呢? input可不可以随便定义一个事件呢?当我们在自定义组件使用v-model的时候并不能实现双向的数据绑定, 因为自定义的组件没有默认value和input事件,在使用的时候我们就得按照刚刚所写的一样去生命定义这些东西这时候,model的选项就派上用场了,在定义组件的时候,指定prop的值和监听的事件。组件的用法不变,子组件这样写(里面事件就随便填了)<template> <div> <input type="text" :value="xx" @input="$emit('xx', $event.target.value)"></input> </div> </template> <script> export default { model: { value:'xx', event:'xx', // 代表自定义的事件名称 } props: { xx: String //代表自定义的变量名成 } } </script> 上面就是整理的一些vue2的双向绑定以及一些用法vue3双向数据绑定vue3与vue2的双向数据绑定区别并不是很大,他是跟vue2的sync进行了合并,所以在vue3的就移除了sync,不多说,上代码!// 自定义一个Input组件 <template> <div> <input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </div> </template> <script> export default { props: { modelValue: { type: String } } } </script> //在vue3中默认的不在是value 而是modelValue 然后在其他页面使用 <template> <h1>{{ msg }}</h1> <Input v-model="msg"></Input> //等同于下面语法 默认传入一个modelValue然后在子组件接收 <Input :modelValue="msg" @update:modelValue="msg = $event"></Input> </template> <script> import { ref } from "vue"; import Input from "@/components/Input" export default { components:{ Input }, setup(props){ const msg = ref('') return { msg } } } </script>那么这个默认的modelValue就无法改变了吗?当然不是// 父组件 <template> <h1>vue3中使用v-model {{msg}}</h1> <testModel v-model:msg="msg"></testModel> </template> 这时候子组件接收的props就要换成msg了// 子组件 <template> <div> <input type="text" :value="msg" @input="$emit('update:msg', $event.target.value)" /> </div> </template> <script> export default { props: { msg: { type: String } } } </script>当然提到双向绑定,你可能第一时间就会想到表单元素,双向绑定不一定是表单元素,你可以定义各种各样的组件,比如通过click事件改变父组件的值// 父组件 <template> <div>{{count}}</div> <testModel v-model="content" :content="content"></testModel> </template> <script> export default { components: { testModel }, setup(){ const count = ref(0) return { count } } } </script> // 子组件 <template> <!-- 一定是+1 不是+=1 或者++ 否则vue会触发一个不让子组件直接改变props的警告 --> <div @click="$emit('update:count', count + 1)">click me count + 1!</div> </template> <script> export default { props: { count: { type: Number } } } </script>
2022年09月09日
361 阅读
0 评论
0 点赞
2022-09-08
Vue2 与 Vue3区别(一)
vue2 vue3 双向数据的区别一.先来聊聊vue2双向绑定原理:是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图,实现数据和视图同步// 语法: Object.defineProperty(obj, "name", { get:()=> {}, set:()=> {}) 参数一: obj:劫持对象,参数二:"name":劫持对象属性 , 参数三:给属性添加set,get方法二. 再聊一聊vue3双向绑定原理:是通过Object.define.proxy 对对象进行代理,从而实现数据劫持。使用Proxy 的好处是它可以完美的监听到任何方式的数据改变,唯一的缺点是兼容性的问题,因为 Proxy 是 ES6 的语法// 语法: let p =new Proxy(obj,{get:(target,prop,p)=>{},set:(target, prop, vaule, p)=>{}}) 总结:vue2通过Object.defineProperty劫持的是对象中每一个属性vue3通过Proxy劫持的是对象中每一个属性视图更新问题因为 Vue 实例中的数据是响应式的,⽽我们新增的属性并不是响应式的,由于受现在 JavaScript 的限制,Vue ⽆法检测到属性的新增或删除。所以有时⽆法实时的更新到视图上!vue2和vue3的执行机制有所不同,v2是通过object.defindProperty,监听对象新增或修改某一个属性的时候会触发,所以会出现数据更新视图不更新的情况,而v3则是通过es6的proxy监听整个对象的变化,所以不会存在数据变了试图不变的情况遇到这类问题的时候⼀般是通过 this.$set,该⽅法⼀共有三个参数,分别是给谁添加,新增属性,新增的值.下面代码实现:data:{ obj:{ a:1, b:2 } } methods:{ add(){ this.obj.c = 10;// 给obj添加属性及属性值 console.log(this.obj);// 打印下来发现后台有c这条数据, 但是视图却没有更新 this.$set(this.obj,"c",10);//这时候就通过这个方法强制更新 } }
2022年09月08日
433 阅读
3 评论
0 点赞
1
2
3