vue实战项目:项目技巧总结(二)
2020/5/3 11:25:31
本文主要是介绍vue实战项目:项目技巧总结(二),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
十三、vue动态绑定 class
13.1 对象方法
:class="{ 'active': isActive }" 复制代码
13.2 判断是否绑定一个active
:class="{'active':isActive==-1}" 或者 :class="{'active':isActive==index}" 复制代码
13.3绑定并判断多个
第一种(用逗号隔开)
:class="{ 'active': isActive, 'sort': isSort }" 复制代码
第二种(放在 data 里面)
:class="classObject" data() { return { classObject: { active: true, sort: false } } } 复制代码
第三种(使用 computed 属性)
:class="classObject" data() { return { isActive: true, isSort: false } }, computed: { classObject: function() { return { active: this.isActive, sort: this.isSort } } } 复制代码
13.4数组方法
1.单纯数组
:class="[isActive,isSort]" 复制代码
data() { return { isActive: 'active', isSort: 'sort' } } 复制代码
数组与三元运算符结合判断选择需要的class 三元运算符后面的“:”两边的class需要加上单引号
:class="[isActive?'active':'']" 复制代码
或者
:class="[isActive==1?'active':'']" 复制代码
或者
:class="[isActive==index?'active':'']" 复制代码
或者
:class="[isActive==index?'active':'otherActiveClass']" 复制代码
13.5 数组对象结合动态判断
//前面这个 active 在对象里面可以不加单引号,后面这个 sort 要加单引号
:class="[{ active: isActive }, 'sort']" 复制代码
或者
:class="[{ active: isActive==1 }, 'sort']" 复制代码
或者
:class="[{ active: isActive==index }, 'sort']" 复制代码
应用于组件 如果直接在自定义组件中使用 class 或 :class,那么样式规则就会直接应在这个组件的根元素上。
<div id="app"> <text-component :class="{'isStrong':isStrong}"></text-component> </div> 复制代码
<script> Vue.component('text-component', { template: '<p class="content">不懂基因测序的学霸不是好的人工智能公司 CEO</p>' }); var app = new Vue({ el: '#app', data: { isStrong: true } }); </script> 复制代码
参考文档01 参考文档02
style三元表达式
<span v-bind:style="{'display':config.isHaveSearch ? 'block':'none'}" >动态绑定样式</span> 复制代码
参考文档
也可以使用 v-bind:style 或 :style 直接给 HTML 元素绑定样式,它也有对应的对象语法与数组语法。
<div id="app"> <div :style="border"></div> </div> 复制代码
<script> var app = new Vue({ el: '#app', data: { border:{ border:'1px solid #00F', textShadow:'0 0 .3em gray' } } }); </script> 复制代码
因为 JS 属性不支持短横分隔命名,所以我们这里使用 CSS 也支持的驼峰命名法。
参考文档
计算属性computed
例:反转字符串:
<div id="app"> <p>原始字符串: {{ message }}</p> <p>计算后反转字符串: {{ reversedMessage }}</p> </div> 复制代码
<script> var vm = new Vue({ el: '#app', data: { message: 'Runoob!' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } }) </script> 复制代码
我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。。换句话说,computed 是局部渲染,而 methods 是全部渲染 区别:
1.methods是个方法,比如你点击事件要执行一个方法,这时候就用methods, 2.computed是计算属性,实时响应的,比如你要根据data里一个值随时变化做出一些处理,就用computed。 3.我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。 4.methods必须需要一定的条件去触发,而computed则不需要. 5.computed依赖缓存,如果不需要经常变动的用computed,需要经常变动的用methods。如果你需要传参数,就用methods。
computed
computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
var vm = new Vue({ el: '#app', data: { name: 'Google', url: 'http://www.google.com' }, computed: { site: { // getter get: function() { return this.name + ' ' + this.url }, // setter set: function(newValue) { var names = newValue.split(' ') this.name = names[0] this.url = names[names.length - 1] } } } }) 复制代码
// 调用 setter, vm.name 和 vm.url 也会被对应更新 vm.site = 'http://www.runoob.com'; document.write('name: ' + vm.name); document.write('<br>'); document.write('url: ' + vm.url); 复制代码
从实例运行结果看在运行 vm.site = 'http://www.runoob.com'; 时,setter 会被调用, vm.name 和 vm.url 也会被对应更新。
十四、style样式绑定
class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。 Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。
14.1 class 属性绑定
我们可以为 v-bind:class 设置一个对象,从而动态的切换 class:
<style> .active { width: 100px; height: 100px; background: green; } </style> 复制代码
<div id="app"> <div v-bind:class="{ active: isActive }"></div> </div> 复制代码
<script> new Vue({ el: '#app', data: { isActive: true } }) </script> 复制代码
例:text-danger 类背景颜色覆盖了 active 类的背景色:
方法一:在对象中传入更多属性用来动态切换多个 class 。
<style> .active { width: 100px; height: 100px; background: green; } .text-danger { background: red; } </style> 复制代码
<div id="app"> <div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"> </div> </div> 复制代码
<script> new Vue({ el: '#app', data: { isActive: true, hasError: true } }) </script> 复制代码
方法二:直接绑定数据里的一个对象:
<style> .active { width: 100px; height: 100px; background: green; } .text-danger { background: red; } </style> 复制代码
<div id="app"> <div v-bind:class="classObject"></div> </div> 复制代码
<script> new Vue({ el: '#app', data: { classObject: { active: true, 'text-danger': true } } }) </script> 复制代码
方法三:绑定返回对象的计算属性:
<style> .active { width: 100px; height: 100px; background: green; } .text-danger { background: red; } </style> 复制代码
<div id="app"> <div v-bind:class="classObject"></div> </div> 复制代码
<script> new Vue({ el: '#app', data: { isActive: true, error: null }, computed: { classObject: function () { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal', } } } }) </script> 复制代码
方法四:数组语法
<style> .active { width: 100px; height: 100px; background: green; } .text-danger { background: red; } </style> 复制代码
<div id="app"> <div v-bind:class="[activeClass, errorClass]"></div> </div> 复制代码
<script> new Vue({ el: '#app', data: { activeClass: 'active', errorClass: 'text-danger' } }) </script> 复制代码
还可以使用三元表达式来切换列表中的 class : errorClass 是始终存在的,isActive 为 true 时添加 activeClass 类:
<style> .text-danger { width: 100px; height: 100px; background: red; } .active { width: 100px; height: 100px; background: green; } </style> 复制代码
<div id="app"> <div v-bind:class="[errorClass ,isActive ? activeClass : '']"></div> </div> 复制代码
<script> new Vue({ el: '#app', data: { isActive: true, activeClass: 'active', errorClass: 'text-danger' } }) </script> 复制代码
style样式邦定
v-bind:style直接设置样式:
<div id="app"> <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程</div> </div> 复制代码
<script> new Vue({ el: '#app', data: { activeColor: 'green', fontSize: 30 } }) </script> 复制代码
也可以直接绑定到一个样式对象:
<div id="app"> <div v-bind:style="styleObject">菜鸟教程</div> </div> 复制代码
<script> new Vue({ el: '#app', data: { styleObject: { color: 'green', fontSize: '30px' } } }) </script> 复制代码
v-bind:style 可以使用数组将多个样式对象应用到一个元素上:
<div id="app"> <div v-bind:style="[baseStyles, overridingStyles]">菜鸟教程</div> </div> 复制代码
<script> new Vue({ el: '#app', data: { baseStyles: { color: 'green', fontSize: '30px' }, overridingStyles: { 'font-weight': 'bold' } } }) </script> 复制代码
参考文档
十五、vue组件参数传递:
Vue 组件间通信包括:父子组件间通信,兄弟组件间通信以及模块之间通信等。Vue 是数据驱动视图更新的框架, 所以对于 Vue 来说组件间的数据通信非常重要。Vue 实现组件间通信有很多方式,今天我来给大家讲解一下父子组件间通信:props 和$emit。
15.1.子组件向父组件传递参数;
子组件 A:
<template> <div class="childA-wrapper"> 子组件A </div> </template> <script> export default { data() { return { childA: '我是组件A传过来的值' } }, created: function() {}, mounted() { this.sendDataParent() }, methods: { sendDataParent() { // getChildDataA是在父组件on监听的方法 // 第二个参数this.childA是需要传的值 this.$emit('getChildDataA', this.childA) } } } </script> 复制代码
子组件 B:
<template> <div class="childB-wrapper"> 子组件B </div> </template> <script> export default { data() { return { childB:'我是组件B传过来的值' } }, created:function() { }, mounted(){ this.sendDataParent() }, methods: { sendDataParent() { // getChildDataB是在父组件on监听的方法 // 第二个参数this.childB是需要传的值 this.$emit('getChildDataB', this.childB) } } } </script> 复制代码
父组件:
<template> <div> <v-childA v-on:getChildDataA="getChildDataA"></v-childA> <v-childB v-on:getChildDataB="getChildDataB"></v-childB> <div>获取组件A传过来的值:{{childAValue}}</div> <div>获取组件B传过来的值:{{childBValue}}</div> </div> </template> <script> import childA from '@/components/childA.vue' import childB from '@/components/childB.vue' export default { data() { return { childAValue:'', childBValue:'', } }, methods: { getChildDataA(childA){ console.log(childA) this.childAValue=childA }, getChildDataB(childB){ console.log(childB) this.childBValue=childB } }, components: { 'v-childA': childA, 'v-childB': childB} } </script> 复制代码
15.2、父组件向子组件传递参数
父组件:
<template> <div> <v-childA></v-childA> <v-childB :sendBData="sendB"></v-childB> </div> </template> <script> import childA from '@/components/childA.vue' import childB from '@/components/childB.vue' export default { data() { return { sendB:'父组件向B组件传递的参数' } }, methods: { }, components: { 'v-childA': childA, 'v-childB': childB} } </script> 复制代码
子组件 B:
<template> <div class="childB-wrapper"> 子组件B:{{sendBData}} </div> </template> <script> export default { data() { return {} }, created: function() {}, mounted() {}, methods: {}, props: { sendBData: String, required: true } } </script> 复制代码
15.3、非父子组件进行传值;
bus.js
import Vue from 'vue' export default new Vue() 复制代码
组件 childB:
<template> <div class="childB-wrapper"> </div> </template> <script> import Bus from '@/common/bus.js' export default { data() { return { childB: '我是组件B的内容' } }, created: function() {}, mounted() { this.elementByValue() }, methods: { elementByValue: function () { Bus.$emit('val', this.childB) } } } </script> 复制代码
##### 组件 childA: <template> <div class="childA-wrapper"> A组件:<span>{{childB}}</span> </div> </template> <script> import Bus from '@/common/bus.js' export default { data() { return { childB: '' } }, created: function() {}, mounted() { var that = this // 用 $on事件来接收参数 Bus.$on('val', (data) => { console.log(data) that.childB = data }) } } </script> 复制代码
更多请查看:你不知道的vue组件传值方式
16.vue脚手架配置预渲染,prerender-spa-plugin 配置
用到插件:cnpm install prerender-spa-plugin --save 脚手架 2.0:(自己的是 2.0)
16.1 build/webpack.prod.conf.js 配置
const PrerenderSPAPlugin = require('prerender-spa-plugin') const Renderer = PrerenderSPAPlugin.PuppeteerRenderer const webpackConfig = merge(baseWebpackConfig, { plugins: [ // vue-cli 生成的配置就有了 new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true }, chunksSortMode: 'dependency' }), // 配置 PrerenderSPAPlugin new PrerenderSPAPlugin({ // 生成文件的路径,也可以与 webpakc 打包的一致。 staticDir: path.join(\_\ _dirname, '../dist'), // 对应自己的所有路由文件,比如 index 有参数,就需要写成 /index/param1。这个其实不需要;千万不要加'/'这个 嵌套路由得 commonquestion 直接写即可 routes: ['index', '...', '/commonQuestion', '/commonQuestion/questionList', '/commonQuestion/questionDetailInfo'], // ; renderer: new Renderer({ inject: { // 可选;最好还是用 foo: 'bar' }, headless: false, // 可选;最好用 renderAfterTime: 5000, // 通过实践是必选 官网说可选有误 一定要必选 renderAfterDocumentEvent: 'render-event' // 可选;最好用 }) }), ] }) 复制代码
16.2.路由得 index.js 添加属性:
mode:‘history’, 复制代码
修改config/index.js 中的build的 assetsPublicPath: ‘/’ ;不然会导致刷新页面路径错乱导致样式或者js丢失; 修改main.js new Vue({ el: '#app', router, store, // 如果需要了切记引入啊 切记需要挂载的全部挂载上去 render: h => h(App), mounted () { document.dispatchEvent(new Event('render-event')) } }) 复制代码
16.3.build/webpack.prod.conf.js 配置
const PrerenderSPAPlugin = require('prerender-spa-plugin'); const Renderer = PrerenderSPAPlugin.PuppeteerRenderer; const path = require('path'); module.exports = { configureWebpack: config => { if (process.env.NODE_ENV !== 'production') return; return { plugins: [ new PrerenderSPAPlugin({ // 生成文件的路径,也可以与 webpakc 打包的一致。 // 下面这句话非常重要!!! // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。 staticDir: path.join(\_\ _dirname, 'dist'), // 对应自己的路由文件,比如 a 有参数,就需要写成 /a/param1。 routes: ['/', '/product', '/about'], // 这个很重要,如果没有配置这段,也不会进行预编译 renderer: new Renderer({ inject: { foo: 'bar' }, headless: false, renderAfterTime: 5000, // 必选哈 // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。 renderAfterDocumentEvent: 'render-event' }) }), ], }; } } 复制代码
16.4 main.js 配置
new Vue({ router, store, render: h => h(App), mounted() { document.dispatchEvent(new Event('render-event')) } }).\$mount('#app') 复制代码
其他修改同 2.0;
参考文档
十六、vue SPA单页面的 SEO 优化
vue-meta-info 复制代码
官方地址: monkeyWangs/vue-meta-info
1.安装
npm install vue-meta-info --save 复制代码
2.全局引入 vue-meta-info
import Vue from 'vue' import MetaInfo from 'vue-meta-info' Vue.use(MetaInfo) 复制代码
3.组件内静态使用 metaInfo
<template> ... </template> 复制代码
<script> export default { metaInfo: { title: 'My Example App', // set a title meta: [{ // set meta name: 'keyWords', content: 'My Example App' }] link: [{ // set link rel: 'asstes', href: 'https://assets-cdn.github.com/' }] } } </script> 复制代码
4.如果你的 title 或者 meta 是异步加载的,那么你可能需要这样使用
<template> ... </template> 复制代码
<script> export default { name: 'async', metaInfo () { return { title: this.pageName } }, data () { return { pageName: 'loading' } }, mounted () { setTimeout(() => { this.pageName = 'async' }, 2000) } } </script> 复制代码
<meta name="参数" content="具体的描述"> 复制代码
5.meta标签共有两个属性,分别是http-equiv属性和name属性
name 属性 name 属性主要用于描述网页,比如网页的关键词,叙述等。与之对应的属性值为 content,content 中的内容是对 name 填入类型的具体描述,便于搜索引擎抓取。 meta 标签中 name 属性语法格式是:
<meta name="参数" content="具体的描述"> 复制代码
其中 name 属性共有以下几种参数。(A-C 为常用属性)
A. keywords(关键字)
说明:用于告诉搜索引擎,你网页的关键字。
<meta name="keywords" content="XX网,汽车,车主,评选"> 复制代码
B. description(网站内容的描述)
说明:用于告诉搜索引擎,你网站的主要内容。 复制代码
<meta name="description" content="汽车评选,XX网,评选,汽车"> 复制代码
C.viewport(移动端的视口)
说明:这个属性常用于设计移动端网页。
举例
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/> 复制代码
D. robots(定义搜索引擎爬虫的索引方式)
说明:robots 用来告诉爬虫哪些页面需要索引,哪些页面不需要索引。 content 的参数有 all,none,index,noindex,follow,nofollow。默认是 all。 复制代码
举例:
<meta name="robots" content="none"> 复制代码
具体参数如下:
1.none : 搜索引擎将忽略此网页,等价于 noindex,nofollow。 2.noindex : 搜索引擎不索引此网页。 3.nofollow: 搜索引擎不继续通过此网页的链接索引搜索其它的网页。 4.all : 搜索引擎将索引此网页与继续通过此网页的链接索引,等价于 index,follow。 5.index : 搜索引擎索引此网页。 6.follow : 搜索引擎继续通过此网页的链接索引搜索其它的网页。 复制代码
E. author(作者)
说明:用于标注网页作者 举例:
<meta name="author" content="Lxxyx,841380530@qq.com"> 复制代码
F. generator(网页制作软件)
说明:用于标明网页是什么软件做的 举例: (不知道能不能这样写):
<meta name="generator" content="Sublime Text3"> 复制代码
G. copyright(版权)
说明:用于标注版权信息 举例:
<meta name="copyright" content="Lxxyx"> //代表该网站为Lxxyx个人版权所有。 复制代码
H. revisit-after(搜索引擎爬虫重访时间)
说明:如果页面不是经常更新,为了减轻搜索引擎爬虫对服务器带来的压力,可以设置一个爬虫的重访时间。如果重访时间过短,爬虫将按它们定义的默认时间来访问。 举例:
<meta name="revisit-after" content="7 days" > 复制代码
I. renderer(双核浏览器渲染方式)
说明:renderer 是为双核浏览器准备的,用于指定双核浏览器默认以何种方式渲染页面。比如说 360 浏览器。 举例:
<meta name="renderer" content="webkit"> //默认webkit内核 <meta name="renderer" content="ie-comp"> //默认IE兼容模式 <meta name="renderer" content="ie-stand"> //默认IE标准模式 复制代码
6. http-equiv 属性
http-equiv 相当于 HTTP 的作用,比如说定义些 HTTP 参数啥的。 meta 标签中 http-equiv 属性语法格式是:
<meta http-equiv="参数" content="具体的描述"> 复制代码
其中 http-equiv 属性主要有以下几种参数:
A. content-Type(设定网页字符集)(推荐使用 HTML5 的方式)
说明:用于设定网页字符集,便于浏览器解析与渲染页面 举例:
<meta http-equiv="content-Type" content="text/html;charset=utf-8"> //旧的HTML,不推荐 <meta charset="utf-8"> //HTML5设定网页字符集的方式,推荐使用UTF-8 复制代码
B. X-UA-Compatible(浏览器采取何种版本渲染当前页面)
说明:用于告知浏览器以何种版本来渲染页面。(一般都设置为最新模式,在各大框架中这个设置也很常见。) 举例:
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> //指定IE和Chrome使用最新版本渲染当前页面 复制代码
C. cache-control(指定请求和响应遵循的缓存机制)
用法 1.
说明:指导浏览器如何缓存某个响应以及缓存多长时间。这一段内容我在网上找了很久,但都没有找到满意的。 最后终于在 Google Developers 中发现了我想要的答案。
举例:
<meta http-equiv="cache-control" content="no-cache"> 复制代码
共有以下几种用法:
no-cache: 先发送请求,与服务器确认该资源是否被更改,如果未被更改,则使用缓存。 no-store: 不允许缓存,每次都要去服务器上,下载完整的响应。(安全措施) public : 缓存所有响应,但并非必须。因为 max-age 也可以做到相同效果 private : 只为单个用户缓存,因此不允许任何中继进行缓存。(比如说 CDN 就不允许缓存 private 的响应) maxage : 表示当前请求开始,该响应在多久内能被缓存和重用,而不去服务器重新请求。例如:max-age=60 表示响应可以再缓存和重用 60 秒。 参考链接:HTTP 缓存 用法 2.(禁止百度自动转码)
说明:用于禁止当前页面在移动端浏览时,被百度自动转码。虽然百度的本意是好的,但是转码效果很多时候却不尽人意。所以可以在 head 中加入例子中的那句话,就可以避免百度自动转码了。 举例:
<meta http-equiv="Cache-Control" content="no-siteapp" /> 复制代码
D. expires(网页到期时间)
说明:用于设定网页的到期时间,过期后网页必须到服务器上重新传输。 举例:
<meta http-equiv="expires" content="Sunday 26 October 2016 01:00 GMT" /> 复制代码
E. refresh(自动刷新并指向某页面)
说明:网页将在设定的时间内,自动刷新并调向设定的网址。 举例:
<meta http-equiv="refresh" content="2;URL=http://www.lxxyx.win/"> //意思是2秒后跳转向我的博客 复制代码
F. Set-Cookie(cookie 设定)
说明:如果网页过期。那么这个网页存在本地的 cookies 也会被自动删除。
<meta http-equiv="Set-Cookie" content="name, date"> //格式 <meta http-equiv="Set-Cookie" content="User=Lxxyx; path=/; expires=Sunday, 10-Jan-16 10:00:00 GMT"> //具体范例 复制代码
更详细更具体的 vue 学习文档访问 vue学习文档01 vue学习文档02
vue实战项目:项目技巧总结(一)
这篇关于vue实战项目:项目技巧总结(二)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-04package.json 文件位置在哪?-icode9专业技术文章分享
- 2024-10-01Craco.js学习:从入门到实践指南
- 2024-10-01Create-React-App学习:入门与实践指南
- 2024-10-01CSS-in-JS学习:从入门到实践指南
- 2024-09-30JSX语法学习:从入门到初步掌握
- 2024-09-30Mock.js学习:入门教程与实战演练
- 2024-09-30React Hooks学习:从入门到实践
- 2024-09-30受控组件学习:React中的基础入门教程
- 2024-09-29JS定时器教程:初学者必看指南
- 2024-09-29JS对象教程:初学者的全面指南