<div id="app">
<!-- 如果需要往子组件总传递父组件data中的数据 需要加v-bind="数据名称" -->
<hello v-bind:msg="info"></hello>
<!-- 如果传递的是字面量 那么直接写-->
<hello my-msg="abc"></hello>
</div>
<!-- js -->
<script>
new Vue({
el: "#app",
data : {
info : 15
},
components: {
hello: {
// 创建props及其传递过来的属性
props: ['msg', 'myMsg'],
template: '<h1>这是 hello 组件,这是消息:{{msg}} --- {{myMsg}}</h1>'
}
}
})
</script>
方式:父组件给子组件传递一个函数,由子组件调用这个函数
步骤:
<hello @pfn="parentFn"></hello>
<script>
Vue.component('hello', {
template: '<button @click="fn">按钮</button>',
methods: {
// 子组件:通过$emit调用
fn() {
this.$emit('pfn', '这是子组件传递给父组件的数据')
}
}
})
new Vue({
methods: {
// 父组件:提供方法
parentFn(data) {
console.log('父组件:', data)
}
}
})
</script>
在简单的场景下,可以使用一个空的 Vue 实例作为事件总线
var bus = new Vue()
// 在组件 B 绑定自定义事件
bus.$on('id-selected', function (id) {
// ...
})
// 触发组件 A 中的事件
bus.$emit('id-selected', 1)
<!-- 组件A: -->
<com-a></com-a>
<!-- 组件B: -->
<com-b></com-b>
<script>
// 中间组件
var bus = new Vue()
// 通信组件
var vm = new Vue({
el: '#app',
components: {
comB: {
template: '<p>组件A告诉我:{{msg}}</p>',
data() {
return {
msg: ''
}
},
created() {
// 给中间组件绑定自定义事件 注意:如果用到this 需要用箭头函数
bus.$on('tellComB', (msg) => {
this.msg = msg
})
}
},
comA: {
template: '<button @click="emitFn">告诉B</button>',
methods: {
emitFn() {
// 触发中间组件中的自定义事件
bus.$emit('tellComB', '土豆土豆我是南瓜')
}
}
}
}
})
</script>
案例:
<!-- html代码 -->
<div id="app">
<hello>
<!-- 如果只有一个slot插槽 那么不需要指定名称 -->
<p slot="插槽名称">我是额外的内容</p>
</hello>
</div>
// js代码
new vue({
el : "#app",
components : {
hello : {
template : `
<div>
<p>我是子组件中的内容</p>
<slot name="名称"></slot>
</div>
`
}
}
})
<div id="app">
<div ref="dv"></div>
<my res="my"></my>
</div>
<!-- js -->
<script>
new Vue({
el : "#app",
mounted() {
this.$refs.dv //获取到元素
this.$refs.my //获取到组件
},
components : {
my : {
template: `<a>sss</a>`
}
}
})
</script>
单页Web应用(single page application,SPA),就是只有一个Web页面的应用,
是加载单个HTML页面,并在用户与应用程序交互时动态更新该页面的Web应用程序。
单页面应用程序:
传统多页面应用程序:
优势
实现思路和技术点
在 Web app 中,通过一个页面来展示和管理整个应用的功能。
SPA往往是功能复杂的应用,为了有效管理所有视图内容,前端路由 应运而生!
简单来说,路由就是一套映射规则(一对一的对应规则),由开发人员制定规则。
当URL中的哈希值(# hash)发生改变后,路由会根据制定好的规则,展示对应的视图内容
<div id="app">
<!-- 5 路由入口 指定跳转到只定入口 -->
<router-link to="/home">首页</router-link>
<router-link to="/login">登录</router-link>
<!-- 7 路由出口:用来展示匹配路由视图内容 -->
<router-view></router-view>
</div>
<!-- 1 导入 vue.js -->
<script src="./vue.js"></script>
<!-- 2 导入 路由文件 -->
<script src="./node_modules/vue-router/dist/vue-router.js"></script>
<script>
// 3 创建两个组件
const Home = Vue.component('home', {
template: '<h1>这是 Home 组件</h1>'
})
const Login = Vue.component('login', {
template: '<h1>这是 Login 组件</h1>'
})
// 4 创建路由对象
const router = new VueRouter({
routes: [
// 路径和组件一一对应
{ path: '/home', component: Home },
{ path: '/login', component: Login }
]
})
var vm = new Vue({
el: '#app',
// 6 将路由实例挂载到vue实例
router
})
</script>
// 将path 重定向到 redirect
{ path: '/', redirect: '/home' }
路由导航高亮
匹配路由模式
new Router({
routers:[],
mode: "hash", //默认hash | history 可以达到隐藏地址栏hash值 | abstract,如果发现没有浏览器的 API 则强制进入
linkActiveClass : "now" //当前匹配的导航链接将被自动添加now类
})
// 方式一
<router-link to="/user/1001">如果你需要在模版中使用路由参数 可以这样 {{$router.params.id}}</router-link>
// 方式二
<router-link :to="{path:'/user',query:{name:'jack',age:18}}">用户 Rose</router-link>
<script>
// 路由
var router = new Router({
routers : [
// 方式一 注意 只有/user/1001这种形式能被匹配 /user | /user/ | /user/1001/ 都不能被匹配
// 将来通过$router.params获取参数返回 {id:1001}
{ path: '/user/:id', component: User },
// 方式二
{ path: "user" , component: User}
]
})
// User组件:
const User = {
template: `<div>User {{ $route.params.id }}</div>`
}
</script>
<!-- 如果要子啊vue实例中获取路由参数 则使用this.$router.params 获取路由参数对象 -->
<!-- {{$router.query}} 获取路由中的查询字符串 返回对象 -->
// 父组件:
const User = Vue.component('user', {
template: `
<div class="user">
<h2>User Center</h2>
<router-link to="/user/profile">个人资料</router-link>
<router-link to="/user/posts">岗位</router-link>
<!-- 子路由展示在此处 -->
<router-view></router-view>
</div>
`
})
// 子组件[简写]
const UserProfile = {
template: '<h3>个人资料:张三</h3>'
}
const UserPosts = {
template: '<h3>岗位:FE</h3>'
}
// 路由
var router =new Router({
routers : [
{ path: '/user', component: User,
// 子路由配置:
children: [
{
// 当 /user/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/posts 匹配成功
// UserPosts 会被渲染在 User 的 <router-view> 中
path: 'posts',
component: UserPosts
}
]
}
]
})
为什么需要模块化
AMD 浏览器端
CommonJS nodejs
CMD 浏览器端
AMD 的使用
Asynchronous Module Definition:异步模块定义,浏览器端模块开发的规范 代表:require.js 特点:模块被异步加载,模块加载不影响后面语句的运行
1、定义模块
// 语法:define(name, dependencies?, factory);
// name表示:当前模块的名称,是一个字符串 可有可无
// dependencies表示:当前模块的依赖项,是一个数组无论依赖一项还是多项 无则不写
// factory表示:当前模块要完成的一些功能,是一个函数
// 定义对象模块
define({})
// 定义方法模块
define(function() {
return {}
})
// 定义带有依赖项的模块
define(['js/a'], function() {})
2、加载模块
// - 注意:require的第一个参数必须是数组
// 参数必须是数组 表示模块路径 以当前文件为基准,通过回调函数中的参数获取加载模块中的变量 参数与模块按照顺序一一对应
require(['a', 'js/b'], function(a, b) {
// 使用模块a 和 模块b 中的代码
})
3、路径查找配置
// 配置示例
// 注意配置应当在使用之前
require.config({
baseUrl: './js' // 配置基础路径为:当前目录下的js目录
})
require(['a']) // 查找 基础路径下的 ./js/a.js
// 简化加载模块路径
require.config({
baseUrl: './js',
// 配置一次即可,直接通过路径名称(template || jquery)加载模块
paths: {
template: 'assets/artTemplate/template-native',
jquery: 'assets/jquery/jquery.min'
}
})
// 加载jquery template模块
require(['jquery', 'template'])
4、非模块化和依赖项支持
// 示例
require.config({
baseUrl: './js',
paths: {
// 配置路径
noModule: 'assets/demo/noModule'
},
// 配置不符合规范的模块项
shim: {
// 模块名称
noModule: {
deps: [], // 依赖项
exports: 'sayHi' // 导出模块中存在的函数或变量
}
}
});
// 注意点 如果定义模块的时候,指定了模块名称,需要使用该名称来引用模块
// 定义 这个模块名称与paths中的名称相同
define('moduleA', function() {})
// 导入
require.config({
paths: {
// 此处的模块名:moduleA
moduleA: 'assets/demo/moduleA'
}
})
5、路径加载规则
路径配置的优先级:
<!--
设置data-main属性
1 data-main属性指定的文件也会同时被加载
2 用于指定查找其他模块的基础路径
-->
<script src="js/require.js" data-main="js/main"></script>
1 webpack 将带有依赖项的各个模块打包处理后,变成了独立的浏览器能够识别的文件
2 webpack 合并以及解析带有依赖项的模块
webpack 是一个现代 JavaScript 应用程序的模块打包器(特点 module、 bundler)
webpack 是一个模块化方案(预编译)
webpack获取具有依赖关系的模块,并生成表示这些模块的静态资源
对比
模块化方案: webpack 和 requirejs(通过编写代码的方式将前端的功能,划分成独立的模块)
browserify 是与 webpack 相似的模块化打包工具
webpack 预编译 (在开发阶段通过webpack进行模块化处理, 最终项目上线, 就不在依赖于 webpack)
requirejs 线上的编译( 代码运行是需要依赖与 requirejs 的 )
webpack解决了现存模块打包器的两个痛点:
JS的模块化规范:
非JS等静态资源:
全局安装:npm i -g webpack
项目安装:npm i -D webpack
/*
src/js/index.js
*/
// 1 导入 jQuery
import $ from 'jquery'
// 2 获取页面中的li元素
const $lis = $('#ulList').find('li')
// 3 隔行变色
// jQuery中的 filter() 方法用来过滤jquery对象
$lis.filter(':odd').css('background-color', '#def')
$lis.filter(':even').css('background-color', 'skyblue')
//命令行运行 `webpack src/js/index.js dist/bundle.js 目录生成在命令行运行目录
/*
运行流程:
1、webpack 根据入口找到入口文件
2、分析js中的模块化语法
3、将所有关联文件 打包合并输出到出口
*/
// 参数解释 注意参数是无序的 有值的参数空格隔开
// --open 自动打开浏览器
// --contentBase ./ 指定浏览器 默认打开的页面路径中的 index.html 文件
// --open 自动打开浏览器
// --port 8080 端口号
// --hot 热更新,只加载修改的文件(按需加载修改的内容),而非全部加载
"scripts": {
"dev": "webpack-dev-server --open --contentBase ./ --port 8080 --hot"
}
var path = require('path')
module.exports = {
// 入口文件
entry: path.join(__dirname, 'src/js/index.js'),
// 输出文件
output: {
path: path.join(__dirname, 'dist'), // 输出文件的路径
filename: 'bundle.js' // 输出文件的名称
}
}
const webpack = require('webpack')
devServer: {
// 服务器的根目录 Tell the server where to serve content from
// https://webpack.js.org/configuration/dev-server/#devserver-contentbase
contentBase: path.join(__dirname, './'),
// 自动打开浏览器
open: true,
// 端口号
port: 8888,
// --------------- 1 热更新 -----------------
hot: true
},
plugins: [
// ---------------- 2 启用热更新插件 ----------------
new webpack.HotModuleReplacementPlugin()
]
html-webpack-plugin 插件
/* webpack.config.js */
const htmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new htmlWebpackPlugin({
// 模板页面路径
template: path.join(__dirname, './index.html'),
// 在内存中生成页面路径,默认值为:index.html
filename: 'index.html'
})
]
原文来自:segmentfault
声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com
通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。
IP反查域名是通过IP查询相关联的域名信息的功能,它提供IP地址历史上绑定过的域名信息。
结合权威身份认证的精准人脸风险查询服务,提升人脸应用及身份认证生态的安全性。人脸风险情报库,覆盖范围广、准确性高,数据权威可靠。
全国城市和站点空气质量查询,污染物浓度及空气质量分指数、空气质量指数、首要污染物及空气质量级别、健康指引及建议采取的措施等。
输入手机号和拦截等级,查看是否是风险号码